# 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
  • 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)

# _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
  • 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

# _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 for h1 elements, which can be achieved by using @extend h1
    • Afterwards, we overwrite the font-size and the line-height with some specific values
  • Likewise, for the headings h3, we duplicate all the style rules of h2 elements with @extends h2, after which we overwrite the font-size

# _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 text color 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

# Interpolation

  • Within each iteration step, i.e., for every $key and $value pair, we define a class .text-... which sets the text color equal to $value
    • To embed the $key (primary, danger, ...) in the CSS class names, we use interpolation, i.e., we wrap the $key within
      #{ }

# 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 a solid, 1px border around an element, as well as some bottom margin
    • The border colors are slightly darkened versions of the colors in $color-map

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
  • 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 from 1 to 10
    • The use of the keyword through means that the value 10 will be included in the iteration; you can use to (@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 the border-width equal to 1px, 2px, ..., 10px respectively)
  • 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 and 100 stand for the percentage of a rem, we iterate from 1 through 4 and use some interpolated mathematical expressions (#{$i*25} and #{calc($i / 4)}) for the class names and the border-radius values, respectively

# 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 and h3, .text-primary, .text-danger, .border-black, .border-success, .border-danger, .border-width-3, .border-width-5 and .border-radius-50

TMF Example

Last Updated: 3/7/2023, 6:47:19 AM