Although I have used SASS in a number of projects, I found many advanced uses I have not used in studying the source code of Element SASS UI framework. By this summary, I combed the knowledge system of SASS in detail.

Sass is an auxiliary tool to enhance CSS. It adds advanced functions such as variables, nested rules, mixins, inline imports and so on on the basis of CSS syntax. These extensions make CSS more powerful and elegant. Using Sass and Sass’s style libraries, such as Compass, can help you better organize and manage style files and develop projects more efficiently.

1 Installation and Compilation

1.1 installation

  • Install Ruby (No need to install Ruby on MAC!)

    • In the website rubyinstaller.org/downloads/… After the installation is complete, run CMD and enter ruby -v. If the installation is successful, the version number is printed

    • Delete and replace the original gem source

    Gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/ // Check the contents of the gem installationCopy the code
  • Install sass with Compass

Gem install sass gem install compass gem install sass --version=3.3 sass -v compass -vCopy the code

1.2 build

  • Command line compilation
// Single file compilation; Go to the SCSS directory sass demo.scss demo. CSS // Listen to the SCSS file. Go to the scssTest directory sass --watch SCSS: CSS // Compile the files in the SCSS directory as CSS and store them in the CSS directoryCopy the code
  • Command line instruction
Sass-cache file --sourcemap add debug map --style select compile format Map sass --watch input. SCSS :output. CSS --style expanded --sourcemapCopy the code
  • Software-based compilation

    Koala&codekit, they are excellent compilers; Supports Less, Sass, Compass, and CoffeeScript

  • Live Sass compiler

  • The VSCode extension helps you compile/convert SASS/SCSS files to CSS files in real time with real-time browser reloads.

  • Webpack configuration

npm install -D sass-loader node-sass style-loader css-loader

module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader','css-loader','sass-loader'],
        exclude: /node_modules/
      }
    ]
}

Copy the code

1.3 Output Format

  • Nested format

    Selectors and properties occupy a single line with the same amount of indentation as in Sass files, and the amount of indentation for each line reflects the number of layers within the nested rules. When reading large CSS files, this style makes it easy to analyze the main structure of the file.

  • Expanded format

    Expanded output is more like a handwritten style, with the selector, properties, and so on all on one line, the properties indent according to the selector, and the selector does not indent at all.

  • Compact format

    Each CSS rule has only one line and contains all the attributes under it. Nested selectors output with no empty lines, while non-nested selectors output blank lines as delimiters.

  • Compressed format

    Compressed output deletes all meaningless Spaces, blank lines, and comments, and tries to compress the file volume to the minimum. At the same time, it will make other adjustments, such as automatically replacing the color expression that takes up the least space.

2 Syntax Format

2.1 Syntax Format

  • The Sass syntax format, known as the indent format (Indented Sass), is a simplified format; Write in strict indentation syntax, without curly braces ({}) and semicolons
  • SCSS is a new syntax introduced by Sass 3, which is fully compatible with CSS3 and inherits the powerful functions of Sass. Very similar to how CSS syntax is written.
  • SCSS is generally recommended because the syntax requirements are not so strict

2.2 Encoding Format

The @charset encoding is not detected. Utf-8 encoding is used by default.

2.3 annotations

Sass supports standard CSS multi-line comments (/* */) and single-line comments (//), the former being fully printed to compiled CSS files, while the latter is not

3 sass Script

3.1 variable

3.1.1 Variable writing method

  • Variables start with a dollar sign
  • SCSS considers the underlined and underlined lines to be exactly equal
$primary : #DABE8D ! default;Copy the code

3.1.2 Variable scope

  • Local variable: a variable defined within a selector and used by that selector and its children
  • Global variables: a variable defined outside the selector is overwritten if a child selector has a variable of the same name
$width: 200px; .block{ $width: 100px; #{&}-item{ width: $width; } } .block-other{ width: $width; }.block. Block-item {width: 100px;} // after compilation (.variable1 uses nested global variables).block. } .block-other { width: 200px; }Copy the code
  • Local variable conversion to global variable can be added! global
// before compiling. Block {$width: 100px! global; #{&}-item{ width: $width; } } .block-other{ width: $width; } // compile.block. block-item {width: 100px; } .block-other { width: 100px; }Copy the code

3.1.3 Variable definition, set the default value of the variable! default

End of variable added! Default Specifies the default value. If the variable has been assigned, it will not be reassigned. If the variable has not been assigned, it will be assigned a new value.

  • The variable is assigned a value
$primary-dark: pink; $primary-dark : red ! default; .block{ color: $primary-dark; } // after compiling (the variable value is the same as the previously declared value). Block {color: pink; }Copy the code
  • The variable is not assigned
$primary-dark: null; $primary-dark : red ! default; .block{ color: $primary-dark; } // after compiling (the variable value is the new value).block {color: red; }Copy the code

3.2 Data Types

  • Values (1, 2, 13, 10px)
  • Strings, quoted and unquoted strings (“foo”, ‘bar’, baz)
  • Color (blue, #04a3f9, rgba(255,0,0,0.5))
  • Boolean (true, false)
  • Null
  • Array (list), delimited by Spaces or commas (1.5em 1em 0 2em, Helvetica, Arial, sans-serif)
  • Maps, the equivalent of JavaScript object, (key1: value1, key2: value2)

3.3 operation

Note:

  • Addition, subtraction, multiplication, and division must all be calculated in the same unit. Otherwise, an error will be reported.
  • The left side of the subtraction is concatenated without Spaces. To avoid related problems, Spaces are reserved on both sides of the operator
  • If multiple value units are the same, you only need to supply units for one value.
  • Parentheses can be used to influence the order of operations
  • #{} can avoid Sass running arithmetic expressions and compile CSS directly

3.3.1 Numerical operation

  • Add and subtract

    • You have to add and subtract in the same unit
    • The calculation of one with unit and one without unit is dominated by units with unit
  • The multiplication

    • Support for multiple units; You only need to attach units to one item, or an error will be reported if you attach units to each item.
    .mk-col-6 {
      width: (1 / 24 * 6 * 100) * 1%;
    }
    Copy the code
  • division

    • The following three cases/will be considered as division symbols:
    $width-c: 200px; $width-c: 200px; $width-c: 200px; .block{ width: $width-c / 2; } // If the value is wrapped in parentheses. Block {width: (100px) / 2; } // If the value is part of an arithmetic expression. Block {width: (100px) / 2; margin-left: 4px + 8px/2px; }Copy the code
    • If you need to use variables, and you want to make sure that/does not do division and is compiled completely into your CSS file, just wrap the variables with #{} interpolation statements.
    .block{
      $font-size: 12px;
      $line-height: 30px;
      font: #{$font-size}/#{$line-height};
    }
    Copy the code

3.3.2 String Operations

    • Can be used to concatenate strings
// before compiling. Block {content: "hello "+ "world"; } // compile. Block {content: "Hello world"; }Copy the code
  • The string type (with or without quotes) to the left of the + sign is the main string type
.block{content: "hello "+ world; } // compile. Block {content: "Hello world"; }Copy the code

3.3.1 Color operation

Color calculation with a small range, do not do too much research, interested friends can go to the official website to learn, today focuses on introducing several Sass built-in color methods

  • A representation of colors

    • HEX notation (hexadecimal)
    • RGB representation
    • An HSL notation

    HSL is short for Hue, Saturation and Lightness.

    Hue is the basic attribute of a color (red, green, yellow, etc.). Saturation refers to the purity of colors, the higher the Saturation, the lighter the lower the color. Lightness refers to the degree of brightness of colors, with the higher the color, the whiter the color, and the lower the color, the darker the color

  • Mix (Mix (color1,color1, color1,color2, $weight: 50%))

The colors color1 and color1 are mixed with color1 and color2 to produce a new color; $weight determines the weight of the color in the result. If you specify 25%, this means that the first color is 25% and the second color is 75%.

span{
    &:nth-child(2){
    background: mix($--color-primary, white, 80%);
    }
    &:nth-child(3){
    background: mix($--color-primary, black, 80%);
}
Copy the code
  • Lighten up (color,color, color,amount)

Color light, color light, color light, mount is between 0% and 100% (inclusive). Increase the brightness of the $color HSL by this value.

span{
    background: lighten( $--color-primary, 10% );
}
Copy the code
  • Darken (darken(color,color, color,amount)

Color deepen, color deepen, color deepen, mount is a value between 0% and 100%. Reduce the brightness of the $color HSL by this value.

span{
    background: darken( $--color-primary, 10% );
}
Copy the code
  • Rgba (color,color, color,amount)

To change color transparency, $mount is a value between 0 and 1 inclusive

Span {background: rgba ($- color - primary, 0.8); }Copy the code
  • Effect comparison of several color functions

@ 3.4 function function

  • SASS is a function that passes in arguments, evaluates them internally, and outputs a value with @return. But you have to set the return value
  • The difference from blending is that blending produces a specific style and the function returns a specific value
  • To output styles directly, use mixins; To perform operations that return values, use function

3.4.1 SASS built-in functions

Sass built-in functions can go to see the Celsius zero written “SASS built-in functions at a glance”, I think the summary is quite detailed

3.4.2 SASS Custom functions

  • The function can access any globally defined variable
  • Function parameters, can be directly passed indefinite parameters, in the order they are listed in the function;
$total: 2; @function column-width($col, $total) { @return (1 / $total * $col * 100) * 1%; } @for $i from 1 through $total { .mk-col-#{$i} { width: Column-width ($I,$total) // call column-width($I,$total) // call column-width($I,$total) // } .mk-col-2 { width: 100%; }Copy the code
  • Use keywords. You can pass key/value pairs in the key: value format without having to order them in the order listed in the function.
$total: 2; @function column-width($col, $total) { @return percentage($col/$total); // Use percentage($number) as the sass built-in function. } @for $I from 1 through $total {. Mk-col -#{$I} {width: The column - width ($total: $total, $col: $I)}} / / compiled. Mk - col 1 {width: 50%; } .mk-col-2 { width: 100%; }Copy the code
  • Set the default value for parameter transmission
@function column-width($col:3, $total:4) {@return percentage($col/$total); }. Mk-col-3 {width: column-width(2)} // compile. Mk-col-3 {width: 50%; }Copy the code
  • Set variable parameters, similar to ES6 destruct, but not used in function scenarios, useful for mixins, can add multiple box shadows
@function column-width($index, $widths...); { @return nth($widths, $index); $NTH ($list, $n); } .mk-col-3 { width: column-width(3, 25%, 50%, 75%, 100%); } // after compile. Mk-col-3 {width: 75%; }Copy the code

4 nested

4.1 Sass Nesting rules

Sass allows one set of CSS styles to be nested within another, with the inner style taking its outer selector as its parent, avoiding repeating the input of the parent selector

Mk-cell {display: flex; width: 100%; padding: 6px 12px; overflow: hidden; .mk-cell__title { width: 80px; flex-shrink: 0; color: #666; } .mk-cell__value { flex-basis: auto; font-weight: 600; }} // after compiling. Mk-cell {display: -webkit-box; display: -ms-flexbox; display: flex; width: 100%; padding: 6px 12px; overflow: hidden; } .mk-cell .mk-cell__title { width: 80px; -ms-flex-negative: 0; flex-shrink: 0; color: #666; } .mk-cell .mk-cell__value { -ms-flex-preferred-size: auto; flex-basis: auto; font-weight: 600; }Copy the code

4.2 Parent selector: clever use of &

  • Hover or pseudoclass elements can be set directly using the parent selector of the nested outer layer
Mk-cell {background: # FFF; &:hover{ background: #eee; } // after compiling. Mk-cell {background: # FFF; } .mk-cell:hover { background: #eee; }Copy the code
  • Use the parent selector & Build a new selector – sibling
Mk-cell {background: # FFF; &__title { width: 80px; flex-shrink: 0; color: #666; } // after compiling. Mk-cell {background: # FFF; } .mk-cell__title { width: 80px; -ms-flex-negative: 0; flex-shrink: 0; color: #666; }Copy the code
  • Using the parent selector & to build a new child selector requires interpolation #{}
Mk-cell {background: # FFF; #{&}__title { width: 80px; flex-shrink: 0; color: #666; } // after compiling. Mk-cell {background: # FFF; } .mk-cell .mk-cell__title { width: 80px; -ms-flex-negative: 0; flex-shrink: 0; color: #666; }Copy the code

4.3 Attribute Nesting

Some CSS properties follow the same namespace (namespace). For example, font-family, font-size, and font-weight all use font as the namespace of the property. To facilitate the management of such attributes, and to avoid duplicate input, Sass allows attributes to be nested in namespaces

Mk-cell {background: # FFF; font: { family: fantasy; size: 30em; weight: bold; } // after compiling. Mk-cell {background: # FFF; font-family: fantasy; font-size: 30em; font-weight: bold; }Copy the code

4.4 Placeholder selector %

Placeholder selectors are not compiled into CSS files when used alone (not called by @extend); Easy to define style reuse

Mk-cell {background: # FFF; Font: {family: fantasy; size: 30em; weight: bold; } } } .mk-cell-title{ @extend %title; } // after compiling. Mk-cell {background: # FFF; } .mk-cell .mk-cell-title { font-family: fantasy; font-size: 30em; font-weight: bold; }Copy the code

4.5 Used together with @import

The contents of the imported SCSS file are written to the nested selector and compiled as normal nested compilation

//_tag. SCSS @each $color in red, blue, pink {. Tag -#{$color}{color: $color; } } //demo.scss .tag-group{ @import "./_tag"; } // after compiling.tag-group. Tag-red {color: red; } .tag-group .tag-blue { color: blue; } .tag-group .tag-pink { color: pink; }Copy the code

5 hybrid

Mixins are used to define reusable styles, avoiding the use of nonverbal classes; Hybrid instructions can contain all CSS rules, most Sass rules, and even introduce variables through parameter functions to output a variety of styles.

5.1 Definition and use of blending

  • The use of the mixin directive is to add the name and style after @mixin
  • Use the @include directive to refer to the blended style in the form of the blended name followed by the desired parameters (optional) :
@mixin utils-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @include utils-ellipsis,.block{@include utils-ellipsis}Copy the code

5.2 Mixed Parameter Transmission

For details, see ==++3.4.2 SASS custom function ++==

  • Ordinary mass participation
@mixin ellipsis($line) {overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $line; } .block{ @include ellipsis(2) }Copy the code
  • Mixed keyword parameter transmission
@mixin button-variant($color, $background, $border) {color: $color; border: 1px solid $border; background-color: $background; }. Block {@include button-variant($background:# FFF,$color:red, $border:red)} border: 1px solid red; background-color: #fff; }Copy the code
  • Mixed parameter variable (undecided parameter passing parameter)
@mixin box-shadow($shadows...) { -moz-box-shadow: $shadows; -webkit-box-shadow: $shadows; box-shadow: $shadows; } .shadows { @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999); Shadowed {-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; }Copy the code
  • Importing content into blended styles (combined with @content)

When referring to a blended style, you can import a piece of code into the blended instruction before printing the blended style, and the additional imported parts will appear in the place of the @Content flag:

@media only screen and (max-width: $max-width) {@content; // @mixin res($max-width: $600) {// @media only screen and (max-width: $max-width) {@content; }}. Block {@include res(768){//@content render style display: block; width: 100%; }} @media only screen and (max-width: 768) {. Block {display: block; width: 100%; }}Copy the code
  • Mixing with other instructions

The free stuff in the mix is @if, @at-root, interpolation syntax #{}, & parent elements, and so on, just like writing regular styles

@mixin ellipsis_mix($line:1) {@if $line > 1 {// Use overflow: hidden with @if; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $line; } @else { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } &:hover{// use background: #eee; } #{&}-item{// interpolation syntax #{} use display: flex; }}.block_ellipsis{@include ellipsis_mix(1)}.block_ellipsis{overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .block_ellipsis:hover { background: #eee; } .block_ellipsis .block_ellipsis-item { display: -webkit-box; display: -ms-flexbox; display: flex; }Copy the code

6 @-rules and Instructions

@ 6.1 – use Rules

6.1.2 SASS Import Using -@import

@import is used to import style rules from other stylesheets. Here we will analyze the difference between CSS imports and SASS imports:

  • The browser will not know to download and parse the referenced CSS file until the CSS file has been downloaded and parsed, and will initiate an HTTP request. The CSS file will not start rendering until it has been fully parsed. Therefore, the CSS resolution delay caused by CSs@import will lengthen the blank period of the page. It is not recommended to use the link import
  • Sass’s import @import directive includes the code directly into the target SCSS file without generating additional HTTP requests

Let’s summarize the SASS import rules

  • Import files with an expanded name of.css, files starting with http://, url(), or @import containing media queries are all used as CSS3 import rules
  • In other cases, if the extension name of the file is.scss or.sass, the import succeeds. Without specifying an extension, Sass will try to find and import a file with the same file name, extension.scss or.sass.
  • You can nest imports (see the nesting section on imports)
  • Cannot be used directly in control directives or hybrid directives, but can be used in nested CSS rules within directives
Import directives may not be used within control directives or mixins@mixin import_test($line:1) {@import "tag.css"; @mixin import_test($line:1) {. Tag-group {@import "tag.css"; } } .block{ @include import_test(); }.block. tag-group. Tag-red {color: red; } .block .tag-group .tag-blue { color: blue; } .block .tag-group .tag-pink { color: pink; }Copy the code

6.1.2 @media Use of media query

@media can be used for nesting in sass, but will compile to the outermost layer when compiled, mainly for easy writing without much analysis

6.1.3 Style extension the use of -@extent

Style inheritance focuses on a few common aspects

  • Inherits repeated styles into styles that use inherited statements
Pink {background: pink; } .block{ width: 100px; Pink,.block {//.block inherits. Pink's style background: pink; } .block { width: 100px; }Copy the code
  • Defines a set of styles in conjunction with the placeholder %, which are not compiled when used alone and will only be rendered when referenced
%pink{background: pink; } .block{ width: 100px; @extend %pink; } // after compiling. Block {background: pink; } .block { width: 100px; }Copy the code

This is where I summarize the differences between blending, inheritance, and functions

  • Blending is mainly the introduction of variables through the parameter function, the output of a variety of styles, in order to practical code reuse.
  • The function passes in an argument, evaluates it internally, and outputs a value with @return.

The biggest difference between hybrid and inheritance lies in the different compilation methods. Hybrid compilation results in directly adding styles to style classes, which may lead to code redundancy, while inheritance only adds selectors to classes to achieve the purpose of sharing

  • Inheritance has no arguments and cannot output a variety of styles like blending
Pink {background: pink; } @mixin ellipsis($line:1) { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $line; } .block{ width: 100px; @extend .pink; @include ellipsis}.block {// inherit pink style background: pink; } .block { width: 100px; // Mix references to generate mixed output style overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; }Copy the code

6.1.4 Use of @at-root

  • By default @at-root only jumps out of selector nesting (out of all parent selectors), not @media or @support
  • If you need to jump out, use the following instructions
    • @at-root (without:all) jumps all levels (including all parent, @media, @support)
    • @at-root (without:rule) Jumps out of the selector nesting. If @at-root has no rule, this command is used by default
    • @at-root (without:media) // Skip @media
    • @at-root (without:support) indicates support. @support is not widely used because of compatibility
@at-root (without: rule) width: 100px; @at-root (without: rule); // Use @at-root. child {width: 50px; } @at-root {.child1 {width: 50px; } .child2 { width: 50px; }} @media*/ @media screen and (max-width: 300px) {. Parent {color:#f00; @at-root .child { width: 50px; }} / / @media screen and (max-width: 300px) {. Parent {color:#f00; @at-root (without: media) { .child { width: 50px; }}}} /* use @media screen and (max-width: 300px) {. Parent {color:#f00; @at-root (without: all) { .child { width:200px; }}}} // compiled /* out of the parent element nesting */. Parent {width: 100px; } .child { width: 50px; } .child1 { width: 50px; } .child2 { width: 50px; } @media*/ @media screen and (max-width: 300px) {. Parent {color: #f00; } .child { width: 50px; }} / / @media screen and (max-width: 300px) {. Parent {color: #f00; } } .child { width: 50px; } / / @media screen and (max-width: 300px) {. Parent {color: #f00; } } .child { width: 200px; }Copy the code

6.1.5 SASS control Instructions

Sass control commands are widely used in @mixin and @function to provide corresponding flow and logical judgment

6.1.5.1 Judgment Instructions

The @if directive processes a style block based on a condition, which returns a style block if true or another style block if true, similar to js usage

@mixin ellipsis_mix($line:1) {@if $line > 1 {// Use overflow: hidden with @if; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $line; } @else { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }}.block{@include ellipsis_mix(2)}.block{overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }Copy the code
6.1.5.2 Circular instruction
  • The loop instruction @for

The @for directive has two formats: @for varfrom

through

, or @forvar from

through

, or @for varfrom

through

, Or @forvar from to, the difference is that through contains the end value,to does not contain the end value, and must be integers; To analyze the usage of this instruction through the Layout





@for $I from 0 through 3 {.mk-col-#{$I} {width: (1 / 3 * $i * 100) * 1%; }} // compile with end value 3. mk-col-0 {width: 0%; }. Mk-col-1 {width: 33.33333%; }. Mk-col-2 {width: 66.66667%; } .mk-col-3 { width: 100%; } @for $I from <start> to <end> @for $I from 0 to 3 {. Mk-col -#{$I} {width: (1/3 * $I * 100) * 1%; }} // do not include end value 3. }. Mk-col-1 {width: 33.33333%; }. Mk-col-2 {width: 66.66667%; }Copy the code
  • The loop instruction @while

The @while directive is a bit like a combination of @if and @for, generating different style blocks when the expression is true and stopping the loop when the expression is false, so it can achieve relatively complex functionality

$nums: 0; $nums} {width: (1/8 * $nums * 100) * 1%; } $nums: $nums + 2} $nums: $nums + 2} } .mk-col-2 { width: 25%; } .mk-col-4 { width: 50%; } .mk-col-6 { width: 75%; }Copy the code
  • The loop instruction @each

The usage of @each can be quite extensive. Generally, ICONS, fonts, etc. can be used when building UI framework. The syntax is @each $var in; Is the sASS array variable (array (list), delimited by Spaces or commas (1.5em 1em 0 2em, Helvetica, Arial, Sans-serif, described above); You can assign a single value or multiple variable values. Take setting up background ICONS and font icon style files as an example

The @each directive allocates a single variable

#{$var}-icon {background-image: url('/images/#{$var}.png'); Add-icon {background-image: url("/images/add.png"); } .edit-icon { background-image: url("/images/edit.png"); } .delete-icon { background-image: url("/images/delete.png"); } .check-icon { background-image: url("/images/check.png"); }Copy the code

The @each directive can also assign multiple variables; Separated by commas

@each $icon-name,$icon-content in (add,/e6a6) (edit,/e6a6) (delete,/e6a7) (check,/e6a8) {.#{$icon-name}-icon { The //quote function adds double quotation marks to the string passed in. If there are already double quotation marks, the string is returned without operation. content: quote($icon-content); Add-icon {content: "/e6a6"; } .edit-icon { content: "/e6a6"; } .delete-icon { content: "/e6a7"; } .check-icon { content: "/e6a8"; }Copy the code

7 BEM architecture in SASS

Here I will later combined with element source code to do a detailed summary, code word is not easy, first here, later not periodically perfect, point a small star to give me power oh!