Joe Casabona Podcast Consultant, Educator. Dad. Husband. Likes Yankees, Cigars, Disney. Makes courses for @lynda . Writes tech books. Host of @howibuilt .

A beginner’s guide to programming for CSS with Sass

5 min read 1407

In recent years, CSS has transformed from writing simple rulesets to a powerful engine for creating beautiful user experiences. But as projects grow more complicated, as does the CSS that is being written, it gets harder to manage and even harder to make changes. Native CSS has implemented some new tools to help with this, like Grid and variables, but CSS preprocessors take writing and managing CSS to the next level.

Aside from writing flexible, reusable rulesets, CSS preprocessors like Sass bring powerful program logic to CSS. That’s right – using Sass, you can perform arithmetic operations, write functions (@mixins), and even use control structures like if/else statements and loops. In this article, we’ll take a look at all the ways you can write programmable logic in CSS. The syntax being used is SCSS.

TIP: If you’ve never used SCSS before, I recommend checking out this guide to get started. But fret not! If you just want to see what SCSS has to offer as far a program logic goes, you can do so in CodePen.io

Low hanging fruit: arithmetic operators

The easiest way to get started with programming in SCSS is by doing math. There are five arithmetic operations you can perform:

  • Addition with +
  • Subtraction with -
  • Multiplication with *
  • Division with /
  • Get the remainder with %

This allows you to use math in your font sizing, or even create nice gradients in styles. Here’s an example:

  $scale: 1.5;
    $heading-base: 65px;
    
    h1 {
      font-size: $heading-base;
    }
    
    h2 {
      font-size: $heading-base / $scale;
    }

Thanks to a simple divisor, your heading font sizes are now scaled, relative to each other. And later, you’ll see how to make that even better.

One thing to note if you can only use these operators on similar units. So you can’t multiply px and em for example. You can use operators on hex colors though to make some interesting colors! As a general rule, I try to use only numbers, without units, for math in SCSS when I can.

But using math in CSS is only the start. Let’s take a look at even more powerful programming features of SCSS.

@mixins: The functions of SCSS

Repeatable code is an important aspect of any programming language, and SCSS is no different. Using @mixin, you can create a set of code that’s reusable. Here’s a simple example:

@mixin button() {
        background: #880000;
        color: #FFFFFF;
        border-radius: 10px;
        padding: 15px;
        text-align: center;
}

a.button {
  @include button;
}

In this mixin, we have a set of common rules for all buttons. Then, as we declare something that should have those rules, we can use the @include directive to import that ruleset. But it gets better. You can pass variables to mixins as well. Let’s say, for example, you want to control the color of the button:

We made a custom demo for .
No really. Click here to check it out.

@mixin button($color) {
        background: $color;
        color: #FFFFFF;
        border-radius: 10px;
        padding: 15px;
        text-align: center;
}

a.button {
  @include button(#008800);
}

Finally, if you want a default changeable color, you can set an optional variable:

@mixin button($color: #880000) {...}

Then if you send a color, that’s used. And if not, the default, #880000 is used.

You can imagine this is pretty powerful for having, controlling, and modifying a set of common styles. If the general style for all buttons ever changes, you’d only need to change it in the @mixin.

With the ability to generalize code and make it repeatable, there’s another thing you might want to add to your toolset: decision making.

Controlling flow: using if statements for your CSS

Some would argue that programming is pretty much making specific decisions based on some condition. And while I’ll save the philosophical discussion for a different article, it is true that decision making unlocks a lot of power in code to control the flow of a program.

In SCSS, this is less about reacting to real-time interactions (that’s what media queries are for), and more about being able to consolidate and better manage large blocks of rulesets. Let’s look at an example:

@mixin shape($w, $h, $circle: false) {
        width: $w;
        height: $h;
        background: #FF0000;
        @if $circle {
                border-radius: 50%;
        }
}

.square {
  @include shape(100px, 100px);
}

.circle {
  @include shape(100px, 100px, true);
}

In this mixin, we create a general shape (well, really a square) but thanks to the @if, we can use the same mixin to create a circle as well. In a more practical example, and one that uses @else to, you might have a mixin to manage the base styles for a “dark mode”:

@mixin theme-styles($dark-mode: false) {
 @if $dark-mode {
    //Set styles based on dark mode variables
  } @else {
    //Set styles based on light mode variables
  }       
}

So math lets us make better calculations for our measurements, mixins let us generalize rulesets to make them easier to manage from a high level, and if/else statements let us take that management one step further by conditionally adding rulesets and properties as needed.

But perhaps the biggest time saver in SCSS program logic is loops.

Repetition: create beautiful styles with loops

Loops let you repeat a task as long as some condition is true. There are three types of loops in SCSS:

  • @for
  • @while
  • @each

For loops

The @for loop is a simple counting loop. You can perform a task a specific amount of times. A great example of this is easily creating those scaled heading sizes we looked at earlier:

$heading-size: 65px;

@for $i from 1 through 6 {
        h#{$i} {
                font-size: $base-size;
        }

        $heading-size: $heading-size / 1.25;
}

Here, we have a variable we’ve defined as $i (commonly used in loops; you can think of it as “index” or “interator”), which starts at 1 and increments up to 6. Then we have a little bit of clever syntax in SCSS that lets us use variable names in selectors. First, we use the hash sign (#) to indicate we’re starting a variable name, then we wrap the variable in curly braces ({ }).

So here we’re using $i to define each of the 6 heading tags. Then we’re setting a font size based on the $heading-size variable. At the end of the loop, we divide that variable by 1.25, making it smaller, then doing the same thing for the next heading tag. So the rendered CSS looks like this:

h1 { font-size: 65px; }
h2 { font-size: 52px; }
h3 { font-size: 41.6px; }
h4 { font-size: 33.28px; }
h5 { font-size: 26.624px; }
h6 { font-size: 21.2992px; }

Nice, mathematically scaled heading sizes!

While loops

@while loops are similar, but we’re not relegated to a single incrementor. We can do something like create a scaled gradient, based on some multiplier:

$gradient: 1;
$i: 1;
@while $gradient >= 0.1 {
        main p:nth-child(#{$i}) {
                background: rgba(0,0,240, $gradient);
                min-height: 20px;
                margin: 0;
        }

        $gradient: $gradient - 0.1;
        $i: $i + 1;
}

In this example, we’re targeting <p> inside a <main> element, and stepping down a blue gradient for each child. We have 2 counters here: the $gradient, which controls the opacity, and $i, which is counting for nth-child.

This can also be used to create a set of gradient classes, or create a nice visual effect for long content.

Each loops

Perhaps the most interesting loop in SCSS is the @each loop. This let’s you step through variable lists(SCSS’s version of arrays). You can do some pretty nifty stuff with the right combination of info. Let’s say you want a series of alerts. You can loop through an array of colors like this:

$alerts: red, blue, green, yellow;

@each $alert in $alerts {
        .alert-#{$alert} {
                background: $alert;
                color: #FFFFFF;
                padding: 10px;
                text-align: center;
        }
}

This says, for each entry in the $alerts list, create a class with the entry’s name and set the entry as the background color.

You can take this one step further with maps – key → value pairs in lists. If you wanted more descriptive names, you could do this:

$alerts: ("error" : red,
    "neutral" : blue,
    "good" : green,
    "warning" : yellow
);

@each $name, $color in $alerts {
        .alert-#{$name} {
                background: $color;
                color: #FFFFFF;
                padding: 10px;
                text-align: center;
        }
}

This is an effective away to quickly work through large sets of repetitive CSS. You can imagine a custom icon font you want to use, where you have a map of the icon name, and the unicode value for the glyph.

Go forth and program CSS!

With that, you’re ready to start coding your own SCSS. You now have the syntax you need to do math, if statements, and loops for your styles. What are you going to use this new-found power for? Let us know in the comments!

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Is your frontend hogging your users' CPU?

    As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

    LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

    Modernize how you debug web apps — .

    Joe Casabona Podcast Consultant, Educator. Dad. Husband. Likes Yankees, Cigars, Disney. Makes courses for @lynda . Writes tech books. Host of @howibuilt .

    One Reply to “A beginner’s guide to programming for CSS with Sass”

    1. Hey Joe,

      First off, thanks for all of the tips here on how to make our CSS more powerful and modular.

      I just felt like it is worth noting that in the example of the for loop that the line at the end “$heading-size: $heading-size / 1.25;” will actually make it so that $heading-size remains at the final value before the loop is done. I think this is important because if you have another style right after it something like:

      h1.double-size { font-size: $heading-size * 2; }

      Then it would not be double the size you are expecting most likely. Do you know if there is a way to have the value reset to it’s original after the loop is finished without making the code too clunky?

      Again, this is a great piece and thank you for sharing it!

    Leave a Reply