Welcome back to the series of articles on SASS/SCSS. If you love this topic, here is the link for you to follow other articles. Series about SASS/SCSS.
Table of
contents:
- Parent selector
- Parent selector combined with BEM
- Advanced @mixin - @include
Let’s go to
the content!
Parent
selector
If you are
familiar with SASS/SCSS then you are no stranger to nested in SASS/SCSS. In
this section we discuss the more advanced parts of nested. This is the usual
way of writing from parent components to child components.
// index.scss
.card {
background-color: #232323;
.card__header {
padding: 1rem;
}
}
And the
result for the above code will be:
/* index.css */
.card {
background-color: #232323;
}
.card .card__header {
padding: 1rem;
}
These are
the basics. However, have you noticed that when you select child selectors with
the same name as the parent selector, you need to repeat the name. In the
example above we have the parent selector as “card” and the child selector as
“card__header”. Both coincide as "card". Now we must have a way to
minimize this duplication. Let's see how the above problem will be solved:
// index.scss
.card {
background-color: #232323;
position: relative;
&::before {
content: '';
position: absolute;
width: 20px;
height: 10px;
}
}
And the
result will be:
/* index.css */
.card {
background-color: #232323;
position: relative;
}
.card::before {
content: "";
position: absolute;
width: 20px;
height: 10px;
}
Do you see
what's happening? We have an "&" added. The "&"
sign represents the currently selected selector. In this case is the class
"card". We solved the repeat selector problem in SASS/SCSS. Let's
continue to go through the other sections to see what more problems the
selector can solve.
// index.scss
.card {
background-color: #232323;
position: relative;
:not(&) {
display: none;
}
&:nth-child(2) {
background-color: red;
}
&__header {
padding: 1rem;
}
}
And the
result we get will be:
/* index.css */
.card {
background-color: #232323;
position: relative;
}
:not(.card) {
display: none;
}
.card:nth-child(2) {
background-color: red;
}
.card__header {
padding: 1rem;
}
True to
theory, the "&" sign replaces the nearest selector containing it,
this is a shorthand way of writing.
Note, if
you combine "&selector" will give a different result, if you
combine "& selector" will give a different result.
// index.scss
.btn {
&:hover {
background-color: green;
}
& .header {
padding: 1rem;
}
}
The result
for the above difference will be:
/* index.css */
.btn:hover {
background-color: green;
}
.btn .header {
padding: 1rem;
}
The result
will coincide with the way you combine “&” with the selector. Depending on
each specific case, you should use the "&" sign appropriately.
Parent
selector combined with BEM
First, we
talk about what is the class naming standard according to the BEM standard?
This is a naming rule of the form main__component—modifier. “Main” is the main
component that covers everything inside. We can get as card, navigation,
notification. "Component" will be the child components in the main
part, can be header, body, title, description, ... To connect between the main
part and the child, we use two "__" signs. “Modifier” is the
different state of each component, for example, we have a success message, a
failure message, … To add a modifier, we will use “—” oil to combine.
We've
briefly gone over the BEM standard in class naming. We will combine the BEM
standard and the parent selector to create the fastest and most efficient code.
// index.scss
.card {
box-shadow: 0px 8px 8px 1px rgba(0, 0, 0, 0.1);
&__header {
width: 100%;
}
&__body {
padding: 1rem;
}
&--success {
background-color: green;
}
&--warning {
background-color: yellow;
}
}
Let's see
the results we get:
/* index.css */
.card {
box-shadow: 0px 8px 8px 1px rgba(0, 0, 0, 0.1);
}
.card__header {
width: 100%;
}
.card__body {
padding: 1rem;
}
.card--success {
background-color: green;
}
.card--warning {
background-color: yellow;
}
You see that
if we know the parent selector we can name it according to the BEM criteria extremely
simply and quickly.
Another
note is that “&” will represent the current selector. Let's see the
following example:
// index.scss
.btn {
& .header {
padding: 1rem;
& .title {
font-size: 1.5rem;
}
}
}
And the
result will be:
/* index.css */
.btn .header {
padding: 1rem;
}
.btn .header .title {
font-size: 1.5rem;
}
The
ampersand "&" inserted in any scope will represent the selector
in that scope. As the example above we see that the same sign "&",
but the results are completely different. Depending on the scope, the sign
“&” is standing.
Advanced @mixin
- @include
In part one
of my SASS/SCSS series I covered the basic usage of @mixin - @include. Includes
using no arguments, having arguments, and setting arguments to default value.
In this article we go through another way to use arguments in @mixin -
@include. Let's come to the following example:
// index.scss
@mixin btn($arguments...) {
@each $arg in $arguments {
@debug $arg
}
};
.btn {
@include btn(border, width, height)
// scss\index.scss:4 Debug: border
// scss\index.scss:4 Debug: width
// scss\index.scss:4 Debug: height
}
In the above
problem we are dealing with a case where when we don't know the exact number of
arguments we receive for a @mixin we can use $variable-name…. This means we can
take as many arguments as we want. In the above wallet in class “.btn” we get
three arguments and we print it in terminal via @debug. And we see that the
results we get are the same as the arguments we passed in.
However, for
receiving many arguments we still find it not enough, we only get one value, so
we cannot solve a specific problem. Receiving multiple arguments at @mixin and
passing arguments at @include makes for a great combination.
// index.scss
@use 'sass:meta';
@mixin btn($arguments...) {
@each $key, $val in meta.keywords($arguments) {
@debug $key - $val
}
};
@include btn(
$border: 20px,
$width: 20px,
$height: 20px
)
// scss\index.scss:5 Debug: border-20px
// scss\index.scss:5 Debug: width-20px
// scss\index.scss:5 Debug: height-20px
As you can
see above, we have made some changes in receiving arguments in @mixin and
@include. For @include we no longer use merely the value passed. We have $key:
value. We use @use to use the library as “meta” in SASS.
Note that
if we pass arguments of the type $key: value without using "meta" we
will not be able to get the values of the type $key, $value in that argument.
Next we use
“meta.keywords(arguments)” to get the key, value pair. In the end we get the
results we want.
Going
through the above problem, we know how to use multiple arguments in @mixin -
include. So let's apply the knowledge we have just learned to real problems to
solve the problem.
We will
create buttons with different modifiers like success, warning, danger, info.
Characteristic for each button will be a different color. The properties that
make up a button will be the same. And we only use one @mixin and get multiple
arguments to solve this problem. Let's do it step by step.
First, to
handle receiving multiple arguments and separate them into key and value
counters, we must use "sass:meta", to use meta.keywords. Next we will
get key, value pairs to use to create modifers for buttons.
// index.scss
@use 'sass:meta';
@mixin btn($arguments...) {
@each $key, $value in meta.keywords($arguments){
.btn--#{$key}{
background-color: #{value};
}
}
}
Now we will
build common properties for a button and use @include to create modifiers for
the button.
// index.scss
.btn {
padding: 0.5em 1em;
font-size: 0.75rem;
border-radius: 20px;
@include btn(
$warning: yellow,
$success: green,
$danger: red,
$info: blue
)
}
Now let's
see what the result will be:
/* index.css */
.btn {
padding: 0.5em 1em;
font-size: 0.75rem;
border-radius: 20px;
}
.btn .btn--warning {
background-color:
value;
}
.btn .btn--success {
background-color:
value;
}
.btn .btn--danger {
background-color:
value;
}
.btn .btn--info {
background-color:
value;
}
Awesome! We
have created a class “btn” that shares the buttons and has a modifier for each
type of button. This is a small application problem in practice. You can apply
these multiple arguments to solve more problems.
Conclusion
We have just
learned and applied “&” to make the selector problem easier. At the same
time, we also combine “&” with the BEM standard. I also went through
advanced @mixin - @include.
If you have
any ideas, feel free to comment below. Thank you for joining with me. Having a
good day!
0 Nhận xét