The most mature, stable, and powerful professional CSS extension language in the world! – Sass website

Main Contents:

  • Sass uses summaries
  • Bootstrap@4 about implementing the float component

The installation

I use it locally with gulp+ SASS automation tools, mainly as follows:

npm install node-sass gulp-sass --save-dev
Copy the code

The configuration of gulpfile.js file is as follows. For details, see here.

const { src, dest, watch } = require("gulp");
const sass = require("gulp-sass");
sass.compiler = require("node-sass");

function scss() {
  return src(scssGlobSrc)
    .pipe(sass({ outputStyle: "expanded" }).on("error", sass.logError))
    .pipe(dest("dist/sass"));
}

exports.scss = scss;
Copy the code

Start: gulp SCSS.

  • How do I install Sass

Four types of compilation and typesetting

/* Uncompiled style */
.box {
  width: 300px;
  height: 400px;
  &-title {
    height: 30px;
    line-height: 30px; }}Copy the code

Nested compiler typesetting format

/* Command line content */
sass style.scss:style.css --style nested /* compiled style */.box {width:300px;
  height: 400px;
}
.box-title {
  height: 30px;
  line-height: 30px;
}
Copy the code

Expanded Compiles typesetting format

/* Command line content */
sass style.scss:style.css --style expanded /*300px;
  height: 400px;
}
.box-title {
  height: 30px;
  line-height: 30px;
}
Copy the code

Compact compiles typesetting format

/* Command line content */
sass style.scss:style.css --style compact /* compiled style */.300px;
  height: 400px;
}
.box-title {
  height: 30px;
  line-height: 30px;
}
Copy the code

Compressed compiles typesetting format

/* Command line content */
sass style.scss:style.css --style compressed /* style compressed */.300px;
  height: 400px;
}
.box-title {
  height: 30px;
  line-height: 30px;
}
Copy the code

Silent annotation

body {
  // This comment content does not appear in the generated CSS file
  color: # 333;
  /* This comment content will appear in the generated CSS file */
  padding: 0;
}
Copy the code
body {
  color: # 333;
  /* This comment content will appear in the generated CSS file */
  padding: 0;
}
Copy the code

Use the variable

$color: #4a4a4a; , variable reference: color: $color; , specific examples are shown as follows:

$bg-color: #f90;
$font-color: # 444;
body {
  background: $bg-color;
  color: $font-color;
}
.selected {
  border: 1px solid $font-color;
}
Copy the code
body {
  background: #f90;
  color: # 444;
}

.selected {
  border: 1px solid # 444;
}
Copy the code

Nested CSS rules

Documentation: In Sass, you can nest rule blocks within rule blocks like Russian dolls. Sass will take care of these nested rules when exporting CSS so that you don’t have to write them again.

Let’s look at an example and see what it means.

ul {
  li {
    a {
      color: $font-color;
      &:hover {
        color: red;
      }
      &::after {
        content: "..."; }}}}Copy the code
ul li a {
  color: # 444;
}

ul li a:hover {
  color: red;
}

ul li a::after {
  content: "...";
}
Copy the code

Neat enough, but there are some nested rules that you need to be careful about, such as:

  • The identifier of the parent selector&
  • Nesting of group selectors
  • Subcombinatorial selectors and same-layer combinatorial selectors:>, + and ~
  • Attributes are nested

The identifier of the parent selector

Parent selector identifier &, remember that & is the father, you can be behind the father, or in front of the father, however you like, hahaha:

nav a {
  color: $font-color;
  /* Dad after */
  &:hover {
    color: red;
  }
  /* Dad before */
  .header & {
    color: # 000; }}Copy the code
nav a {
  color: # 444;
}

/* Dad after */
nav a:hover {
  color: red;
}

/* Dad before */
.header nav a {
  color: # 000;
}
Copy the code

Dad is Dad: Nav A, what scene can be used Dad before? So if you think about nav a being a generic style, I want to give the header component a style for nav A alone, which is.header nav A, which is.header &.

Of course, you can also use it like this:

.main {
  color: black;
  &-sidebar {
    border: 1pxsolid; }}// css
.main {
  color: black;
}

.main-sidebar {
  border: 1px solid;
}
Copy the code

Nesting of group selectors

Document examples:

.container {
  h1.h2.h3 {
    margin-bottom: 0.8 em; }}nav.aside {
  a {
    color: blue; }}Copy the code
.container h1..container h2..container h3 {
  margin-bottom: 0.8 em;
}

nav a.aside a {
  color: blue;
}
Copy the code

The name tells us the gist of the rule: groups. The curly bracket {can be a group, like container, like nav, aside, whatever.

As a member of the group, he or she is entitled to an heir, and he or she is entitled to an heir exactly like any other group member. If he or she has three (H1, H2, H3) heirs, then each member of the group must have three; If a person has only one (a) heir, each member must have one, even if the group is large.

Walkthrough: There are three header article footers, and I want the font color to have default values, link exceptions, and hover changes.

.header..acticle..footer {
  color: $font-color;
  a {
    color: # 999;
    &:hover {
      color: red; }}}Copy the code
.header..acticle..footer {
  color: # 444;
}

.header a..acticle a..footer a {
  color: # 999;
}

.header a:hover..acticle a:hover..footer a:hover {
  color: red;
}
Copy the code

Subcombination and same layer combination

The subgroup selector > and the group selector + and ~ are consistent with the CSS rules.

/* Select all article elements in the same layer as article */
article ~ article {
  border-top: 1px dashed #ccc;
}
/* Select the article element */ immediately after the nav element
nav + article {
  margin-top: 0;
}
/* Select all elements under article that hit the section selector */
article > section {
  background: #eee;
}
Copy the code

Document examples:

article{~article {
    border-top: 1px dashed #ccc;
  }
  > section {
    background: #eee;
  }
  dl > {
    dt {
      color: # 333;
    }
    dd {
      color: # 555; }}nav + & {
    margin-top: 0; }}Copy the code
article ~ article {
  border-top: 1px dashed #ccc;
}

article > section {
  background: #eee;
}

article dl > dt {
  color: # 333;
}

article dl > dd {
  color: # 555;
}

nav + article {
  margin-top: 0;
}
Copy the code

Nested properties

Rule: Break the attribute name from the underscore -, add a colon: after the root attribute, followed by a {} block, in which the child attribute part is written. Just like CSS selectors nested, sass unwinds your sub-attributes one by one, connecting the root and sub-attributes with a underlined -, resulting in the same CSS style that you would manually write over and over again:

nav {
  border: {
    style: solid;
    width: 1px;
    color: #ccc; }}nav {
  border: 1px solid #ccc {
    left: 0px; }}// css
nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

nav {
  border: 1px solid #ccc;
  border-left: 0px;
}
Copy the code

Sentence: I want to put the border – style – interrupted, scattered around, and replace: to use {} nested use, purpose is nothing down, nothing up, has broken just stand, merge all duplicate everything and only write key parts.

@-Rules

@ import import

Using @import rules in CSS alone is not as efficient as using link to import files, such as loading font libraries. I once suffered from this problem in a project and swore I would never use this rule.

Sass’s @import rule imports CSS files as soon as they are generated, so it has nothing to do with CSS @import.

But because sass is compatible with native CSS, it also supports native CSS@import, such as import files or urls that end in.css.

Use:

// Common methods
@import "header";
@import "footer";

// Multiple imports
@import "rounded-corners"."text-shadow";

// Nested imports
.blue-theme {
  @import "blue-theme";
}
Copy the code

If you name the file _colors.scss, the _colours.css file will not be compiled, but @import “colors” will still be imported; .

@media Media query

The @media directive in Sass is used the same way as in CSS, but it is also allowed to be nested within CSS rules. When compiled, @Media will be compiled to the outermost layer of the file, including nested parent selectors.

.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px; }}/* splice and */
@media screen {
  .sidebar {
    @media (max-width: 1140px) {
      width: 960px; }}.other {
    @media (max-width: 640px) {
      width: 100%; }}}Copy the code
.sidebar {
  width: 300px;
}

@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px; }}/* splice and */
@media screen and (max-width: 1140px) {
  .sidebar {
    width: 960px; }}@media screen and (max-width: 640px) {
  .other {
    width: 100%; }}Copy the code

@extend

Like any other language, inheritance. For example, the.error and.intrusion classes in this code are inherited:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.error.intrusion {
  background-image: url("/image/hacked.png");
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
Copy the code
.error..seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

.error.intrusion..intrusion.seriousError {
  background-image: url("/image/hacked.png");
}

.seriousError {
  border-width: 3px;
}
Copy the code

Control instruction

@if

As with JavaScript if:

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black; }}Copy the code
p {
  color: green;
}
Copy the code

@for

The difference lies in the meaning of through and to: Through contains the last bit, while to does not contain:

@for $i from 1 to 3 {
  .list-# {$i} {
    width: 1em * $i; }}@for $i from 1 through 3 {
  .item-# {$i} {
    width: 2rem * $i; }}Copy the code
.list-1 {
  width: 1em;
}

.list-2 {
  width: 2em;
}

.item-1 {
  width: 2rem;
}

.item-2 {
  width: 4rem;
}

.item-3 {
  width: 6rem;
}
Copy the code

@each

JavaScript like for… In:

@each $kind in small, middle, large {
  .#{$kind} -icon {
    background-image: url("/images/#{$kind}-icon.png"); }}Copy the code
.small-icon {
  background-image: url("/images/small-icon.png");
}

.middle-icon {
  background-image: url("/images/middle-icon.png");
}

.large-icon {
  background-image: url("/images/large-icon.png");
}
Copy the code

mixer

Mixers are defined using the @mixin identifier, and are used via @include to address large chunks of code that can be reused.

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & {
    height: 1px; }}.clearfix {
  @include clearfix;
}
Copy the code
.clearfix {
  display: inline-block;
}

.clearfix:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

* html .clearfix {
  height: 1px;
}
Copy the code

The most powerful thing is that, like a function, you can pass parameters, not only specifying default values, but also using keyword arguments, so that you don’t care about the order of arguments:

@mixin border-value($width: 1px.$color: # 333.$style: solid) {
  border-width: $width;
  border-color: $color;
  border-style: $style;
}
/* No input */
h1 {
  @include border-value;
}
/ * and * /
h2 {
  @include border-value(2px.# 666, dashed);
}
/*关键词传参*/
h3 {
  @include border-value($style: dashed, $width: 3px.$color: # 999);
}
Copy the code
/* No input */
h1 {
  border-width: 1px;
  border-color: # 333;
  border-style: solid;
}

/ * and * /
h2 {
  border-width: 2px;
  border-color: # 666;
  border-style: dashed;
}

/*关键词传参*/
h3 {
  border-width: 3px;
  border-color: # 999;
  border-style: dashed;
}
Copy the code

The function instruction

As with mixins, several global variables can be passed to functions as arguments. A function can contain more than one statement that requires a @return call to output the result.

$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

.sidebar1 {
  width: grid-width(5);
}
.sidebar2 {
  width: grid-width($n: 10);
}
Copy the code
.sidebar1 {
  width: 240px;
}

.sidebar2 {
  width: 490px;
}
Copy the code

SassScript

The data type

SassScript supports six main data types:

  • Numbers,1, 2, 13, 10px
  • String, quoted string and unquoted string,"foo", 'bar', baz
  • The color,Blue, # 4 a3f9, rgba (255,0,0,0.5)
  • The Boolean,true, false
  • A null value,null
  • Array (list), delimited by Spaces or commas,1.5 EM 1EM 0 2EM, Helvetica, Arial, Sans-serif
  • Maps, the equivalent of JavaScript object,(key1: value1, key2: value2)

operation

SassScript support Numbers, integer, etc of addition, subtraction, multiplication, and division operations (+, -, *, /, %), the relationship between operation <, >, < =, > = can also be used for digital computing, equal operation = =,! = is available for all data types.

Interpolation statement #{}

The #{} interpolation statement allows you to use variables in a selector or attribute name, avoiding Sass from running an operational expression.

Bootstrap@4

  • The Bootstrap v4.4.1

The bootstrap. SCSS entry file introduces many components, so let’s take a look at one of them. For example, here is our final float content:

.float-left {
  float: left ! important;
}

.float-right {
  float: right ! important;
}

.float-none {
  float: none ! important;
}

@media (min-width: 576px) {
  .float-sm-left {
    float: left ! important;
  }
  .float-sm-right {
    float: right ! important;
  }
  .float-sm-none {
    float: none ! important; }}@media (min-width: 768px) {
  .float-md-left {
    float: left ! important;
  }
  .float-md-right {
    float: right ! important;
  }
  .float-md-none {
    float: none ! important; }}@media (min-width: 992px) {
  .float-lg-left {
    float: left ! important;
  }
  .float-lg-right {
    float: right ! important;
  }
  .float-lg-none {
    float: none ! important; }}@media (min-width: 1200px) {
  .float-xl-left {
    float: left ! important;
  }
  .float-xl-right {
    float: right ! important;
  }
  .float-xl-none {
    float: none ! important; }}Copy the code

Then, let’s look at how bootstrap is implemented:

Step 1: Find your way

According to bootstrap. SCSS @import “mixins”; Go to _mixins. SCSS in the current directory and see @import “mixins/float”; So continue to open _float.scss in the mixins directory.

Step 2: Content

The contents of _float.scss are as follows:

// stylelint-disable declaration-no-important

@each $breakpoint in map-keys($grid-breakpoints) {
  @include media-breakpoint-up($breakpoint) {
    $infix: breakpoint-infix($breakpoint.$grid-breakpoints);

    .float# {$infix} -left {
      float: left ! important;
    }
    .float# {$infix} -right {
      float: right ! important;
    }
    .float# {$infix} -none {
      float: none ! important; }}}Copy the code

Then there are three places, I don’t know what they are, such as map-keys(), media-breakpoint-up(), breakpoint-infix().

Step 3: Clear the air

  • map-keys()Return all keys in the map:
$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
) !default;

@each $breakpoint in map-keys($grid-breakpoints) {. # {$breakpoint} {
    color: red; }}// css
.xs {
  color: red;
}

.sm {
  color: red;
}

.md {
  color: red;
}

.lg {
  color: red;
}

.xl {
  color: red;
}
Copy the code

Information: Sass Map details

  • media-breakpoint-up(), custom function, mainly according to the media query to give different results
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
// Makes the @content apply to the given breakpoint and wider.
@mixin media-breakpoint-up($name.$breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name.$breakpoints);
  @if $min {
    @media (min-width: $min) {
      @content; }}@else {
    @content; }}Copy the code

Breakpoint-min () is also a function:

// Minimum breakpoint width. Null for the smallest (first) breakpoint.
//
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 576px
@function breakpoint-min($name.$breakpoints: $grid-breakpoints) {
  $min: map-get($breakpoints.$name);
  @return if($min! =0.$min, null);
}
Copy the code

Map-get returns the value specified in the map as map-keys:

$min-num: breakpoint-min(sm, $grid-breakpoints);

@media (min-width: $min-num) {
  p {
    color: # 444; }}// css
@media (min-width: 576px) {
  p {
    color: # 444; }}Copy the code

@content is used in mixins. After defining a mixin and setting @content, you can pass in the corresponding content to the mixin and @include:

$color: white;
@mixin colors($color: blue) {
  background-color: $color;
  @content;
  border-color: $color;
}
.colors {
  @include colors {
    color: $color; }}// css
.colors {
  background-color: blue;
  color: white;
  border-color: blue;
}
Copy the code

Data: @content in sASS syntax

  • breakpoint-infix(), custom function:
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
// Useful for making responsive utilities.
//
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "" (Returns a blank string)
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "-sm"
@function breakpoint-infix($name.$breakpoints: $grid-breakpoints) {
  @return if(breakpoint-min($name.$breakpoints) == null, ""."-#{$name}");
}
Copy the code

According to the notes, let’s demonstrate:

$min-value-sm: breakpoint-infix(sm, $grid-breakpoints);
$min-value-xs: breakpoint-infix(xs, $grid-breakpoints);

.float# {$min-value-sm} -left {
  float: left;
}
.float# {$min-value-xs} -left {
  float: left;
}

// css
.float-sm-left {
  float: left;
}

.float-left {
  float: left;
}
Copy the code

integration

Finally, we put everything together about float:

$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
) !default;

@function breakpoint-min($name.$breakpoints: $grid-breakpoints) {
  $min: map-get($breakpoints.$name);
  @return if($min! =0.$min, null);
}

@function breakpoint-infix($name.$breakpoints: $grid-breakpoints) {
  @return if(breakpoint-min($name.$breakpoints) == null, ""."-#{$name}");
}

@mixin media-breakpoint-up($name.$breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name.$breakpoints);
  @if $min {
    @media (min-width: $min) {
      @content; }}@else {
    @content; }}@each $breakpoint in map-keys($grid-breakpoints) {
  @include media-breakpoint-up($breakpoint) {
    $infix: breakpoint-infix($breakpoint.$grid-breakpoints);

    .float# {$infix} -left {
      float: left ! important;
    }
    .float# {$infix} -right {
      float: right ! important;
    }
    .float# {$infix} -none {
      float: none ! important; }}}Copy the code

So you can run directly in the environment.