# Writing Maintainable CSS with Sass

> How I bring structure to growing stylesheets using Sass variables, nested rules, and file partials.

- Published: 2016-12-04
- Category: Interface
- Tags: CSS, Sass
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/writing-maintainable-css-with-sass/
- Language: en-US
- Author: Muhammet Şafak

---
CSS is manageable when it lives in a single file. As the project grows, that file balloons — you're searching for color codes, and every time you touch one thing, something else breaks. At that point, thinking "there has to be a better way" becomes inevitable.

[Building UIs with Bootstrap 3](/en/blog/building-fast-consistent-uis-with-bootstrap-3/) carried me a fair way on ready-made classes; the moment I started writing my own CSS, this problem came back.

**Sass (Syntactically Awesome Style Sheets)** is a preprocessor that adds variables, nesting, mixins, and modularity on top of standard CSS. The `.scss` files you write are compiled into plain `.css` — the browser only ever sees CSS.

In this post I'll walk through the Sass features that have made the biggest difference in my projects.

## Installation

With Node.js installed, the `node-sass` package does the job:

```bash
npm install --save-dev node-sass
```

I add a build script to `package.json`:

```json
{
    "scripts": {
        "sass": "node-sass src/scss/main.scss public/css/main.css --watch"
    }
}
```

The `--watch` flag monitors files and recompiles automatically on every change.

## Variables

Keeping color, typography, and spacing values in variables means a single change propagates everywhere:

```scss
// _degiskenler.scss

$renk-birincil:   #3498db;
$renk-ikincil:    #2c3e50;
$renk-tehlike:    #e74c3c;
$renk-basari:     #27ae60;

$font-boyutu-kucuk:   12px;
$font-boyutu-normal:  16px;
$font-boyutu-buyuk:   20px;

$bosluk-kucuk:   8px;
$bosluk-orta:    16px;
$bosluk-buyuk:   32px;

$kenar-yari:     4px;
```

I import this file everywhere. When I need to change the primary color, I update `$renk-birincil` in one place and it reflects across the entire UI automatically.

On one project a client changed their brand color mid-development. Without Sass variables that would have taken hours; a single value update rippled through the whole interface. Since that experience I've made it a habit to define variables broadly from the start of every new project.

## Nested Rules

In plain CSS you have to repeatedly write related selectors like `.card`, `.card-title`, `.card-content`. With Sass I can nest them:

```scss
.kart {
    background: #fff;
    border: 1px solid #ddd;
    border-radius: $kenar-yari;
    padding: $bosluk-orta;

    .kart-baslik {
        font-size: $font-boyutu-buyuk;
        font-weight: bold;
        margin-bottom: $bosluk-kucuk;
        color: $renk-ikincil;
    }

    .kart-icerik {
        font-size: $font-boyutu-normal;
        color: #555;
    }

    &:hover {
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
}
```

The `&` symbol refers to the parent selector — it compiles to `.kart:hover`. The output CSS is identical to what you'd write by hand, but the source file is far more readable.

One thing I watch out for: don't go overboard with nesting. Four or five levels deep makes the generated CSS complex and leads to specificity problems. When I find myself going beyond three levels I usually step back and reconsider the component's structure — deep nesting is often a sign that you've lost sight of the underlying HTML.

## Grouping Repeated Rules with Mixins

A **mixin** lets you encapsulate a repeating block of CSS under a single definition. Here's one I reach for constantly with media queries:

```scss
@mixin mobil {
    @media (max-width: 768px) {
        @content;
    }
}

@mixin tablet {
    @media (min-width: 769px) and (max-width: 1024px) {
        @content;
    }
}

// Usage
.kutu {
    width: 300px;

    @include mobil {
        width: 100%;
    }

    @include tablet {
        width: 50%;
    }
}
```

This lets me keep each component's responsive behavior right next to its styles, instead of hunting through a separate media-query block at the bottom of the file.

## Splitting Files into Partials

Instead of one monolithic `main.scss` I move each concern into its own file. Files prefixed with an underscore (partials) are never compiled on their own — they're only included via `@import`:

```
scss/
├── _degiskenler.scss
├── _sifirla.scss
├── _tipografi.scss
├── _butonlar.scss
├── _formlar.scss
├── _kart.scss
├── _navigasyon.scss
└── main.scss
```

`main.scss` assembles them all:

```scss
@import 'degiskenler';
@import 'sifirla';
@import 'tipografi';
@import 'butonlar';
@import 'formlar';
@import 'kart';
@import 'navigasyon';
```

The build still outputs a single `main.css`, so there's no increase in HTTP requests. But the source files are organized and easy to find.

## Reducing Duplication with Extend

When two selectors need to share the same set of properties, `@extend` comes in handy:

```scss
%bildirim-temel {
    padding: $bosluk-kucuk $bosluk-orta;
    border-radius: $kenar-yari;
    font-size: $font-boyutu-kucuk;
}

.bildirim-bilgi {
    @extend %bildirim-temel;
    background: lighten($renk-birincil, 40%);
    color: $renk-birincil;
}

.bildirim-tehlike {
    @extend %bildirim-temel;
    background: lighten($renk-tehlike, 40%);
    color: $renk-tehlike;
}
```

A placeholder selector defined with `%` produces no CSS output on its own — it only takes effect when pulled in via `@extend`.

When deciding between `@extend` and a mixin I ask myself: will these shared styles always be used together? If yes, `@extend` makes sense. If I need parametric variation with different values, a mixin is the better fit. Because `@extend` merges selectors in the generated CSS, using it carelessly can produce unexpected selector combinations.

---

Once I started using Sass I never wanted to go back to plain CSS. Variables and a modular structure alone are a massive win. Using mixins and extend well takes a bit of practice, but once you internalize the principles, the CSS you write becomes dramatically easier to maintain.
