阿里云主机折上折
  • 微信号
Current Site:Index > The classification method of SMACSS

The classification method of SMACSS

Author:Chuan Chen 阅读数:56448人阅读 分类: CSS

SMACSS Classification Method

SMACSS (Scalable and Modular Architecture for CSS) is a CSS architecture methodology proposed by Jonathan Snook. It categorizes CSS rules into five types: Base, Layout, Module, State, and Theme. This classification method helps improve code maintainability and scalability.

Base

Base styles are default styles typically applied to HTML elements themselves. These styles include resetting browser defaults, setting global fonts, colors, etc. Base styles should not contain any class or ID selectors.

/* Base style example */
body {
  font-family: Arial, sans-serif;
  line-height: 1.6;
  color: #333;
}

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

a:hover {
  text-decoration: underline;
}

ul, ol {
  padding-left: 2em;
}

Base styles should be as simple as possible since they affect the entire website. Avoid using overly specific property values in base styles to make them easier to override when needed.

Layout

Layout styles define the major structural areas of a page, such as headers, footers, sidebars, and content areas. These styles typically use ID selectors or class names with an l- prefix.

/* Layout style example */
#header, 
#footer {
  width: 100%;
  padding: 1em;
}

.l-container {
  max-width: 1200px;
  margin: 0 auto;
}

.l-sidebar {
  float: left;
  width: 25%;
}

.l-main {
  float: right;
  width: 70%;
}

.l-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1em;
}

Layout styles should focus on the macro structure of the page, not micro details. Using prefixes (e.g., l-) helps clearly distinguish layout classes from other classes.

Module

Modules are reusable components, such as navigation bars, cards, buttons, etc. They are the most common part of SMACSS and should exist independently of layouts.

/* Module style example */
.btn {
  display: inline-block;
  padding: 0.5em 1em;
  border-radius: 4px;
  background-color: #0066cc;
  color: white;
}

.btn--secondary {
  background-color: #e6e6e6;
  color: #333;
}

.card {
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 1em;
  margin-bottom: 1em;
}

.card__title {
  font-size: 1.2em;
  margin-bottom: 0.5em;
}

.card__body {
  color: #666;
}

Modules should use the BEM (Block Element Modifier) naming convention or similar conventions. This helps maintain style independence and predictability.

State

State styles describe the appearance of modules or layouts in specific states, such as active, hidden, error, etc. These styles typically use is- or has- prefixes.

/* State style example */
.is-active {
  background-color: #ffcc00;
}

.is-hidden {
  display: none;
}

.has-error {
  border-color: #ff0000;
}

.is-loading {
  opacity: 0.5;
  pointer-events: none;
}

State styles are often dynamically added or removed via JavaScript. They should override other styles, so they may require higher specificity or !important declarations.

Theme

Theme styles define the look and feel of a website, such as colors, fonts, etc. They are usually variants of base styles used to create different visual themes.

/* Theme style example */
.theme-dark {
  background-color: #333;
  color: #fff;
}

.theme-dark a {
  color: #66ccff;
}

.theme-light {
  background-color: #fff;
  color: #333;
}

.theme-light a {
  color: #0066cc;
}

Theme styles can be applied by adding classes to <body> or higher-level elements. They should override other styles, so they may need to be placed at the end of the stylesheet.

Practical Application Example

Here is an actual HTML and CSS example combining SMACSS classifications:

<!DOCTYPE html>
<html>
<head>
  <style>
    /* Base styles */
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
    }
    
    /* Layout styles */
    .l-header {
      background-color: #f5f5f5;
      padding: 1em;
    }
    
    .l-container {
      max-width: 1200px;
      margin: 0 auto;
      display: flex;
    }
    
    .l-main {
      flex: 3;
      padding: 1em;
    }
    
    .l-sidebar {
      flex: 1;
      padding: 1em;
      background-color: #eee;
    }
    
    /* Module styles */
    .nav {
      list-style: none;
      padding: 0;
    }
    
    .nav__item {
      display: inline-block;
      margin-right: 1em;
    }
    
    .nav__link {
      text-decoration: none;
      color: #333;
    }
    
    .nav__link.is-active {
      font-weight: bold;
      color: #0066cc;
    }
    
    .card {
      border: 1px solid #ddd;
      border-radius: 4px;
      padding: 1em;
      margin-bottom: 1em;
    }
    
    /* State styles */
    .is-hidden {
      display: none;
    }
    
    /* Theme styles */
    .theme-dark {
      background-color: #333;
      color: #fff;
    }
    
    .theme-dark .l-header {
      background-color: #222;
    }
    
    .theme-dark .l-sidebar {
      background-color: #444;
    }
    
    .theme-dark .card {
      border-color: #555;
    }
  </style>
</head>
<body class="theme-dark">
  <header class="l-header">
    <nav>
      <ul class="nav">
        <li class="nav__item"><a href="#" class="nav__link is-active">Home</a></li>
        <li class="nav__item"><a href="#" class="nav__link">About</a></li>
        <li class="nav__item"><a href="#" class="nav__link">Contact</a></li>
      </ul>
    </nav>
  </header>
  
  <div class="l-container">
    <main class="l-main">
      <article class="card">
        <h2>Article Title</h2>
        <p>Article content...</p>
      </article>
    </main>
    
    <aside class="l-sidebar">
      <div class="card">
        <h3>Sidebar</h3>
        <p>Sidebar content...</p>
      </div>
    </aside>
  </div>
</body>
</html>

Naming Conventions and Best Practices

SMACSS recommends specific naming conventions to distinguish between different style categories:

  1. Layout classes use the l- prefix (e.g., l-header)
  2. State classes use the is- or has- prefix (e.g., is-active)
  3. Module classes use meaningful names (e.g., btn, card)
  4. Theme classes use the theme- prefix (e.g., theme-dark)

Other best practices include:

  • Avoid using ID selectors for styling (except for layouts)
  • Keep selector specificity low
  • Use child selectors (>) to limit style scope
  • Avoid overly nested selectors (especially in preprocessors)

Integration with Preprocessors

SMACSS works well with CSS preprocessors like Sass and Less. Here is a Sass example:

// Base styles
body {
  font-family: $base-font;
  line-height: 1.6;
}

// Layout styles
.l-container {
  max-width: $max-width;
  margin: 0 auto;
}

// Module styles
.btn {
  display: inline-block;
  padding: 0.5em 1em;
  
  &--primary {
    background-color: $primary-color;
  }
  
  &--large {
    padding: 1em 2em;
  }
}

// State styles
.is-active {
  font-weight: bold;
}

// Theme styles
.theme-dark {
  background-color: $dark-bg;
  color: $dark-text;
}

Preprocessors can help better organize SMACSS components while keeping the generated CSS clean.

Common Issues and Solutions

  1. Specificity conflicts: If state styles cannot override module styles, consider:

    • Using more specific naming conventions
    • Placing state styles later in the stylesheet
    • Using !important when necessary (use sparingly)
  2. Over-classification: Not every CSS rule must strictly fit into these five categories. For small projects, simplification is acceptable.

  3. Namespace conflicts: When using other frameworks or libraries, consider:

    • Using project-specific prefixes (e.g., myapp-l-header)
    • Creating more specific naming conventions
  4. Maintaining large codebases: As projects grow, you can:

    • Split different style categories into separate files
    • Establish strict code review processes
    • Use CSS-in-JS solutions (e.g., styled-components) to achieve similar modularity

Performance Considerations

While SMACSS primarily focuses on code organization and maintainability, performance should also be considered:

  1. Selector performance: Avoid overly complex selectors, such as deeply nested descendant selectors.
  2. File size: Split CSS into multiple files (by category or module) but merge and compress them for production.
  3. Rendering performance: Be mindful of the impact of certain CSS properties (e.g., box-shadow, border-radius) on rendering performance.
/* Poor performance example */
div.container > ul.nav > li.item > a.link {
  color: blue;
}

/* Better example */
.nav-link {
  color: blue;
}

Relationship with Other Methodologies

SMACSS can be combined with other CSS methodologies:

  1. BEM: The module portion of SMACSS works well with BEM naming conventions.
  2. OOCSS: SMACSS incorporates many OOCSS concepts, such as separating structure and skin.
  3. ITCSS: ITCSS's layering approach can complement SMACSS's classification method.

For example, you can use BEM for modules while maintaining other SMACSS categories:

/* SMACSS + BEM example */
/* Layout */
.l-grid {
  display: grid;
}

/* Module */
.card {
  /* Block styles */
}

.card__title {
  /* Element styles */
}

.card--featured {
  /* Modifier styles */
}

/* State */
.is-expanded {
  /* State styles */
}

Tools and Resources

  1. CSS analysis tools: Such as css-analyzer, which can help evaluate the organization of CSS codebases.
  2. Naming convention checkers: Custom ESLint rules can be created to enforce SMACSS naming conventions.
  3. Documentation generators: Tools like StyleDocco can generate documentation for SMACSS-organized CSS.
# Example using css-analyzer
npx css-analyzer styles.css --format smacss

Extensions and Variants

Some developers have extended SMACSS:

  1. SMACSS+BEM: Combines BEM's strict naming conventions.
  2. SMACSS+ITCSS: Adds ITCSS layering to SMACSS classifications.
  3. Atomic SMACSS: Incorporates atomic CSS concepts into SMACSS.

For example, Atomic SMACSS might include:

/* Atomic classes */
.text-center {
  text-align: center;
}

.mt-1 {
  margin-top: 1em;
}

/* Combined with regular SMACSS */
.l-header {
  @extend .mt-1;
  @extend .text-center;
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:OOCSS的设计原则

下一篇:ITCSS的分层架构

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.