Skip to main content

Style a site using Sass

Sass site

You can do a lot with CSS – perhaps more than you might think – but the venerable style sheet language has its limitations. In a modern web project, with npm modules, JavaScript frameworks, ES6 and more, it can feel somewhat anachronistic to fall back to writing vanilla CSS.

Fortunately, there are options out there that allow you to use other languages that compile to CSS. Referred to as ‘preprocessors’, these tools integrate into your web build process and generate usable style sheets from whatever extension language you’ve chosen.

Sass (Syntactically Awesome Style Sheets) is one of the most popular of these options – read more with our guide What is Sass? Sass adds many valuable new language features that aren’t (currently) available in CSS to help make your sites and apps more maintainable. These include things like mixins and control directives, which sound daunting but are actually quite straightforward, and we’ll look at these in this tutorial.

There are actually two different syntaxes for Sass, one that uses a .scss file extension, and one that uses .sass. The former looks more like CSS (in fact, all .css files are valid .scss files), while the latter eliminates CSS’ brackets and semicolons in favour of indentation and newlines. We’ll focus on .scss, but the choice is simply down to personal preference.

Download the files for this tutorial here (issue 282)

Sass website screenshot

The Sass website has plenty of useful documentation

01. Set up the compiler

Using Sass essentially requires a compiler. The simplest way to do this would be at the command line. You can do so using Homebrew. The Sass compiler is implemented in several different languages, and Homebrew will install the Dart version, which is fast.

brew install sass/sass/sass

02. Create a Sass file

Let’s try creating a simple Sass file to see the compiler in action. One of the simplest concepts in Sass is variables, which can be specified once with a $ prefix and then used throughout your code. We’ll create sass-input.scss.

$text-color: #cccccc;
body {
    color: $text-color;
}

03. Command line compilation

Now we can run the Sass compiler at the command line to convert our .scss file into CSS output. You’ll notice in the output file that the variables are gone and we’re just left with standard CSS syntax that is usable by the browser.

sass sass-input.scss css-output.css

04. Automate your build

This is great, but you don’t want to run the Sass compiler manually every time you make changes. One option is to have it listen for changes to files in a directory and automatically recompile the output to a different directory (preserving filenames). This also effectively lets you segregate your source .scss file from your built CSS.

mkdir src
mkdir src/sass
mkdir public
mkdir public/css
sass --watch src/sass/:public/css/

05. Play with Sass styling

Now let’s look at a simple starter site, which we can use to play around with Sass styling. We can get started by cloning an unstyled example site. The key thing to note is that our HTML page knows nothing about Sass. It has a single CSS file entry point, which we’ll create next.

cd public
curl -o index.html https://raw.
githubusercontent.com/simon-a-j/sass-
tutorial/
master/public/index.html

06. The main stylesheet

We’re using styles.css as our main CSS entry point, which later on we’ll use to import other modules. This means we need to tell Sass to generate this file, so we also need to create a styles.scss file in our src/sass folder. If you’re running sass --watch as before, this will automatically be compiled into CSS in the public/css folder, and refreshing your site will show its changes. Try making some modifications and refreshing the HTML page in the browser as you go.

// styles.scss
body {
  font-family: sans-serif;
  text-align: center;
}

07. Manage colour scheme

Sass website with a colour scheme of blue

There's now a colour schemes thanks to a Sass partial

Let’s look at how Sass can help us manage a colour scheme for the site. It’s common to have a palette of five or six colours for a webpage. We can externalise these in       _colours.scss. The underscore prefix tells Sass not to compile this into a new HTML file (a ‘partial’). But we can use it in a slightly different way.

// _colours.scss
$colour-primary: #231651;
$colour-secondary: #2374AB;
$colour-light: #D6FFF6;
$colour-highlight1: #4DCCBD;
$colour-highlight2: #FF8484;

08. Use colour variables

To use these colour variables we’ve just set up, we can tell Sass to import the content of _colours.scss into our main style sheet. We do this using an @import statement. Once you’ve done this, notice how the variables are resolved within the output CSS file.

// styles.scss
@import “_colours.scss”;
body {
  font-family: sans-serif;
  text-align: center;
  background: linear-gradient(155deg,
$colour-primary 70%, $colour-secondary 
70%);
  color: $colour-light;
  min-height: 100vh;
}
h1 {
    color: $colour-highlight1;
}
h2 {
  color: $colour-highlight2;
}

09. Nest styles

Another useful feature of Sass is the ability to nest styles. That is, you can specify a style for an element that is only applied if that element occurs within a parent element. Let’s use this to differentiate our styling of links depending on whether they appear in the header or body.

a {
  color: $colour-secondary;
}
.profile-header {
  a {
    font-size: 16px;
    margin-left: 10px;
    margin-right: 10px;
    padding: 10px;
    border-radius: 5px;
    color: $colour-light;
    background-color: $colour-secondary;
  }
}

10. Make responsive grid

Sass site with grid

A responsive grid is easier to manage with Sass variables and nesting

Now let’s arrange our content into a responsive grid format. Sass has a couple of features to make this significantly easier to manage. As well as using variables to specify our breakpoints, we can nest @media queries within other styles, which makes behaviour specific to screen size much more readable.

