VOOZH about

URL: https://blog.logrocket.com/how-to-write-reusable-css-with-sass/

⇱ How to write reusable CSS with SASS - LogRocket Blog


2019-09-25
1912
#css
Obinna Ekwuno
6653
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Sass is a CSS preprocessor that is becoming vital in the front-end engineers’ toolbox. Sass gained popularity because of a couple of CSS pitfalls that it fixes.

👁 Image

It is also what Bootstrap 4 runs on. Meaning it would be really helpful to learn Sass in order to understand how to manipulate bootstrap code, rather than overriding the code (which is the custom method by most developers). Understanding Sass gives a better understanding of tools that are on a source code level.

When working with CSS, we are often working in a world of globals and can mistakenly style an element.

Custom CSS (even with CSS variables) is still very redundant. CSS was not designed for the kind of complex architecture we have today and we run into the problem of importing a style sheet inside another style sheet which may lead to a very large style base that may not be understood without proper documentation.

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

TL; DR

In this article, we will be focusing on why preprocessors are important with a particular emphasis on SASS and its ability to compose rules together. Using Sass gives a more logical approach to styling modern web components.

We will also look at why we use these preprocessors with demo examples showing how we break styling up into smaller specific components without forcing our users to download a lot of unneeded CSS files.

Prerequisites

Before we go any further, this article assumes the following:

  • Node.js ≥v6 is installed on your machine
  • npm is installed on your machine
  • Sass is installed on your machine
  • Create-react-app is installed on your machine
  • You have a basic understanding of CSS

Getting started

Sass can be added to your project in a number of ways, you can find all of the installment options here. For the sake of this article, we will be using npm by running:

npm install -g sass

What is wrong with CSS?

When learning the fundamentals of web development, we are introduced to conventional CSS which involves working with and manipulating HTML using identifiers like Classes or IDs.

While working with CSS, we oftentimes have to beat the styling to get it to look the way we want it to. It is really stressful to organize large style sheets. And keeping the classes scoped to avoid styling things in an unintended way is almost tiring.

Even with the introduction of a CSS variable to reduce the repetition with declarations, there are a few issues with this concept that are solved with using a preprocessor. Such as having long variable names.

Even with the advent of CSS3, we still need to rely on techniques (that are basically hacks) to styling user interfaces. We can also notice that while writing HTML, there is a clear nested and visual hierarchy, which regular CSS doesn’t allow for.

Let’s look at the “solution” to the features missing in CSS.

What are CSS preprocessors?

These can basically be thought of as a program that lets you generate CSS from the preprocessor’s own unique syntax. CSS preprocessors generally add some features that don’t exist in pure CSS, such as mixin, nesting selector, inheritance selector. While also giving us a very structured way of writing style sheets. Examples of CSS preprocessors include LESS, stylus, Sass, PostCSS. As stated earlier, this article is focused on Sass as a preprocessor.

👁 csspreprocessors

SASS or SCSS?

Now if you’re new to this concept of Sass you may wonder, ‘if Sass is the preprocessor, what is SCSS’? Well , because there is a bit of confusion in using Sass because of the lack of the semicolon ; and curly brackets {} , in place of that, it uses tabs and spaces.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

In version 3 of Sass, the SCSS syntax was introduced as the main syntax for Sass, it contains all the features of CSS but allows for the use of the features of Sass. Either syntax works when styling and neither one is better than the other in my opinion. The need for SCSS was to make the learning curve and implementation of Sass faster and without errors.

Sass:

$font-stack: Helvetica, sans-serif
$primary-color: #333

body
 font: 100% $font-stack
 color: $primary-color

SCSS:

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
 font: 100% $font-stack;
 color: $primary-color;
}

In the above code example, we notice the difference in Sass and SCSS writing styles. Note that they both use $ to declare a variable.

Concepts in SCSS

Nesting and scoping

When styling HTML files, SCSS enables you to have the same visual hierarchy of your HTML in your style sheet so you can actually map out your styling in a more understandable manner. For example, styling this index.html:

<nav class = 'sidebar'>
 <ul>
 <li> <a> </a></li>
 </ul>
</nav>

CSS:

nav ul {
 margin: 0;
 padding: 0;
 list-style: none;
}
nav li {
 display: inline-block;
}
nav a {
 display: block;
 padding: 6px 12px;
 text-decoration: none;
}

SCSS:

nav {
 ul {
 margin: 0;
 padding: 0;
 list-style: none;
 }

 li { display: inline-block; }

 a {
 display: block;
 padding: 6px 12px;
 text-decoration: none;
 }
}

We can see from the CSS code example above that we are able to deduce the structure of the HTML file while keeping the implementation short and simple. Another advantage of this is that it helps to avoid spelling errors plus you can see that we have scoped some rules so that they only apply within the nav.

Descendant style rules apply in SCSS for example:

.container{
.left-area{
 ...
}
}

What this means is that all the descendants of the container class which have the class = "left-area" would be affected by the rules. Basic CSS selectors still apply to SCSS such as:

Direct descendant (>)

.container{
 > .left-area{
 ...
 }
}

Now only classes that are immediate children of the container div will get the style.

Parent selector ( & )

If we wanted to modify a class by adding a class to it, we could make use of the parent selector, it is mostly used in situations where adding a secondary style changes the style of the element. Which would also play the role of modifiers.

.container{
 & .right-area{
 background-color : #0000
 }
}

We can also use the parent selector to scope roles to another class like this:

button{
 color:#349;
 .theme-dark &{
 color: #fff
}
}

From the code example, the color #fff only applies to the .theme-dark class because of the parent selector.

Variables

Usually, in CSS, we have various style sheets linked by using @import to bring in another style sheet into the main CSS. What does this mean for the user? This would mean having to download extra CSS files.

What if there was a way to resolve all these inputs into a single CSS file using SCSS. The concept of variables in CSS comes from a JavaScript approach.


More great articles from LogRocket:


Note that @import in SCSS are used to get partials into other SCSS files but they do not become CSS files. They are denoted by having _ before the name.

Using SCSS variables

Global variables: As the name suggests, these are variables that can be accessed within a block of CSS. If you are familiar with scoping in JavaScript, you would understand global variables.

Variables in SCSS always begin with a dollar sign $.

$color: #f002
.color{
 $text_color: #ddd;
 background-color: $color;
 color: $text_color;
 text-shadow:0 0 2px darken($text_color, 40%);
}

From the code above, we notice that the $text_color can only be accessed within the block of code.

Mixins

Another awesome feature of SCSS is its ability to package reusable styling together and allow for import into another style block on demand to reduce redundancy in code.

Declaration

Creating a mixin is as simple as adding a @mixin followed by the mixin name before the block of styles, like this:

@mixin {insert name} {
 //write CSS code here
}

Usage

To use Mixins within code blocks we have to use the @include followed by the name of the mixin then a semicolon. This helps to use a predefined mixin within a code block:

.nav {
 @include {mixin name}
}

Another way of using mixins is by using arguments, like a function in JavaScript we can declare a global variable and set it as a parameter for a mixin:

@mixin text-color($color){
 background-color: $color;
 color: white;
}

//import 
.name{
 @include text-color(orange);
}
.background{
 @include text-color(white)
}

Now imagine if we wanted a default value for a mixin and would change or reassign this value in different code blocks, we would use some arguments. To show this, I will refactor the previous code example:

@mixin text-color($color : #fff){
 background-color: $color;
 color: white;
}

//import 
.name{
 @include text-color(orange);
}
.background{
 @include text-color($color: white)
}

What this does is, it sets a default color for the mixin as a base, but it is modifiable by reassigning. We could also set the value to null in order to only use the argument we need in the mixin:

@mixin text-color($color : null){
 background-color: $color;
 color: #038;
}

//import 
.name{
 @include text-color();
}
.background{
 @include text-color(#fff)
}

What this does is it makes the values that are displayed as null to have no value in the @include importation, but displays the other value by default.

Passing a deceleration block:

@mixin text-color($color){
 color: $color;
 .extra{
 @content
 }
}

//import 
.name{
 @include text-color(#fff){
 color: blue;
 }
}

The code block basically allows us to be able to keep the styling simple by styling the parent class and also being able to define the inner class.

Noteworthy info

  • Mixins do not evaluate to a CSS file, they are designed to be consumed, so you would mostly see them as partials in SCSS
  • Mixins do not need to be preceded with a dot (.)

Functions

Functions in SCSS are a big part of the features of SASS, they allow you to define complex operations that are re-usable throughout your style sheet. There are a lot of inbuilt Sass functions that can help. Check out the documentation for more information.

Here is a list of some of the functions you should be familiar with

We can also write our own Sass functions:

$width: 4px;
@function double($x){
 @return 2 * $x;
}
.thin-border{
 border-width: $width
}
.thick-border{
 broder-width:double($width)
}

The function above just doubles the value when the function is called with the normal width as a parameter.

Conditional styling with control flow

This feature is brilliant as it allows us to alternate a specific style, based on the value of another style using the @if and @else declarations. For instance, dynamically increasing a line-height for different values of font-size.

@mixin modify($size){
 font-size: $size;
 @if $size > 18{
 line-height: $size;
 }
}

//import 
.name{
 @include modify(24px)
 }

Some other features to note

  • Comments – Multiple line comments in SCSS are displayed the same way in CSS but inline comments are removed. They can be used for string interpolation (knowing what values are actually displayed in CSS)
  • Sass also comes with @for for iteration and control flow this can be used with mixins and functions

Conclusion

In this article, we have attempted to understand the basics of writing functional CSS with SCSS and also looked at some Sass/SCSS principles in general. I hope we put these practices into play towards writing more stress-free and optimized styling for our applications. Happy coding! 😄

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.

👁 LogRocket Dashboard Free Trial Banner

LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.

LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.

Modernize how you debug web and mobile apps — start monitoring for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

👁 Image
Emmanuel John
Jun 17, 2026 ⋅ 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now