# Advanced topics
- In Example 1, we used Sass to lay-out a specific webpage/website more efficiently
# Example 2
- In our next example, we will use Sass to start writing our own, simple, Bootstrap-like CSS framework, i.e., TMF (Thomas More Framework)
- The result - after compilation - will be a bunch of CSS classes that can be used on HTML elements for styling purposes
- Below, we will discuss the content of some SCSS files used to setup this framework. By doing so, we can elaborate further on some (more) advanced Sass techniques.
REMARK
The example presented below is only a (small) part of the complete TMF framework, written by Patrick Verhaert as an extensive course example in the spring of 2020.
WATCHING TIP
We refer the interested reader to a series of 19 (Dutch) video's on Canvas > Webdesign Advanced > Modules > TMF - A simple CSS framework with Sass (and jQuery) (opens new window) in which the complete TMF framework is developed from scratch. More than 5 hours of binge watching fun! 😉
# style.scss
// Import fonts & icons
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css');
// Configuration
@import "variables";
@import "reset";
// Layout & components
@import "type";
@import "grid";
// Helpers
@import "helpers/text";
@import "helpers/border";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- Our main SCSS file only contains
@import
statements (to load the different partials) - As you already know, the order of importing the partials is important
- First, we import the necessary fonts & icons
- Google Font Lato (styles: Regular 400, Bold 700 and Black 900)
- Font Awesome
- Next, we import the variables (
@import "variables";
) and execute our (universal) reset (@import "reset";
) - Then, we define some general styling rules (
@import "type";
) as well a very basic grid system (@import "grid";
) - Finally, also some helpers (
@import "helpers/text"; @import "helpers/border";
) are included (e.g. to style the text and borders)
- First, we import the necessary fonts & icons
# _variables.scss
// fonts
$font-size: 14px;
$line-height: 1.5;
$ff-arial: Arial, "Helvetica Neue", Helvetica, sans-serif;
$ff-lato: 'Lato', sans-serif;
// colors
$blue: #009cab;
$red: #f04c25;
$orange: #f7ae19;
$green: #8dab3d;
$black: black;
$gray: #a4a4a4;
$darkgray: #6b6b6b;
$white: white;
$color-map: (
//key: value
'primary': $blue,
'danger': $red,
'success': $green,
'info': $orange,
'black': $black,
'gray': $gray,
'white': $white
);
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
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
- In this partial, we first define some variables related to fonts and colors (lines 1-16)
# Maps
- In addition, we also define a map
$color-map
in which we define several key:value pairs between round brackets (lines 18-27)- This map will be used later on (in the helpers) where we will do something for every (key:value) pair, i.e., we will make a series of similar classes corresponding to these (key:value) pairs
READING TIP
# _reset.scss
- In this partial, we implement our classical universal reset (lines 1-5)
- We also set the general
font-size
,font-family
,line-height
and (text)color
(lines 7-15)
# _type.scss
- In this partial, we define some (standard) styling for the main headings
h1
(lines 1-8) and the paragraphs (lines 21-24)
# @extend
- For the headings
h2
, we want to "duplicate" all the style rules written forh1
elements, which can be achieved by using@extend h1
- Afterwards, we overwrite the
font-size
and theline-height
with some specific values
- Afterwards, we overwrite the
- Likewise, for the headings
h3
, we duplicate all the style rules ofh2
elements with@extends h2
, after which we overwrite thefont-size
READING TIP
# _grid.scss
- The partial _grid.scss only includes the code for a centered
.container
class that is limited in width - The code also contains a nice example of a nested child selector (line 7). That is, all elements (
*
) that are immediate descendants/children (>
) of.container
get some horizontal margin
# helpers/_text.scss
- With this short piece of code, we will define the classes
.text-primary
,.text-danger
, ... to change the textcolor
to the colors (values of the key:value pairs) defined in$color-map
, as shown in the resulting CSS
# @each
- The
@each
rule (line 2) results in an iteration over all the key:value pairs ($key, $value
) in$color-map
READING TIPS
# Interpolation
- Within each iteration step, i.e., for every
$key
and$value
pair, we define a class.text-...
which sets the textcolor
equal to$value
- To embed the
$key
(primary
,danger
, ...) in the CSS class names, we use interpolation, i.e., we wrap the$key
within
#{ }
- To embed the
# helpers/_border.scss
- We start (lines 3-11) with an
@each
iteration that is similar to the one used above, resulting in the classes.border-primary
,.border-danger
, ...- These classes add some
padding
and asolid
,1px
border
around an element, as well as some bottom margin - The border colors are slightly darkened versions of the colors in
$color-map
- These classes add some
REMARKS
- Lines 3-11 could also be written as follows:
//.border-primary, .border-danger, ...
@each $key, $value in $color-map {
.border-#{$key} {
border: 1px solid color.adjust($value, $lightness: -10%);
padding: 1rem;
margin-bottom: 1rem;
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- Yet, we chose to include or nest the
@each
iteration within.border{ ... }
and use the parent selector&
. As such, the two additional@for
loops resulting in more "border" classes (.border-width-5
,.border-radius-50
, ...) are implemented in the same way (within.border{ ... }
).
# @for
- Lines 13-17 use a traditional for loop with the counter
$i
ranging from1
to10
- The use of the keyword
through
means that the value10
will be included in the iteration; you can useto
(@for $i from 1 to 10
) if you want the loop to stop at$i = 9
- Interpolation (
#{$i}
) is used to generate the classes.border-width-1
,.border-width-2
, ...,.border-width-10
(which set theborder-width
equal to1px
,2px
, ...,10px
respectively)
- The use of the keyword
- A similar approach is used (in lines 20-25) for the classes
.border-radius-25
,.border-radius-50
,.border-radius-75
and.border-radius-100
- As we only want 4 classes where
25
,50
,75
and100
stand for the percentage of arem
, we iteratefrom 1 through 4
and use some interpolated mathematical expressions (#{$i*25}
and#{calc($i / 4)}
) for the class names and theborder-radius
values, respectively
- As we only want 4 classes where
READING TIPS
# A TMF-based example page
- Example 2 also contains a sample HTML page dist/index.html
- In this page, the compiled CSS code of our TM Framework is linked:
<link rel="stylesheet" href="css/style.css">
- We illustrate the styling of a
.container
,h1
,h2
andh3
,.text-primary
,.text-danger
,.border-black
,.border-success
,.border-danger
,.border-width-3
,.border-width-5
and.border-radius-50
- In this page, the compiled CSS code of our TM Framework is linked: