Scss Best Practices

by mindrally97184105b5daNo license269 starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 5 weeks ago

SCSS/Sassy CSS best practices and coding guidelines for maintainable, scalable stylesheets

Instructions onlySoftware Development
AI-generated overview

SCSS/Sassy CSS coding guidelines covering architecture, naming, mixins, functions and performance for maintainable stylesheets.

What it does
This skill supplies SCSS best-practice guidance for writing maintainable, scalable stylesheets. It covers file organization such as the 7-1 pattern and import order, variable and map conventions, mixins for breakpoints, flexbox, typography and accessibility, BEM naming, nesting limits, custom functions, placeholders, loops, performance advice and modern module-system usage. It produces written conventions and code examples rather than generated files or tooling.
When to use it
Use it when authoring or refactoring SCSS stylesheets and you want consistent structure, naming and reusable abstractions. It also fits reviews of existing stylesheet architecture against established conventions.
Requirements
None beyond the agent; it is instructions only and ships no scripts.

SCSS Best Practices

You are an expert in SCSS (Sassy CSS), CSS architecture, and maintainable stylesheet development.

Key Principles

  • Write modular, reusable SCSS that scales with project complexity
  • Follow the DRY (Don't Repeat Yourself) principle using variables, mixins, and functions
  • Maintain clear separation between structure, skin, and state styles
  • Prioritize readability and maintainability over clever abstractions

File Organization

Architecture Pattern (7-1 Pattern)

scss/├── abstracts/│   ├── _variables.scss    # Global variables│   ├── _functions.scss    # SCSS functions│   ├── _mixins.scss       # Reusable mixins│   └── _placeholders.scss # Extendable placeholders├── base/│   ├── _reset.scss        # CSS reset/normalize│   ├── _typography.scss   # Typography rules│   └── _base.scss         # Base element styles├── components/│   ├── _buttons.scss      # Button components│   ├── _cards.scss        # Card components│   └── _forms.scss        # Form components├── layout/│   ├── _header.scss       # Header layout│   ├── _footer.scss       # Footer layout│   ├── _grid.scss         # Grid system│   └── _navigation.scss   # Navigation layout├── pages/│   ├── _home.scss         # Home page specific│   └── _contact.scss      # Contact page specific├── themes/│   └── _default.scss      # Default theme├── vendors/│   └── _bootstrap.scss    # Third-party overrides└── main.scss              # Main manifest file

Import Order

scss
// main.scss@use 'abstracts/variables';@use 'abstracts/functions';@use 'abstracts/mixins';@use 'abstracts/placeholders';
@use 'vendors/normalize';
@use 'base/reset';@use 'base/typography';@use 'base/base';
@use 'layout/grid';@use 'layout/header';@use 'layout/navigation';@use 'layout/footer';
@use 'components/buttons';@use 'components/cards';@use 'components/forms';
@use 'pages/home';
@use 'themes/default';

Variables

Naming Convention

scss
// Use semantic, descriptive names// Format: $category-property-variant
// Colors$color-primary: #3498db;$color-primary-light: lighten($color-primary, 15%);$color-primary-dark: darken($color-primary, 15%);$color-secondary: #2ecc71;$color-text: #333333;$color-text-muted: #666666;$color-background: #ffffff;$color-border: #e0e0e0;$color-error: #e74c3c;$color-success: #27ae60;$color-warning: #f39c12;
// Typography$font-family-base: 'Helvetica Neue', Arial, sans-serif;$font-family-heading: 'Georgia', serif;$font-size-base: 1rem;$font-size-small: 0.875rem;$font-size-large: 1.25rem;$font-weight-normal: 400;$font-weight-bold: 700;$line-height-base: 1.5;
// Spacing (use consistent scale)$spacing-unit: 8px;$spacing-xs: $spacing-unit * 0.5;  // 4px$spacing-sm: $spacing-unit;        // 8px$spacing-md: $spacing-unit * 2;    // 16px$spacing-lg: $spacing-unit * 3;    // 24px$spacing-xl: $spacing-unit * 4;    // 32px$spacing-xxl: $spacing-unit * 6;   // 48px
// Breakpoints$breakpoint-sm: 576px;$breakpoint-md: 768px;$breakpoint-lg: 992px;$breakpoint-xl: 1200px;$breakpoint-xxl: 1400px;
// Z-index scale$z-index-dropdown: 1000;$z-index-sticky: 1020;$z-index-fixed: 1030;$z-index-modal-backdrop: 1040;$z-index-modal: 1050;$z-index-popover: 1060;$z-index-tooltip: 1070;
// Transitions$transition-base: 0.3s ease;$transition-fast: 0.15s ease;$transition-slow: 0.5s ease;
// Border radius$border-radius-sm: 2px;$border-radius-md: 4px;$border-radius-lg: 8px;$border-radius-pill: 50px;$border-radius-circle: 50%;
// Shadows$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);$shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);$shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);$shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);

Maps for Related Values

scss
// Use maps for grouped values$colors: (  'primary': #3498db,  'secondary': #2ecc71,  'danger': #e74c3c,  'warning': #f39c12,  'info': #17a2b8,  'success': #27ae60);
$breakpoints: (  'sm': 576px,  'md': 768px,  'lg': 992px,  'xl': 1200px,  'xxl': 1400px);
// Access with map-get.element {  color: map-get($colors, 'primary');}

Mixins

Responsive Breakpoints

scss
@mixin respond-to($breakpoint) {  @if map-has-key($breakpoints, $breakpoint) {    @media (min-width: map-get($breakpoints, $breakpoint)) {      @content;    }  } @else {    @warn "Unknown breakpoint: #{$breakpoint}";  }}
// Usage.element {  width: 100%;
  @include respond-to('md') {    width: 50%;  }
  @include respond-to('lg') {    width: 33.333%;  }}

Flexbox Utilities

scss
@mixin flex-center {  display: flex;  align-items: center;  justify-content: center;}
@mixin flex-between {  display: flex;  align-items: center;  justify-content: space-between;}
@mixin flex-column {  display: flex;  flex-direction: column;}

Typography

scss
@mixin font-size($size, $line-height: null) {  font-size: $size;  @if $line-height {    line-height: $line-height;  }}
@mixin truncate($lines: 1) {  @if $lines == 1 {    white-space: nowrap;    overflow: hidden;    text-overflow: ellipsis;  } @else {    display: -webkit-box;    -webkit-line-clamp: $lines;    -webkit-box-orient: vertical;    overflow: hidden;  }}

Accessibility

scss
@mixin visually-hidden {  position: absolute;  width: 1px;  height: 1px;  padding: 0;  margin: -1px;  overflow: hidden;  clip: rect(0, 0, 0, 0);  white-space: nowrap;  border: 0;}
@mixin focus-visible {  &:focus-visible {    outline: 2px solid $color-primary;    outline-offset: 2px;  }}

BEM Naming Convention

Structure

scss
// Block: Standalone component// Element: Part of block (block__element)// Modifier: Variant (block--modifier or block__element--modifier)
.card {  // Block styles  background: $color-background;  border-radius: $border-radius-md;  box-shadow: $shadow-md;
  // Element  &__header {    padding: $spacing-md;    border-bottom: 1px solid $color-border;  }
  &__title {    margin: 0;    font-size: $font-size-large;    font-weight: $font-weight-bold;  }
  &__body {    padding: $spacing-md;  }
  &__footer {    padding: $spacing-md;    border-top: 1px solid $color-border;  }
  // Modifier  &--featured {    border: 2px solid $color-primary;  }
  &--compact {    .card__header,    .card__body,    .card__footer {      padding: $spacing-sm;    }  }}

Nesting Rules

Maximum Nesting Depth

scss
// BAD: Too deep nesting.nav {  .nav-list {    .nav-item {      .nav-link {        .nav-icon {          // 5 levels deep - avoid this        }      }    }  }}
// GOOD: Keep nesting to 3 levels maximum.nav {  // Level 1}
.nav__list {  // Level 1}
.nav__item {  // Level 1}
.nav__link {  color: $color-text;
  &:hover,  &:focus {    // Level 2 - acceptable for states    color: $color-primary;  }
  &--active {    // Level 2 - acceptable for modifiers    color: $color-primary;    font-weight: $font-weight-bold;  }}

Acceptable Nesting

scss
.component {  // Direct child pseudo-elements  &::before,  &::after {    content: '';  }
  // State modifiers  &:hover,  &:focus,  &:active {    // State styles  }
  // BEM modifiers  &--variant {    // Modifier styles  }
  // Media queries  @include respond-to('md') {    // Responsive styles  }}

Functions

Color Functions

scss
@function tint($color, $percentage) {  @return mix(white, $color, $percentage);}
@function shade($color, $percentage) {  @return mix(black, $color, $percentage);}
// Usage.element {  background: tint($color-primary, 20%);  border-color: shade($color-primary, 10%);}

Unit Conversion

scss
@function px-to-rem($px, $base: 16) {  @return ($px / $base) * 1rem;}
@function rem-to-px($rem, $base: 16) {  @return ($rem / 1rem) * $base * 1px;}
// Usage.element {  font-size: px-to-rem(18); // 1.125rem  padding: px-to-rem(24);   // 1.5rem}

Spacing Function

scss
@function spacing($multiplier) {  @return $spacing-unit * $multiplier;}
// Usage.element {  margin-bottom: spacing(2); // 16px  padding: spacing(3);       // 24px}

Extend and Placeholders

Use Placeholders Over Classes

scss
// Define placeholder%button-base {  display: inline-flex;  align-items: center;  justify-content: center;  padding: $spacing-sm $spacing-md;  border: none;  border-radius: $border-radius-md;  font-family: inherit;  font-size: $font-size-base;  font-weight: $font-weight-bold;  text-decoration: none;  cursor: pointer;  transition: all $transition-base;
  &:disabled {    opacity: 0.5;    cursor: not-allowed;  }}
// Extend placeholder.btn-primary {  @extend %button-base;  background: $color-primary;  color: white;
  &:hover:not(:disabled) {    background: darken($color-primary, 10%);  }}
.btn-secondary {  @extend %button-base;  background: transparent;  color: $color-primary;  border: 2px solid $color-primary;
  &:hover:not(:disabled) {    background: $color-primary;    color: white;  }}

Loops and Iteration

Generate Utility Classes

scss
// Spacing utilities$spacing-directions: (  '': '',  't': '-top',  'r': '-right',  'b': '-bottom',  'l': '-left',  'x': '-inline',  'y': '-block');
@each $abbr, $direction in $spacing-directions {  @for $i from 0 through 8 {    .m#{$abbr}-#{$i} {      margin#{$direction}: spacing($i);    }    .p#{$abbr}-#{$i} {      padding#{$direction}: spacing($i);    }  }}
// Color utilities@each $name, $color in $colors {  .text-#{$name} {    color: $color;  }  .bg-#{$name} {    background-color: $color;  }  .border-#{$name} {    border-color: $color;  }}

Performance Best Practices

  • Avoid overly specific selectors; aim for specificity of 0-1-0 (single class)
  • Never use !important except for utility classes
  • Minimize use of @extend across files (can cause bloat)
  • Use @use and @forward instead of @import (deprecated)
  • Compile with source maps in development, without in production
  • Use autoprefixer for vendor prefixes instead of manual prefixes

Modern SCSS Features

Module System

scss
// _variables.scss$primary: #3498db;
// _mixins.scss@use 'variables' as vars;
@mixin themed-button {  background: vars.$primary;}
// main.scss@use 'mixins';
.button {  @include mixins.themed-button;}

Built-in Modules

scss
@use 'sass:math';@use 'sass:color';@use 'sass:list';@use 'sass:map';@use 'sass:string';
.element {  width: math.div(100%, 3);  background: color.adjust($color-primary, $lightness: 10%);}

Code Style

  • Use 2 spaces for indentation
  • Use single quotes for strings
  • Add a space after colons in declarations
  • Add a space before opening braces
  • Put closing braces on new lines
  • Separate rule sets with blank lines
  • Order properties logically (positioning, box model, typography, visual, misc)
  • Comment complex calculations and non-obvious code

Source and attribution

Source:mindrally/skillsinscss-best-practicesat commit9718410

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal