About the Sass practice attempt

Recently, Sass was introduced into the project and some CSS improvements were made. The grammar of Sass is relatively easy to learn and use, but the key is to use it in different situations. This article is a summary of Sass techniques, but not a list of Sass features. See the official documentation for more information.

Use & in nesting

It is customary to create a box by naming the container a class and extending the names of the parts of the container based on the class of the container. For example:

.card {}
.card_title {}
.card_content{}
.card_extra{}
Copy the code

We always have to rewrite the class name of the container, and Sass is a great way to avoid typing unnecessary code. This article describes how we can use Sass to solve the problem of long, redundant names in BEM naming methods, such as:

// scss
.card {
  &_title {}
  &_content {}
  &_extra {}
}

// Compile the CSS
.card_title {}
.card_content{}
.card_extra{}
Copy the code

cycle

I have to say that the Sass loop really saves our hands by reducing duplication of code.

@for

usage

// start <= $var < end
@for $var from start to end
  
// start <= $var <= end
@for $var from start through end
Copy the code

If we use HTML to write a loading style

Our loading element looks like this

<div class="loading">
  {Array.from({ length: 12 }).map((_, i) = > (
    <span key={i} />
  ))}
</div>
Copy the code

Each span element is a rectangular bar, and we have them rotated by different angles, so we can:

.loading span {
  / / to omit...
  width: 3px;
  height: 7px;
  animation: roate 0.96 s infinite;

  @for $i from 1 through 11{&:nth-child(#{$i + 1{})animation-delay: 0.08 s * $i;
      transform: rotate(30deg * $i); }}}Copy the code

@each

@each can be used to loop through list or map data

Assuming we have four status styles success, WARing, Info, and Error, we can do this:

// scss
$statusMap: (
  success: #3ccf3c,
  warning: #30baff,
  info: #ff9830,
  error: #ff2a2a
);

@each $header.$attrs in $statusMap# {{.$header} {
    color: $attrs; }}// Compile the CSS
.success {
  color: #3ccf3c;
}
.warning {
  color: #30baff;
}
.info {
  color: #ff9830;
}
.error {
  color: #ff2a2a;
}
Copy the code

This makes it easier for us to maintain and add new state styles.

Sometimes our state style does not only have a specific color, but also other properties, so the map data can be changed

$statusMap: (
  success: (
    border: 1px solid rgba(60.207.60.0.3),
    background: rgba(60.207.60.0.1),
    color: #3ccf3c
  ),
  warning: (
    border: 1px solid rgba(48.186.255.0.3),
    background: rgba(48.186.255.0.1),
    color: #30baff
  ),
  info: (
    border: 1px solid rgba(255.152.48.0.3),
    background: rgba(255.152.48.0.1),
    color: #ff9830
  ),
  error: (
    border: 1px solid rgba(255.42.42.0.3),
    background: rgba(255.42.42.0.1),
    color: #ff2a2a));Copy the code

And then we can do a double traversal

@each $header.$attrs in $statusMap# {{.$header} {
    @each $key.$attr in $attrs {
      #{$key} :$attr; }}}Copy the code

Compile to get what we want

.success {
  border: 1px solid rgba(60.207.60.0.3);
  background: rgba(60.207.60.0.1);
  color: #3ccf3c; } // Omit...Copy the code

And the state style can be used in conjunction with @mixin. For example, sometimes we want only color in some parts of the page, and some want color and background……

So we can wrap it as @mixin and pass in parameters to determine which attribute values we want

@mixin status($options...). {// Process multiple arguments into a list
  / / the default color
  $array: if(list.length($options) > 0.$options, color);

  @each $label.$attrs in $statusMap# {{.$label} {
      @each $key in $array {
        #{$key}: map.get($attrs.$key);
      }
      // Content placeholder
      @content; }}}Copy the code

Now call this mixin

.box1 {
  @include status;
}

.box2 {
  @include status(color, border) {
    border-radius: 4px;
  };
}
Copy the code

The compiled CSS

.box1 .success {
  color: #3ccf3c;
}
.box1 .warning {
  color: #30baff; } // Omit....box2 .success {
  color: #3ccf3c;
  border: 1px solid rgba(60.207.60.0.3);
  border-radius: 4px; } // Omit...Copy the code

At-Rules

@mixin

Mixin is our tool for extracting common style blocks.

usage

@mixin clearfix() {
  &::after {
    display: block;
    clear: both;
    content: ""; }}.box {
  @include clearfix;
}
Copy the code

We can also do this for@mixinAdd parameters, or import content@content. The two@mixinWe’re going to use it a lot.

For example, we extracted a section of the form from Boostrap

@mixin form-validation-state-selector($state) {
  @if ($state= ="valid" or $state= ="invalid") {
    .was-validated #{if(&, "&", "")}:#{$state},
    #{if(&, "&"."")}.is-#{$state} { @content; }}@else {
    #{if(&, "&", "")}.is-# {$state} {
      @content; }}}Copy the code

This mixin can add custom content to specific class names for different form validation states.

Let’s add this mixin to the class of the Valid State Input box:

.form-check-input {
  @include form-validation-state-selector(valid) {
    $color: # 198754;
    border-color: $color;
    
    &:checked {
      background-color: $color; }}}Copy the code

The compiled CSS

.was-validated .form-check-input:valid..form-check-input.is-valid {
  border-color: # 198754;
}
.was-validated .form-check-input:valid:checked..form-check-input.is-valid:checked {
  background-color: # 198754;
}
Copy the code

Also, notice that the mixin above has if(&, “&”, “”). Why do you make this judgment? Because if you define @mixin with a class, then @include doesn’t have to be nested within a class. For example, boostrap can be used globally without nested use.

$state: valid;
@include form-validation-state-selector($state) # {{~.$state}-feedback,
  ~ .#{$state}-tooltip {
    display: block; }}Copy the code

The ampersand parent selector is empty because of the if(ampersand, “ampersand “, “”) judgment, so compile with an empty string instead

// Compile the CSS.was-validated :valid ~ .valid-feedback..was-validated :valid ~ .valid-tooltip..is-valid ~ .valid-feedback..is-valid ~ .valid-tooltip {
  display: block;
}
Copy the code

The other thing about mixins that we use less often is that we can add parameters to @Content.

We can use @Content ($var), and we can use using($type) when using @include.

// scss
@mixin media($types...). {@each $type in $types {
    @media# {$type} {
      @content($type); }}}@include media(screen, print) using ($type) {
  h1 {
    font-size: 40px;
    @if $type == print {
      font-family: Calluna; }}}// Compile the CSS
@media screen {
  h1 {
    font-size: 40px; }}@media print {
  h1 {
    font-size: 40px;
    font-family: Calluna; }}Copy the code

@extend

Opinions vary as to whether or not a project needs to use @extend. From the point of view of this article, @mixin performs better than @Extend, so use @mixin if you can.

If we want to use @extend, we have to be clear about the selector hierarchy, otherwise we can easily backfire. If you had to find a more common @extend scenario in practice, it would be @extend in combination with the placeholder selector %foo.

// scss
%heading {
  margin-top: 0;
  margin-bottom: 0.5 rem;
  font-weight: 500;
  line-height: 1.2;
  color: # 222;
}

h1 {
  @extend %heading;
  font-size: 24px;
}
h2 {
  @extend %heading;
  font-size: 22px;
}
h3 {
  @extend %heading;
  font-size: 20px;
}

// Compile the CSS
h3.h2.h1 {
  margin-top: 0;
  margin-bottom: 0.5 rem;
  font-weight: 500;
  line-height: 1.2;
  color: # 222;
}

h1 {
  font-size: 24px;
}
h2 {
  font-size: 22px;
}
h3 {
  font-size: 20px;
}
Copy the code

@use

@use is used instead of @import. It has also been announced that support for @import will be dropped in 2022. What are the disadvantages of @import? For example,

  • When we import many SCSS files, it is not easy to know which file it came from for a particular mixin or function
  • It’s easy to have naming conflicts that can lead to unnecessary errors.
  • .

More questions have been detailed in the official documentation for us.

The specific use

// variables.scss
$red: #dc3545;

// index.scss
@use 'variables';
.box {
  color: variables.$red;
}
Copy the code

We can also use as to change the name

// index.scss
@use 'variables' as v;
.box {
  color: v.$red;
}
Copy the code

Alternatively, you can use as * and omit the template name. However, if you introduce more than one template, and several templates have mixins or functions with the same name, you can easily have conflicts. Make sure you want to do that.

// index.scss
@use 'variables' as *;
.box {
  color: $red;
}
Copy the code

More no longer lists, reference sass.bootcss.com/blog/the-mo…

additional

The Live Sass Compiler is a plugin for Visual Studio Code that compiles Sass or Scss into CSS in real time. The recommended plugin is github.com/ritwickdey/… Is not updated with the sass update, and many new syntax will fail to compile. Another github.com/glenn2223/v…

summary

When Sass is used properly, we can manage our projects better and maintain them more easily. This is a personal experience of using Sass, and I will continue to try more and more practical writing methods. If there are any errors in this article, please point them out.

The resources

medium.com/@GarrettLev…

www.sass.hk/skill/sass1…

Sass.bootcss.com/blog/featur…

Sass.bootcss.com/blog/the-mo…