Featured image of post Fundamental SCSS

Fundamental SCSS

learning scss, how to install, use variable, etc..

Installation

  • confirm you have installed sass using sass --version or npx node-sass --version
  • if not, then install via
    • brew for mac, brew install node-sass
    • pacman for arch, pacman -S dart-sass

Getting Started

Here we try to use sass for styling html for the first time by changing the html background color.

  1. create files and folder with following structure
1
2
3
4
5
6
.
β”œβ”€β”€ css
β”‚   └── main.css
β”œβ”€β”€ index.html
└── input
    └── main.scss
  1. add standard boilerplate to index.html with this line to the main.css
1
    <link rel="stylesheet" href="css/main.css">
  1. add content to main.scss
1
2
3
body {
    background-color: blue;
}
  1. run sass --watch input:css
    • input is the folder where sass or scss files stored.
    • css is the target folder to store compile result. If the folder missing, the compiler will create it.
    • --watch is the flag to watch for changes in the input folder.
  2. open the browser and you’ll see the background color is changing.

Using npm

  • run npm init -y to create package.json file
  • add sass as dev dependency npm install sass --save-dev
  • add script to package.json
1
2
3
"scripts": {
    "sass": "sass --watch input:css"
}
  • run npm run sass to compile scss files

Variable and Nested Sass

Here is the example of using variables to store color and font-size values

  1. add content to main.scss
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$color-primary: orange;
$color-secondary: grey;
$color-tertiary: royalblue;

$font-lg: 40px;
$font-md: 30px;
$font-sm: 20px;

.nav {
    background-color: $color-primary;
    ul li {
        list-style: none;
    }

    a {
        text-decoration: none;
        font-size: $font-sm;
        color: $color-secondary;

        &:hover {
            color: $color-tertiary;
        }
    }
}

.banner h1 {
    font-size: $font-lg;
    color: $color-secondary;
    text-align: center;
}

.footer h3 {
    font-size: $font-md;
    color: $color-secondary;
    text-align: center;
}

note:

  • without prefix ampersand & the css will be compiled like this .nav a :hover {...}
  • the ampersand prefix & is used to remove the space between the parent and child selector
  • so, with the ampersand prefix, the result will be nav a:hover {...}

Mixin

Mixin is a block of code, which group bunch of reusable CSS styles. To get started, modify the previous main.scss file with:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// same as previous

@mixin headingStyles($fontSize: 50px) {
    font-size: $fontSize;
    color: $color-secondary;
    text-align: center;
}

@mixin transition($param...) {
    transition: $param;
}

.banner h1 {
    @include headingStyles;
}

.footer h3 {
    @include headingStyles($font-md);
    @include transition(color .5s, background-color 1s);

    &:hover {
        color: $color-tertiary;
        background-color: $color-primary;
    }
}

note:

  • the colon + value 50px in the headingStyles($fontSize: 50px) is optional and used for default value
  • if default value stated, then it can be omitted when calling the mixin like @include headingStyles;
  • the three dots ... in the context of the mixin ($param...) are called the splat operator. It allows you to pass an arbitrary number of arguments to the mixin as a list.
  • the splat operator is not only used in mixin, but also in function

Extend

Extend allows one selector to inherit styles of another selector. Let’s practice

  1. remove the previous code in main.scss regarding mixin
  2. replace with this:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
...

.heading {
    color: $color-primary;
    font-size: $font-lg;
    background-color: $color-secondary;
    text-align: center;
}

h1 {
    @extend .heading;

    &:hover {
        background-color: green;
    }
}

.footer h3 {
    @extend h1;
}

note

  • the extend should be followed by single element like @extend h1, cannot @extend banner h1

Function

Function allows us to run code over and over again when we call it.

Let modify the code in the main.scss file above

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...

@use "sass:color";

.nav {
    background-color: color.adjust($color-tertiary, $alpha: -0.9);
    ul li {
        list-style: none;
     }

    a {
        text-decoration: none;
        font-size: $font-sm;
        color: $color-secondary;

        &:hover {
            color: $color-tertiary;
        }
    }
}


.heading {
    color: $color-primary;
    font-size: $font-lg;
    background-color: #{$color-tertiary};
    text-align: center;
}

@function fontSize($size: 25px) {
    @return $size * 2;
}

h1 {
    @extend .heading;

    &:hover {
        background-color: green;
    }
}

.footer h3 {
    @extend h1;
}

.banner p {
    font-size: fontSize($font-sm);
}


.footer p {
    font-size: fontSize(30px);
}

note

Placeholder Selectors %

Placeholder selector allows us to create cleaner and concise code in case of creating class. It creates more readable code because when you see it, you get that it’s created specifically to extend some styles to element(s).

Without placeholder selectors

the main.scss file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// code truncated

.heading {
    color: $color-primary;
    font-size: $font-lg;
    background-color: #{$color-tertiary};
    text-align: center;
}

h1 {
    @extend .heading;

    &:hover {
        background-color: green;
    }
}

// code truncated

the compiled css file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/* code truncated */

.heading, h1, .footer h3 {
  color: orange;
  font-size: 40px;
  background-color: royalblue;
  text-align: center;
}

h1:hover, .footer h3:hover {
  background-color: green;
}

With placeholder selectors %

the main.scss file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// code truncated

%heading {
    color: $color-primary;
    font-size: $font-lg;
    background-color: #{$color-tertiary};
    text-align: center;
}

h1 {
    @extend %heading;

    &:hover {
        background-color: green;
    }
}

// code truncated

the result of compiled css file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/* code truncated */

h1, .footer h3 {
  color: orange;
  font-size: 40px;
  background-color: royalblue;
  text-align: center;
}

h1:hover, .footer h3:hover {
  background-color: green;
}

Import and partials

structure file and folders to this

1
2
3
4
5
6
7
.
β”œβ”€β”€ css/
β”œβ”€β”€ index.html
β”œβ”€β”€ input/
β”‚   β”œβ”€β”€ _footer.scss
β”‚   └── main.scss
└── README.md

in the file _footer.scss put

1
2
3
4
.footer h3 {
    font-style: italic;
    border: 5px solid blue;
}

import the code to the main.scss using @use "footer"

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$color-primary: orange;
$color-secondary: grey;
$color-tertiary: royalblue;

$font-lg: 40px;
$font-md: 30px;
$font-sm: 20px;

@use "sass:color";
@use "footer";

// code truncated

note

  • The underscore _ prefix at the beginning of a file name has a specific meaning related to partials
  • The underscore _ tells SCSS that the file is a partial and should not be compiled directly.
  • The file can be imported into other SCSS files for modularity and reusability.
  • The @import rule is deprecated in favor of the @use rule

Sass Datatype

Numbers

1
2
3
4
5
.numbers {
    font-weight: 400;
    line-height: 1.5;
    font-size: 20px;
}

Strings

1
2
3
4
5
.strings {
    font-family: 'Helvetica', Arial, sans-serif;
    font-weight: bold;
    font-style: italic;
}

Lists

1
2
3
4
5
.lists {
    margin: 10px 15px 5px 20px;
    font-family: 'Raleway', 'Dosis', 'Lato';
    border: 1px solid red;
}

Maps

The key for maps can be string or number.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$colors: (
    primary: red,
    'secondary': green,
    3: blue,
);

h1 {
    color: map-get($colors, primary);
    background-color: map-get($map: $colors, $key: secondary);
}

for Dart Sass 1.33+, it is recommended to use map.get instead of map-get and import the module sass:map

1
2
3
4
5
6
@use "sass:map";

h1 {
    color: map.get($colors, primary);
    background-color: map.get($map: $colors, $key: secondary);
}

Boolean

1
$dark-mode: true;

Null

1
2
3
4
$theme-colors: (
  primary: #3498db,
  secondary: null
);

Interpolation

1
2
3
4
5
6
7
8
9
$b: "border";
$c: "color";

h2 {
    box-sizing: #{$b}-box;
    #{$b}: 1px solid blue;
    #{$c}: red;
    background-#{$c}: green;
};

Looping

For Loop

Suppose we have repeated styles for different paragraph and we would like to apply different background color.

1
2
3
4
5
6
<body>
    <p class="paragraph-1">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-2">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-3">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-4">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
</body>

We can use looping on scss to reduce the code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$paragraph-color: (
    1: red,
    2: green,
    3: blue,
    4: orange,
);

@for $i from 1 through 4 {
    .paragraph-#{$i} {
        background-color: map.get($map: $paragraph-color, $key: $i);
    }
}

Each Loop

docs: https://sass-lang.com/documentation/at-rules/control/each/

Besides, for loop in SASS, we have each loop which like for loop executes block of code over and over again until elements are expired.

in main.html, put

1
2
3
4
5
6
<body>
    <p class="paragraph-red">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-green">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-blue">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
    <p class="paragraph-yellow">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Deleniti, cum.</p>
</body>

in main.scss, put

1
2
3
4
5
6
7
$paragraph-color: red green blue yellow;

@each $color in $paragraph-color {
    .paragraph-#{$color} { 
        background-color: $color;
    }
}

If directive

ref: https://sass-lang.com/documentation/at-rules/control/if/

example usage:

  1. control size of element
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@mixin headingSize($size) {
    @if($size == large) {
        font-size: 45px;
    } @else if($size == medium) {
        font-size: 30px;
    } @else {
        font-size: 15px;
    }
}

h1 {
    @include headingSize(large);
}
  1. control dark mode
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$dark-mode: false;

body {
  @if $dark-mode {
    background-color: #111;
    color: #fff;
  } @else {
    background-color: #fff;
    color: #000;
  }
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus