Responsive Advertisement

SASS/SCSS #2: Style rule in SASS/SCSS

 

Welcome back to the series about SASS/SCSS, this is where we share our knowledge of SASS/SCSS from basic to advanced. If you love this topic, here is the link for you to follow to know more. SASS/SCSS series.

In this article, we will discuss Style rule in SASS/SCSS.

Table of contents:

  • Nested
  • Interpolation, different between $ and #{$}
  • Property declaration – scope
  • Let’s go to the content!

Nested

In the article about SASS/SCSS part 1, I mentioned about the nested problem in SASS/SCSS, now let's go deeper into this part. We already know the basic way of nesting in SASS/SCSS, that is, the child components will be inside the "{}" sign of the parent component. For other signs like “>”, “+”, “~”, … how will we show them in SASS/SCSS.

// index.scss

.label + {

    .input {

        background-color: #eee;

    }

}

.btn {

    > .bg {

        color: #fff;

    }

}

.header:hover {

    ~ {

        .nav {

            display: block;

        }

    }

}

 

Let's see what the above lines of code will compile?

/* index.css */

.label + .input {

  background-color: #eee;

}

 

.btn > .bg {

  color: #fff;

}

 

.header:hover ~ .nav {

  display: block;

}

 

Just like the usual nested theory, we also have components enclosed in "{}" that will be children of the parent components. Now we combine them with the signs "+", ">", "~" ... in css. The relationship between the parent component and the children component will be combined with the marks above. Not merely contained, but horizontal or combined.

Interpolation, different between $ and #{$}

This is a rather confusing concept for newcomers to SASS/SCSS. To better understand interpolation, let's go through a problem as follows to understand what Interpolation solves?

// index.scss

$font-size: 16px;

$line-height: 1.5;

$font-family: sans-serif;

 

body {

    font: $font-size/$line-height $font-family;

}

 

This is the usual way of writing when you want to create css fonts for components. The result of the above problem will be:

/* index.css */

body {

  font: 10.66667px sans-serif;

}

 

“10.66667px” is the result of dividing “$font-size” and “$line-height”. Put in another case you don't want the result like that, you need the result will be “16px/1.5” then now what you need to do is add “#{}” to “$variable”. Let's see the code:

// index.scss

$font-size: 16px;

$line-height: 1.5;

$font-family: sans-serif;

 

body {

    font: #{$font-size}/#{$line-height} $font-family;

}

 

And let's see if the results of the above code match the requirements we set?

/* index.css */

body {

  font: 16px/1.5 sans-serif;

}

 

Awesome! Completely consistent with what we set out.

So what is the difference between “#{$}” and “$”? First, both return the value that the variable is storing. “$” returns a value, but will be affected by operations and conditions. And “#{$}” will still return a value but will not be affected by operations and conditions. Besides, “${#}” can be used anywhere, while “$” is limited to a few locations. Let's see some examples to understand this better.

// index.scss

@mixin background($property, $value) {

    background-$property: $value;

    // => Error colon expect

}

body {

    @include background('color', #eee);

}

 

In the first example we use @mixin - @include to make the problem is that we customize the background as desired. The error occurs when we use the variable "$property" to make "property". However, we can use “$value” as a value. So let's change “#{$}” to see the difference!

@mixin background($property, $value) {

    background-#{$property}: $value;

    color: #{$value};

}

body {

    @include background('color', #eee);

}

 

And the result for the above code will be:

/* index.css */

body {

  background-color: #eee;

  color: #eee;

}

 

You can see that “#{$}” can be used in property or value. And "$" will only be usable in value, if you intentionally attach a property, you will get an error immediately.

Let's go through the selector to better understand.

// index.scss

$nav: 'nav';

.$nav-primary {

    // => Error indentified expect

    background-color: #eee;

}

 

In the above example, we intentionally used “$nav” as a selector, resulting in an error and unable to compile the code into css. Now we will change “$” to “#{$}”.

$nav: 'nav';

.#{$nav}-primary {

    background-color: #eee;

}

 

And let's see how the return result will be?

/* index.css */

.nav-primary {

  background-color: #eee;

}

 

So we have one more difference between “$” and “#{$}”. That is “#{$}” can use selector and “$” is not.

Let's come up with another example. If you often work with “:root” then you know that root will be the place to initialize variables for use by components. Let's see if we implement “:root” in SASS/SCSS, what will happen?

// index.scss

$primary-clr: #232323;

$secondary-clr: #565656;

$accent-clr: #879797;

$text-clr: #f9f9f9;

 

:root {

    --primary-clr: $primary-clr;

    --secondary-clr: $secondary-clr;

    --accent-clr: $accent-clr;

    --text-clr: $text-clr;

}

 

When looking at it, what would you predict the outcome would be? You would think that the result would be compiled in the .css file as “—primary-clr: #232323 …”. This is a very logical thought. And let's see what our results will be?

/* index.css */

:root {

  --primary-clr: $primary-clr;

  --secondary-clr: $secondary-clr;

  --accent-clr: $accent-clr;

  --text-clr: $text-clr;

}

 

Wow! Why we don't get the value of the variable but we get the variable name? We will talk about how SASScript compiles dynamic values. Most Sass variables are compiled to value via "$". However, there will be an exception that is interpolation via “$”. This is when SASScript compiles SASS variables into CSS variables. SASScript will check the validity of CSS variables. If this is valid then it stays the same and does not compile further to value. Those are the interpolations when using the "$" sign. In other case we use “#{$}” the story will be different.

// index.scss

$primary-clr: #232323;

$secondary-clr: #565656;

$accent-clr: #879797;

$text-clr: #f9f9f9;

 

:root {

    --primary-clr: #{$primary-clr};

    --secondary-clr: #{$secondary-clr};

    --accent-clr: #{$accent-clr};

    --text-clr: #{$text-clr};

}

 

And when we compile into CSS variables we will get something like this:

/* index.css */

:root {

  --primary-clr: #232323;

  --secondary-clr: #565656;

  --accent-clr: #879797;

  --text-clr: #f9f9f9;

}

 

This is interpolation in SASScript. And this seems to only happen at ":root", if we apply the same things in other selectors everything will return to normal..

// index.scss

$primary-clr: #232323;

$secondary-clr: #565656;

$accent-clr: #879797;

$text-clr: #f9f9f9;

 

* {

    background-color: $primary-clr;

}

 

html {

    color: $text-clr;

}

 

And see if the result looks like “:root”:

/* index.css */

* {

  background-color: #232323;

}

 

html {

  color: #f9f9f9;

}

 

So we know the interpolation in SASScript, and this applies at “:root”. You will need to keep this in mind to compile from SASS variables, then CSS variables to your liking.

Property declaration – scope

In part one about SASS/SCSS, I talked about the naming and syntax of a variable in SASS/SCSS. Now we will discuss the problem of what data type the variable in SASS/SCSS will contain and its scope.

First, types such as string, number, null, boolean, lists, colors then SASS variables can be stored.

// index.scss

$string-var: 'hello';

$num-var: 1;

$color-var: #454545;

$boolean-var: true;

$null-var: null;

$list-var: (

    'a': 1,

    'b': 2

);

 

body::after {

    content: $string-var;

    opacity: $num-var;

    color: $color-var;

    background-color: if($boolean-var, red, blue);

    border: $null-var;

}

 

And let's see how the above code will be compiled:

/* index.css */

body::after {

  content: "hello";

  opacity: 1;

  color: #454545;

  background-color: red;

}

 

In the compiled code, we see that the null value will not display the property. The rest of the list data type will have another article analyzing this data type.

Next we will discuss scope in SASS. Like all programming languages, the scope of a variable comes first. In SASS, the scope of variables becomes a little simpler. First, we will have the global scope. Where, all components can be used.

// index.scss

$primary-clr: #343434;

 

body {

    background-color: $primary-clr;

}

 

And the code will be compiled into CSS variables.

/* index.css */

body {

  background-color: #343434;

}

 

Next, we have the local scope. Where variables are only allowed to be used locally and cannot be used elsewhere.

// index.scss

body {

    $primary-clr: #343434;

    background-color: $primary-clr;

}

 

header {

    background-color: $primary-clr;

    // => Error

}

 

Other components will not be able to use local variables, but for nested, components inside nested can be used.

// index.scss

body {

    $primary-clr: #343434;

    background-color: $primary-clr;

   

    header {

    background-color: $primary-clr;

    }

}

 

And the code will be compiled into:

/* index.css */

body {

  background-color: #343434;

}

 

body header {

  background-color: #343434;

}

 

In other case, when variables are in local scope and in children component, then the question will be whether parent components can use that variable or not? Let's come to the example:

// index.scss

body {

    background-color: $primary-clr;

    // error

    header {

    $primary-clr: #232323;

    background-color: $primary-clr;

    }

}

 

Absolutely error. These are some typical cases for variables scope. In case you want to overridden an existing variable, how do you do it?

// index.scss

$font-size: 18px;

 

body {

    $font-size: 16px;

    font-size: $font-size;

}

 

p {

    font-size: $font-size;

}

 

You will need to reassign the variable a different value. And let's see how the code will compile?

/* index.css */

body {

  font-size: 16px;

}

 

p {

  font-size: 18px;

}

 

The value of the variable “$font-size” has been changed in the local of the “body” tag. However, in "p" the value is the same as in local. In case you want to change the value and it will apply to all other selectors, how do you do it?

// index.scss

$font-size: 18px;

 

body {

    $font-size: 16px !global;

    font-size: $font-size;

}

 

p {

    font-size: $font-size;

}

 

By reassigning the value to the variable, you add “!global”. SASScript will automatically adjust so that all other selectors use the same value. Let's see the results:

/* index.css */

body {

  font-size: 16px;

}

 

p {

  font-size: 16px;

}

 

So we already know how to reassign the value to the variable and limit this value to any part of use.

Conclusion

We've gone through the style-rule of sass, and already know advanced nested, interpolation, scope in SASS.

If you have any comments, feel free to comment below. Thank you for joining with me. Having a good day!

Đăng nhận xét

0 Nhận xét