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!
0 Nhận xét