$breakpoint: 800px;
.profile-body {
  display: flex;
  align-items: stretch;
  justify-content: space-around;
  margin-top: 32px;
  margin-left: 10vw;
  margin-right: 10vw;
  @media screen and (max-width: 
$breakpoint) {
      flex-direction: column;
  }
}
.profile-section {
  background-color: $colour-highlight1;
  color: $colour-primary;
  margin: 16px;
  border-radius: 10px;
  width: 340px;
  .profile-content {
    padding: 20px;
  }
  @media screen and (max-width:
$breakpoint) {
    width: 100%;
  }
}

11. Introduce mixins

Sass with mixin

A mixin helps maintain backward compatibility with older browsers when using CSS transforms such as rotation

Mixins are another powerful Sass feature, which you can think of as a way of defining reusable stylesheet functions. A mixin is defined once, can take parameters, and can then be invoked anywhere in your Sass code. One use case for this is to handle vendor prefixing. If we want a CSS transform to work in older browsers, this might require a -webkit prefix for Chrome and Safari, for example. Let’s define a mixin that takes care of this for us.

12. Mixins and variables

We can also use a mixin with multiple parameters, combined with some variables that we define, to more elegantly handle styling of various parts of the page. If we create a mixin that defines foreground and background colour, this will enable us to select appearances for different sections from a finite list of style variables.

$style1: (foreground: $colour-light, 
background: $colour-secondary);
$style2: (foreground: $colour-primary, 
background: $colour-highlight1);
$style3: (foreground: $colour-primary, 
background: $colour-highlight2);
@mixin content-style($foreground, 
$background) {
  color: $foreground;
  background-color: $background;
}

13. Use your new mixin

.profile-header {
  a {
    @include content-style($style1...);
    // …
  }
}
.profile-section {
    @include content-style($style2...);
  // …
}

14. Understand inheritance

Another very powerful feature of Sass is inheritance. Right now we have two different styles for links in our page. If we want to use common styles across both, rather than copying and pasting CSS, why don’t we use a placeholder class, denoted with ‘%’, which can be extended by both, allowing them to inherit its styles?

%link-shared {
  font-size: 16px;
  margin-left: 10px;
  margin-right: 10px;
  padding: 10px;
  border-radius: 10px;
}

15. Extend classes

Now we can extend the link-shared class to define link styling throughout our site. This is starting to look quite elegant. We define what a link generally looks like just once, reuse it throughout, and specify colours from the palette for each link using a mixin.

.profile-header {
  a {
    @extend %link-shared;
    @include content-style($style1...);
  }
}
a {
  @extend %link-shared;
  @include content-style($style3...);
}

16. Modify the theme

Now let’s take a look at how easy Sass makes it to modify the theme of our site. The current colours might not be perfect. We cannot only modify the colour variables, but we can also use some Sass functions to procedurally generate colours that match a primary of our choosing.

// _colours.scss
$colour-primary: #2E1F27;
$colour-secondary: lighten($colour-primary, 
25%);
$colour-light: lighten($colour-primary, 
75%);
$colour-highlight1: 
lighten(complement($colour-primary), 50%);
$colour-highlight2: 
lighten(complement($colour-secondary), 50%);

17. Select a new set of colours

Now, we can modify the entire colour scheme for the site simply by specifying a new colour-primary value in the _colours.scss file. Give it a try by experimenting with alternative colours. We could also have Sass randomise it (but remember this refers to the point at which your site is built, not runtime). You can also try adjusting the logic we’re using to derive the other colours in the theme from the primary.

$red: random(255);
$green: random(255);
$blue: random(255);
$colour-primary: rgb($red, $green, $blue);

18. Use libraries

Sass’s module system also makes it very straightforward to use third-party libraries with minimal effort, and without shipping large runtime files to your end users. Let’s try out the Angled Edges library, which we can use to create sloped edges for objects on our page.

git clone https://github.com/josephfusco/
angled-edges.git src/sass/angled-edges

19. The Angled Edges mixin

We can import Angled Edges the same way we did for our colour scheme partial. It’s then usable via a mixin that ships with the library. Let’s try it out in our profile-section class.

@import “angled-edges/_angled-edges.scss”;
.profile-section {
  @include angled-edge(“outside bottom”, 
“lower right”, $colour-highlight1);
  @include angled-edge(“outside top”, 
“upper right”, $colour-highlight1);
  margin: 120px 16px 120px 16px;
  // ...
}

20. Output formatting

Let’s finish up by looking at the output Sass generates. If you’ve been tracking your CSS files as we’ve made changes, you’ll notice they remain quite readable. However, you can also have Sass build condensed CSS, which is less human-readable but still ready to ship. You can do this using the --style command-line flag.

sass src/sass/:public/css/ --style 
compressed

21. More Sass

We’ve now explored quite a few features of Sass, and our site isn’t looking too bad. Hopefully you’re beginning to see how Sass helps us develop more maintainable style sheets. We haven’t covered every feature of the language – there are many more useful functions shipped with it, and advanced features like control directives (such as @if, @for and @while) that are often used to create complex library functions. Overall, remember that Sass is entirely a stylistic preference. You can do everything we’ve seen with pure CSS if you like, but you should definitely think about pre-processing as your work becomes more complex.

This article was originally published in issue 282 of Web Designer. Buy issue 282 or subscribe here.

Read more: