SASS/SCSS

SASS Architecture: ITCSS & SMACSS

20 min Lesson 25 of 30

SASS Architecture: ITCSS & SMACSS

While the 7-1 pattern is excellent for organizing SASS files, there are other architectural methodologies that approach CSS organization from different perspectives. In this comprehensive lesson, we'll explore ITCSS (Inverted Triangle CSS) and SMACSS (Scalable and Modular Architecture for CSS), two powerful approaches to managing CSS at scale.

Understanding ITCSS (Inverted Triangle CSS)

ITCSS, created by Harry Roberts, is a methodology that organizes CSS based on specificity and reach. It's visualized as an inverted triangle, where styles flow from generic to explicit, and from low specificity to high specificity.

The Core Principle

ITCSS is based on the idea that CSS should be organized in layers, with each layer having:

  • Reach: How far the styles affect the DOM (wide to narrow)
  • Specificity: How specific the selectors are (low to high)
  • Explicitness: How explicit the styling is (generic to explicit)
Note: The "inverted triangle" refers to the visualization: the widest, most generic styles at the top (Settings), narrowing down to the most specific styles at the bottom (Utilities).

The 7 Layers of ITCSS

ITCSS divides your CSS into seven distinct layers, each with a specific purpose:

ITCSS Layer Structure

scss/
├── 1-settings/           # Global variables, config
│   ├── _colors.scss
│   ├── _typography.scss
│   └── _spacing.scss
├── 2-tools/              # Mixins and functions
│   ├── _mixins.scss
│   └── _functions.scss
├── 3-generic/            # Resets and normalize
│   ├── _reset.scss
│   └── _box-sizing.scss
├── 4-elements/           # Bare HTML elements
│   ├── _headings.scss
│   ├── _links.scss
│   └── _forms.scss
├── 5-objects/            # Layout patterns (OOCSS)
│   ├── _container.scss
│   ├── _layout.scss
│   └── _media.scss
├── 6-components/         # UI components
│   ├── _buttons.scss
│   ├── _cards.scss
│   └── _navigation.scss
└── 7-utilities/          # Helper classes
    ├── _spacing.scss
    ├── _text.scss
    └── _display.scss

Layer 1: Settings

Global variables and configuration. No CSS output at this layer.

1-settings/_colors.scss

// Color palette - no CSS generated
$color-brand-primary: #0066cc;
$color-brand-secondary: #ff6600;
$color-ui-success: #28a745;
$color-ui-error: #dc3545;
$color-ui-warning: #ffc107;

// Grayscale
$color-gray-100: #f8f9fa;
$color-gray-200: #e9ecef;
$color-gray-300: #dee2e6;
$color-gray-800: #343a40;
$color-gray-900: #212529;

// Semantic color mapping
$color-text-primary: $color-gray-900;
$color-text-secondary: $color-gray-800;
$color-background: #ffffff;
$color-border: $color-gray-300;

1-settings/_spacing.scss

// Base spacing unit
$spacing-unit: 8px;

// Spacing scale
$spacing-scale: (
    "xs": $spacing-unit * 0.5,    // 4px
    "sm": $spacing-unit,           // 8px
    "md": $spacing-unit * 2,       // 16px
    "lg": $spacing-unit * 3,       // 24px
    "xl": $spacing-unit * 4,       // 32px
    "xxl": $spacing-unit * 6       // 48px
);

// Breakpoints
$breakpoints: (
    "sm": 576px,
    "md": 768px,
    "lg": 992px,
    "xl": 1200px
);

Layer 2: Tools

Mixins, functions, and other SASS tools. No CSS output.

2-tools/_mixins.scss

// Responsive mixin
@mixin respond-above($breakpoint) {
    @if map-has-key($breakpoints, $breakpoint) {
        $value: map-get($breakpoints, $breakpoint);
        @media (min-width: $value) {
            @content;
        }
    }
}

// Font size with line height
@mixin font-size($size, $line-height: null) {
    font-size: $size;
    @if $line-height {
        line-height: $line-height;
    }
}

// Truncate text with ellipsis
@mixin truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

Layer 3: Generic

Ground-zero styles like resets and normalize. First layer to generate actual CSS.

3-generic/_reset.scss

// Modern CSS reset
*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
    padding: 0;
}

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    min-height: 100vh;
    line-height: 1.5;
}

img,
picture,
svg {
    display: block;
    max-width: 100%;
}

Layer 4: Elements

Bare HTML element styles (no classes). Low specificity.

4-elements/_headings.scss

// Heading elements
h1, h2, h3, h4, h5, h6 {
    font-weight: 700;
    line-height: 1.2;
    color: $color-text-primary;
}

h1 { @include font-size(2.5rem); }
h2 { @include font-size(2rem); }
h3 { @include font-size(1.75rem); }
h4 { @include font-size(1.5rem); }
h5 { @include font-size(1.25rem); }
h6 { @include font-size(1rem); }

4-elements/_links.scss

// Anchor elements
a {
    color: $color-brand-primary;
    text-decoration: underline;
    transition: color 0.2s ease;

    &:hover {
        color: darken($color-brand-primary, 15%);
    }

    &:focus {
        outline: 2px solid $color-brand-primary;
        outline-offset: 2px;
    }
}

Layer 5: Objects

Class-based selectors that define layout patterns (OOCSS principles). Structural, cosmetically-free design patterns.

5-objects/_container.scss

// Container object - centers and constrains content
.o-container {
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
    padding-left: map-get($spacing-scale, "md");
    padding-right: map-get($spacing-scale, "md");

    &--fluid {
        max-width: none;
    }

    &--narrow {
        max-width: 800px;
    }
}

5-objects/_layout.scss

// Layout object - flexible layout system
.o-layout {
    display: flex;
    flex-wrap: wrap;
    margin: 0 calc(map-get($spacing-scale, "md") * -0.5);

    &__item {
        padding: 0 calc(map-get($spacing-scale, "md") * 0.5);
    }

    &--center {
        justify-content: center;
    }

    &--space-between {
        justify-content: space-between;
    }

    &--align-center {
        align-items: center;
    }
}

5-objects/_media.scss

// Media object - image next to text
.o-media {
    display: flex;
    align-items: flex-start;

    &__img {
        margin-right: map-get($spacing-scale, "md");
        flex-shrink: 0;
    }

    &__body {
        flex: 1;
    }

    &--reverse {
        flex-direction: row-reverse;

        .o-media__img {
            margin-right: 0;
            margin-left: map-get($spacing-scale, "md");
        }
    }
}

Layer 6: Components

Complete, designed UI components. This is where most of your styling lives.

6-components/_buttons.scss

// Button component
.c-button {
    display: inline-block;
    padding: map-get($spacing-scale, "sm") map-get($spacing-scale, "md");
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    border: 2px solid transparent;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s ease;

    &--primary {
        background-color: $color-brand-primary;
        color: white;

        &:hover {
            background-color: darken($color-brand-primary, 10%);
        }
    }

    &--secondary {
        background-color: $color-brand-secondary;
        color: white;

        &:hover {
            background-color: darken($color-brand-secondary, 10%);
        }
    }

    &--outline {
        background-color: transparent;
        border-color: $color-brand-primary;
        color: $color-brand-primary;

        &:hover {
            background-color: $color-brand-primary;
            color: white;
        }
    }

    &--large {
        padding: map-get($spacing-scale, "md") map-get($spacing-scale, "lg");
        @include font-size(1.125rem);
    }

    &--small {
        padding: map-get($spacing-scale, "xs") map-get($spacing-scale, "sm");
        @include font-size(0.875rem);
    }
}

Layer 7: Utilities

Helper classes with high specificity. These override everything else and should be immutable.

7-utilities/_spacing.scss

// Spacing utilities
@each $name, $value in $spacing-scale {
    // Margin utilities
    .u-m-#{$name} { margin: $value !important; }
    .u-mt-#{$name} { margin-top: $value !important; }
    .u-mr-#{$name} { margin-right: $value !important; }
    .u-mb-#{$name} { margin-bottom: $value !important; }
    .u-ml-#{$name} { margin-left: $value !important; }

    // Padding utilities
    .u-p-#{$name} { padding: $value !important; }
    .u-pt-#{$name} { padding-top: $value !important; }
    .u-pr-#{$name} { padding-right: $value !important; }
    .u-pb-#{$name} { padding-bottom: $value !important; }
    .u-pl-#{$name} { padding-left: $value !important; }
}

7-utilities/_text.scss

// Text utilities
.u-text-center { text-align: center !important; }
.u-text-left { text-align: left !important; }
.u-text-right { text-align: right !important; }

.u-text-truncate { @include truncate; }

.u-text-uppercase { text-transform: uppercase !important; }
.u-text-lowercase { text-transform: lowercase !important; }
.u-text-capitalize { text-transform: capitalize !important; }

// Color utilities
.u-text-primary { color: $color-brand-primary !important; }
.u-text-secondary { color: $color-text-secondary !important; }
.u-text-success { color: $color-ui-success !important; }
.u-text-error { color: $color-ui-error !important; }

Understanding SMACSS

SMACSS (Scalable and Modular Architecture for CSS), created by Jonathan Snook, is a methodology that categorizes CSS rules into five types. Unlike ITCSS, which focuses on specificity, SMACSS focuses on categorization and naming conventions.

The 5 Categories of SMACSS

SMACSS Structure

scss/
├── base/                 # Base rules
│   ├── _reset.scss
│   └── _typography.scss
├── layout/               # Layout rules
│   ├── _header.scss
│   ├── _sidebar.scss
│   └── _grid.scss
├── module/               # Module rules (components)
│   ├── _button.scss
│   ├── _card.scss
│   └── _navigation.scss
├── state/                # State rules
│   ├── _is-active.scss
│   ├── _is-hidden.scss
│   └── _is-collapsed.scss
└── theme/                # Theme rules
    ├── _light.scss
    └── _dark.scss

1. Base Rules

Base rules define default styling for HTML elements. No classes or IDs.

base/_typography.scss

// Base typography - element selectors only
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 16px;
    line-height: 1.6;
    color: #333;
}

h1, h2, h3, h4, h5, h6 {
    margin-bottom: 0.5em;
    font-weight: 600;
    line-height: 1.2;
}

p {
    margin-bottom: 1em;
}

a {
    color: #0066cc;
    text-decoration: none;
}

2. Layout Rules

Layout rules divide the page into sections. Prefixed with l- or layout-.

layout/_header.scss

// Layout rules - prefixed with l-
.l-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 2rem;
    background-color: #fff;
    border-bottom: 1px solid #e0e0e0;

    &__logo {
        font-size: 1.5rem;
        font-weight: bold;
    }

    &__nav {
        display: flex;
        gap: 2rem;
    }
}

.l-sidebar {
    width: 250px;
    padding: 1.5rem;
    background-color: #f5f5f5;

    @media (max-width: 768px) {
        width: 100%;
    }
}

.l-main {
    flex: 1;
    padding: 2rem;
}

3. Module Rules (Components)

Modules are reusable, modular components. They form the majority of your CSS.

module/_card.scss

// Module rules - standalone components
.card {
    background: white;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    overflow: hidden;

    &-header {
        padding: 1rem 1.5rem;
        background-color: #f8f9fa;
        border-bottom: 1px solid #e0e0e0;
    }

    &-title {
        margin: 0;
        font-size: 1.25rem;
    }

    &-body {
        padding: 1.5rem;
    }

    &-footer {
        padding: 1rem 1.5rem;
        background-color: #f8f9fa;
        border-top: 1px solid #e0e0e0;
    }

    // Module variants
    &--featured {
        border-color: #0066cc;
        border-width: 2px;
    }

    &--compact {
        .card-body {
            padding: 1rem;
        }
    }
}

4. State Rules

State rules describe how modules or layouts look in particular states. Prefixed with is- or has-.

state/_states.scss

// State rules - prefixed with is- or has-
.is-hidden {
    display: none !important;
}

.is-visible {
    display: block !important;
}

.is-active {
    background-color: #0066cc;
    color: white;
}

.is-disabled {
    opacity: 0.5;
    pointer-events: none;
    cursor: not-allowed;
}

.is-loading {
    position: relative;
    pointer-events: none;

    &::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 20px;
        height: 20px;
        margin: -10px 0 0 -10px;
        border: 2px solid #0066cc;
        border-top-color: transparent;
        border-radius: 50%;
        animation: spin 0.6s linear infinite;
    }
}

.has-error {
    border-color: #dc3545;
    background-color: #fff5f5;
}

.has-success {
    border-color: #28a745;
    background-color: #f0fff4;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

5. Theme Rules

Theme rules describe how modules or layouts might look with different themes.

theme/_dark.scss

// Theme rules
.theme-dark {
    background-color: #1a1a1a;
    color: #e0e0e0;

    .card {
        background-color: #2a2a2a;
        border-color: #3a3a3a;
        color: #e0e0e0;

        &-header,
        &-footer {
            background-color: #222;
            border-color: #3a3a3a;
        }
    }

    .l-header {
        background-color: #222;
        border-color: #3a3a3a;
    }

    a {
        color: #66b3ff;
    }
}

Comparing 7-1, ITCSS, and SMACSS

Note: These methodologies are not mutually exclusive. Many teams combine elements from multiple approaches to create their ideal architecture.

7-1 Pattern

  • Best For: Teams familiar with SASS, medium-to-large projects
  • Strength: Clear folder structure, easy to navigate
  • Learning Curve: Low - straightforward organization
  • Philosophy: File organization by purpose

ITCSS

  • Best For: Large projects with many developers, enterprise applications
  • Strength: Specificity management, prevents conflicts
  • Learning Curve: Medium - requires understanding specificity
  • Philosophy: Organization by specificity and reach

SMACSS

  • Best For: Projects needing clear categorization, CMS themes
  • Strength: Clear naming conventions, state management
  • Learning Curve: Low-Medium - simple categories
  • Philosophy: Categorization by rule type

Choosing the Right Architecture

Consider 7-1 When:

  • Your team is new to CSS architecture
  • You want a simple, intuitive folder structure
  • Project size is small to medium

Consider ITCSS When:

  • Specificity conflicts are a major concern
  • You have a very large, complex codebase
  • Multiple teams work on the same styles
  • You want strict organization rules

Consider SMACSS When:

  • You need clear state management
  • Building themes or white-label products
  • Working with CMS or dynamic content
  • You want flexible naming conventions

Combining Methodologies

Many successful projects combine elements from multiple methodologies:

Hybrid Approach Example

scss/
├── settings/          # From ITCSS
├── tools/             # From ITCSS
├── generic/           # From ITCSS
├── base/              # From SMACSS
├── layout/            # From SMACSS
├── objects/           # From ITCSS (OOCSS patterns)
├── components/        # From 7-1 (or modules from SMACSS)
├── state/             # From SMACSS
├── utilities/         # From ITCSS
└── themes/            # From 7-1 and SMACSS

Exercise 1: Implement ITCSS Structure

Create a complete ITCSS architecture for a blog platform:

  • Set up all 7 layers with appropriate files
  • Create settings for colors, typography, and spacing
  • Write objects for container, layout, and media patterns
  • Create components for article cards, author bio, and comment threads
  • Generate spacing and text utilities
  • Ensure proper specificity flow from generic to specific

Exercise 2: Apply SMACSS Methodology

Refactor an existing component library using SMACSS:

  • Categorize all styles into Base, Layout, Module, State, and Theme
  • Apply proper prefixes: l- for layout, is-/has- for states
  • Create state classes for: active, disabled, loading, error, success
  • Implement a light and dark theme
  • Document naming conventions for your team

Exercise 3: Compare and Choose

Analyze a real project and decide which architecture fits best:

  • List project requirements (size, team, complexity)
  • Evaluate pros/cons of 7-1, ITCSS, and SMACSS for this project
  • Create a hybrid approach combining best elements from each
  • Document your architectural decisions
  • Create folder structure and sample files

Summary

In this lesson, you've explored advanced SASS architectures. You now understand:

  • ITCSS's inverted triangle approach based on specificity
  • The 7 layers of ITCSS from Settings to Utilities
  • SMACSS's 5 categories: Base, Layout, Module, State, Theme
  • Naming conventions in SMACSS (l-, is-, has- prefixes)
  • How to compare 7-1, ITCSS, and SMACSS
  • When to use each methodology
  • How to combine methodologies for hybrid approaches
  • Best practices for choosing architecture based on project needs

The right architecture depends on your project, team, and goals. Understanding these methodologies gives you the tools to make informed decisions and build scalable, maintainable CSS for any project size.