Skip to content

CSS Methodologies: Building Maintainable Style Systems โ€‹

When your project expands from a few pages to dozens of pages, and CSS files grow from a few hundred lines to several thousand lines, you'll encounter a problem: styles become increasingly difficult to manage. Modifying a component's style might unexpectedly affect other places, team members have inconsistent naming styles, and new developers don't know where to add styles.

This is like a rapidly expanding city without urban planningโ€”roads become chaotic and buildings are arranged randomly. CSS methodologies serve as this "urban planning," helping us establish systematic rules and conventions that make code easier to understand, maintain, and extend.

Why Do We Need CSS Methodologies? โ€‹

Before diving into specific methodologies, let's understand why we need them.

Problems Without Methodologies โ€‹

css
/* Poor CSS Organization */
.title {
  font-size: 24px;
  color: #333;
}

.big-title {
  font-size: 32px;
}

.header .title {
  color: #fff;
}

.sidebar .title {
  font-size: 18px;
}

/* Which style will be applied? How is priority calculated? */

This casual CSS writing approach leads to several serious problems:

  1. Naming conflicts: .title has different styles in different places
  2. Uncontrollable priority: Which has higher priority, .header .title or .sidebar .title?
  3. Difficult to reuse: New styles must be written every time, making it hard to reuse existing code
  4. Hard to maintain: Modifying one place might affect multiple others

The Value of Methodologies โ€‹

CSS methodologies provide:

  • Unified naming conventions: Team members all follow the same naming rules
  • Clear organizational structure: Everyone knows where styles should be written
  • Better maintainability: Styles are easier to understand and modify
  • Reduced conflicts: Avoid style conflicts through specifications
  • Better reusability: Component-based thinking makes code easier to reuse

BEM Methodology โ€‹

BEM (Block Element Modifier) is one of the most popular CSS methodologies today, proposed by Russian search engine company Yandex. Its core idea is to divide the interface into independent blocks, where each block contains elements and uses modifiers to represent different states or variations.

BEM Naming Rules โ€‹

BEM uses very specific naming conventions:

.block {}                    /* Block */
.block__element {}           /* Element */
.block--modifier {}          /* Block modifier */
.block__element--modifier {} /* Element modifier */

Let's understand through a practical example:

html
<!-- A card component -->
<div class="card card--featured">
  <div class="card__header">
    <h2 class="card__title">Product Title</h2>
    <span class="card__badge card__badge--new">New</span>
  </div>
  <div class="card__body">
    <p class="card__description">Product description goes here...</p>
  </div>
  <div class="card__footer">
    <button class="card__button card__button--primary">Buy Now</button>
    <button class="card__button card__button--secondary">Details</button>
  </div>
</div>

Corresponding CSS:

css
/* Block: card */
.card {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background-color: white;
  overflow: hidden;
}

/* Block modifier: featured card */
.card--featured {
  border: 2px solid #3498db;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* Element: card header */
.card__header {
  padding: 20px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e0e0e0;
}

/* Element: card title */
.card__title {
  margin: 0;
  font-size: 20px;
  color: #333;
}

/* Element: badge */
.card__badge {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
}

/* Element modifier: new badge */
.card__badge--new {
  background-color: #2ecc71;
  color: white;
}

/* Element: card body */
.card__body {
  padding: 20px;
}

/* Element: description text */
.card__description {
  margin: 0;
  color: #666;
  line-height: 1.6;
}

/* Element: card footer */
.card__footer {
  padding: 20px;
  background-color: #f8f9fa;
  border-top: 1px solid #e0e0e0;
  display: flex;
  gap: 10px;
}

/* Element: button */
.card__button {
  flex: 1;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s;
}

/* Button modifier: primary button */
.card__button--primary {
  background-color: #3498db;
  color: white;
}

.card__button--primary:hover {
  background-color: #2980b9;
}

/* Button modifier: secondary button */
.card__button--secondary {
  background-color: #ecf0f1;
  color: #333;
}

.card__button--secondary:hover {
  background-color: #bdc3c7;
}

Core Principles of BEM โ€‹

1. Block Independence โ€‹

Blocks should be independent, reusable components that don't depend on other elements on the page:

css
/* โœ… Good practice: blocks are independent */
.button {
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
}

/* โŒ Avoid: blocks depend on parent elements */
.sidebar .button {
  padding: 10px 20px; /* Don't do this */
}

2. Elements Belong to Blocks โ€‹

Elements are part of blocks and cannot exist independently:

css
/* โœ… Good practice: elements always belong to a block */
.menu__item {
  padding: 10px;
}

.menu__link {
  color: #333;
  text-decoration: none;
}

/* โŒ Avoid: elements exist independently */
.item {
  /* Which block does this element belong to? Unclear */
}

3. Modifiers Represent States or Variations โ€‹

Modifiers are used to represent different states, themes, or sizes of blocks or elements:

css
/* โœ… Good practice: use modifiers to represent states */
.button--disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.button--large {
  padding: 15px 30px;
  font-size: 18px;
}

.button--primary {
  background-color: #3498db;
  color: white;
}

/* โŒ Avoid: using additional class names */
.button.disabled {
  /* Doesn't conform to BEM specifications */
}

Practical BEM Application Example โ€‹

Let's look at a complete navigation menu example:

html
<nav class="nav nav--horizontal">
  <div class="nav__logo">
    <img src="logo.png" alt="Logo" class="nav__logo-image" />
  </div>
  <ul class="nav__list">
    <li class="nav__item">
      <a href="#" class="nav__link nav__link--active">Home</a>
    </li>
    <li class="nav__item">
      <a href="#" class="nav__link">About</a>
    </li>
    <li class="nav__item nav__item--has-dropdown">
      <a href="#" class="nav__link">Services</a>
      <ul class="nav__dropdown">
        <li class="nav__dropdown-item">
          <a href="#" class="nav__dropdown-link">Service 1</a>
        </li>
        <li class="nav__dropdown-item">
          <a href="#" class="nav__dropdown-link">Service 2</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>
css
/* Block: navigation */
.nav {
  background-color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 0 20px;
}

/* Modifier: horizontal navigation */
.nav--horizontal {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Element: Logo container */
.nav__logo {
  padding: 10px 0;
}

/* Element: Logo image */
.nav__logo-image {
  height: 40px;
  width: auto;
}

/* Element: navigation list */
.nav__list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 5px;
}

/* Element: navigation item */
.nav__item {
  position: relative;
}

/* Element modifier: item with dropdown menu */
.nav__item--has-dropdown:hover .nav__dropdown {
  display: block;
}

/* Element: navigation link */
.nav__link {
  display: block;
  padding: 15px 20px;
  color: #333;
  text-decoration: none;
  transition: background-color 0.3s;
}

.nav__link:hover {
  background-color: #f8f9fa;
}

/* Link modifier: active state */
.nav__link--active {
  color: #3498db;
  border-bottom: 2px solid #3498db;
}

/* Element: dropdown menu */
.nav__dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background-color: white;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  padding: 10px 0;
  list-style: none;
}

/* Element: dropdown menu item */
.nav__dropdown-item {
  margin: 0;
}

/* Element: dropdown menu link */
.nav__dropdown-link {
  display: block;
  padding: 10px 20px;
  color: #333;
  text-decoration: none;
  transition: background-color 0.3s;
}

.nav__dropdown-link:hover {
  background-color: #f8f9fa;
}

Pros and Cons of BEM โ€‹

Advantages:

  • Clear and intuitive: The hierarchical relationship between elements can be seen from class names
  • Avoid conflicts: Each component's class names are unique
  • Easy to maintain: Modifying a component won't affect other parts
  • Tool support: Many tools and plugins support BEM

Disadvantages:

  • Longer class names: .card__button--primary is quite verbose
  • HTML redundancy: Need to write many class names
  • Learning curve: Teams need time to adapt to this naming approach

SMACSS Methodology โ€‹

SMACSS (Scalable and Modular Architecture for CSS) was proposed by Jonathan Snook. It divides CSS rules into five categories, each with specific purposes and naming rules.

SMACSS's Five Categories โ€‹

1. Base โ€‹

Base rules define the default styles of elements, usually using element selectors:

css
/* Base rules */
html {
  font-size: 16px;
  line-height: 1.6;
  color: #333;
}

body {
  margin: 0;
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  background-color: #f8f9fa;
}

a {
  color: #3498db;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-top: 0;
  line-height: 1.2;
}

p {
  margin: 0 0 1em 0;
}

img {
  max-width: 100%;
  height: auto;
}

2. Layout โ€‹

Layout rules define the main structure of the page, using l- or layout- prefixes:

css
/* Layout rules */
.l-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
}

.l-header {
  background-color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  position: sticky;
  top: 0;
  z-index: 100;
}

.l-main {
  min-height: calc(100vh - 200px);
  padding: 40px 0;
}

.l-sidebar {
  width: 300px;
  padding: 20px;
}

.l-content {
  flex: 1;
  padding: 20px;
}

.l-footer {
  background-color: #2c3e50;
  color: white;
  padding: 40px 0;
  margin-top: 60px;
}

/* Two-column layout */
.l-two-column {
  display: flex;
  gap: 40px;
}

3. Module โ€‹

Modules are reusable components, which is the core of SMACSS:

css
/* Module: Card */
.card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.card-header {
  padding: 20px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e0e0e0;
}

.card-title {
  margin: 0;
  font-size: 20px;
  color: #333;
}

.card-body {
  padding: 20px;
}

.card-footer {
  padding: 20px;
  background-color: #f8f9fa;
  border-top: 1px solid #e0e0e0;
}

/* Module: Button */
.button {
  display: inline-block;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s;
}

/* Module: Alert */
.alert {
  padding: 15px 20px;
  border-radius: 4px;
  margin-bottom: 20px;
}

.alert-title {
  font-weight: bold;
  margin-bottom: 5px;
}

.alert-message {
  margin: 0;
}

4. State โ€‹

State rules describe the styles of modules or layouts in specific states, using the is- prefix:

css
/* State rules */
.is-hidden {
  display: none !important;
}

.is-visible {
  display: block;
}

.is-active {
  font-weight: bold;
  color: #3498db;
}

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

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

.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* Module-specific states */
.button.is-disabled {
  background-color: #95a5a6;
}

.alert.is-dismissible {
  padding-right: 40px;
  position: relative;
}

5. Theme โ€‹

Theme rules define visual appearances such as colors and fonts, using the theme- prefix:

css
/* Theme rules */
.theme-dark {
  background-color: #2c3e50;
  color: #ecf0f1;
}

.theme-dark .card {
  background-color: #34495e;
  color: #ecf0f1;
}

.theme-dark .button {
  background-color: #3498db;
  color: white;
}

/* Brand themes */
.theme-brand-primary {
  background-color: #3498db;
  color: white;
}

.theme-brand-success {
  background-color: #2ecc71;
  color: white;
}

.theme-brand-warning {
  background-color: #f39c12;
  color: white;
}

.theme-brand-danger {
  background-color: #e74c3c;
  color: white;
}

SMACSS File Organization โ€‹

SMACSS recommends organizing files by category:

styles/
โ”œโ”€โ”€ base/
โ”‚   โ”œโ”€โ”€ _reset.css      # Reset styles
โ”‚   โ”œโ”€โ”€ _typography.css # Typography basics
โ”‚   โ””โ”€โ”€ _elements.css   # Element base styles
โ”œโ”€โ”€ layout/
โ”‚   โ”œโ”€โ”€ _grid.css       # Grid system
โ”‚   โ”œโ”€โ”€ _header.css     # Header layout
โ”‚   โ”œโ”€โ”€ _footer.css     # Footer layout
โ”‚   โ””โ”€โ”€ _sidebar.css    # Sidebar layout
โ”œโ”€โ”€ modules/
โ”‚   โ”œโ”€โ”€ _button.css     # Button module
โ”‚   โ”œโ”€โ”€ _card.css       # Card module
โ”‚   โ”œโ”€โ”€ _form.css       # Form module
โ”‚   โ””โ”€โ”€ _navigation.css # Navigation module
โ”œโ”€โ”€ state/
โ”‚   โ””โ”€โ”€ _states.css     # State styles
โ”œโ”€โ”€ theme/
โ”‚   โ”œโ”€โ”€ _default.css    # Default theme
โ”‚   โ””โ”€โ”€ _dark.css       # Dark theme
โ””โ”€โ”€ main.css            # Main file, imports all styles

Practical SMACSS Application Example โ€‹

html
<!-- Using SMACSS page structure -->
<div class="l-container">
  <!-- Layout: header -->
  <header class="l-header">
    <nav class="navigation">
      <a href="#" class="navigation-link is-active">Home</a>
      <a href="#" class="navigation-link">About</a>
      <a href="#" class="navigation-link">Contact</a>
    </nav>
  </header>

  <!-- Layout: main content area -->
  <main class="l-main">
    <div class="l-two-column">
      <!-- Layout: content -->
      <div class="l-content">
        <!-- Module: card -->
        <article class="card">
          <header class="card-header">
            <h2 class="card-title">Article Title</h2>
          </header>
          <div class="card-body">
            <p>Article content goes here...</p>
            <button class="button theme-brand-primary">Read More</button>
          </div>
        </article>

        <!-- Module: alert (with state) -->
        <div class="alert theme-brand-warning is-dismissible">
          <h3 class="alert-title">Warning</h3>
          <p class="alert-message">This is a warning message.</p>
        </div>
      </div>

      <!-- Layout: sidebar -->
      <aside class="l-sidebar">
        <!-- Module: sidebar card -->
        <div class="card">
          <div class="card-header">
            <h3 class="card-title">Sidebar</h3>
          </div>
          <div class="card-body">
            <p>Sidebar content...</p>
          </div>
        </div>
      </aside>
    </div>
  </main>

  <!-- Layout: footer -->
  <footer class="l-footer">
    <p>&copy; 2025 Your Company</p>
  </footer>
</div>

Pros and Cons of SMACSS โ€‹

Advantages:

  • Clear categorization: CSS has a well-defined organizational structure
  • Easy to scale: Know where to add new styles
  • Semantic prefixes: Can tell the purpose from the prefix
  • Flexible: Doesn't force specific naming formats

Disadvantages:

  • Requires discipline: Team needs to strictly follow categorization rules
  • Possible over-categorization: Sometimes hard to determine which category to use
  • Learning cost: Need to understand the differences between five categories

OOCSS Methodology โ€‹

OOCSS (Object Oriented CSS) was proposed by Nicole Sullivan, borrowing ideas from object-oriented programming. It emphasizes treating styles as reusable "objects."

Two Core Principles of OOCSS โ€‹

Principle 1: Separate Structure and Skin โ€‹

Structure refers to layout-related properties like width, height, positioning, etc. Skin refers to visual-related properties like colors, fonts, shadows, etc.

css
/* โŒ Poor practice: structure and skin mixed together */
.button-primary {
  /* Structure */
  display: inline-block;
  padding: 10px 20px;
  /* Skin */
  background-color: #3498db;
  color: white;
  border-radius: 4px;
}

.button-secondary {
  /* Structure (repeated) */
  display: inline-block;
  padding: 10px 20px;
  /* Skin */
  background-color: #95a5a6;
  color: white;
  border-radius: 4px;
}

/* โœ… Good practice: separate structure and skin */
/* Structure */
.button {
  display: inline-block;
  padding: 10px 20px;
  border: none;
  cursor: pointer;
  transition: all 0.3s;
}

/* Skin */
.skin-primary {
  background-color: #3498db;
  color: white;
}

.skin-secondary {
  background-color: #95a5a6;
  color: white;
}

.skin-rounded {
  border-radius: 4px;
}

.skin-pill {
  border-radius: 50px;
}

Usage:

html
<button class="button skin-primary skin-rounded">Primary Button</button>
<button class="button skin-secondary skin-pill">Secondary Button</button>

Principle 2: Separate Container and Content โ€‹

The style of content should not depend on the container it's in.

css
/* โŒ Poor practice: content depends on container */
.sidebar h2 {
  font-size: 20px;
  color: #333;
  margin-bottom: 10px;
}

.main-content h2 {
  font-size: 24px;
  color: #333;
  margin-bottom: 15px;
}

/* โœ… Good practice: separate container and content */
/* Heading object */
.heading {
  color: #333;
  line-height: 1.2;
}

.heading-large {
  font-size: 24px;
  margin-bottom: 15px;
}

.heading-medium {
  font-size: 20px;
  margin-bottom: 10px;
}

.heading-small {
  font-size: 16px;
  margin-bottom: 8px;
}

/* Usage */
/* <div class="sidebar">
     <h2 class="heading heading-medium">Sidebar Title</h2>
   </div>

   <div class="main-content">
     <h2 class="heading heading-large">Main Title</h2>
   </div> */

Practical OOCSS Application โ€‹

Let's create a flexible media object:

css
/* Media object: structure */
.media {
  display: flex;
  align-items: flex-start;
  gap: 15px;
}

.media-figure {
  flex-shrink: 0;
}

.media-body {
  flex: 1;
}

/* Media object: size variants */
.media-small .media-figure {
  width: 50px;
}

.media-medium .media-figure {
  width: 100px;
}

.media-large .media-figure {
  width: 150px;
}

/* Skin: spacing */
.spacing-tight {
  gap: 10px;
}

.spacing-comfortable {
  gap: 20px;
}

.spacing-loose {
  gap: 30px;
}

/* Skin: background */
.bg-white {
  background-color: white;
}

.bg-gray {
  background-color: #f8f9fa;
}

/* Skin: border */
.bordered {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 15px;
}

Using these objects:

html
<!-- Comment component -->
<div class="media media-medium spacing-comfortable bordered bg-white">
  <div class="media-figure">
    <img src="avatar.jpg" alt="User Avatar" class="avatar" />
  </div>
  <div class="media-body">
    <h3 class="heading heading-small">John Smith</h3>
    <p>This is a comment using the media object pattern...</p>
  </div>
</div>

<!-- Product list item -->
<div class="media media-large spacing-loose bg-gray">
  <div class="media-figure">
    <img src="product.jpg" alt="Product" />
  </div>
  <div class="media-body">
    <h3 class="heading heading-medium">Product Name</h3>
    <p>Product description...</p>
    <button class="button skin-primary skin-rounded">Add to Cart</button>
  </div>
</div>

OOCSS Utility Classes โ€‹

OOCSS encourages creating many reusable utility classes:

css
/* Display utilities */
.d-block {
  display: block;
}
.d-inline {
  display: inline;
}
.d-inline-block {
  display: inline-block;
}
.d-flex {
  display: flex;
}
.d-grid {
  display: grid;
}
.d-none {
  display: none;
}

/* Flexbox utilities */
.flex-row {
  flex-direction: row;
}
.flex-column {
  flex-direction: column;
}
.justify-start {
  justify-content: flex-start;
}
.justify-center {
  justify-content: center;
}
.justify-between {
  justify-content: space-between;
}
.align-start {
  align-items: flex-start;
}
.align-center {
  align-items: center;
}
.align-end {
  align-items: flex-end;
}

/* Spacing utilities */
.m-0 {
  margin: 0;
}
.m-1 {
  margin: 8px;
}
.m-2 {
  margin: 16px;
}
.m-3 {
  margin: 24px;
}
.p-0 {
  padding: 0;
}
.p-1 {
  padding: 8px;
}
.p-2 {
  padding: 16px;
}
.p-3 {
  padding: 24px;
}

/* Text utilities */
.text-left {
  text-align: left;
}
.text-center {
  text-align: center;
}
.text-right {
  text-align: right;
}
.text-bold {
  font-weight: bold;
}
.text-normal {
  font-weight: normal;
}

/* Color utilities */
.text-primary {
  color: #3498db;
}
.text-success {
  color: #2ecc71;
}
.text-danger {
  color: #e74c3c;
}
.bg-primary {
  background-color: #3498db;
}
.bg-success {
  background-color: #2ecc71;
}
.bg-danger {
  background-color: #e74c3c;
}

/* Border utilities */
.border {
  border: 1px solid #e0e0e0;
}
.border-top {
  border-top: 1px solid #e0e0e0;
}
.border-bottom {
  border-bottom: 1px solid #e0e0e0;
}
.rounded {
  border-radius: 4px;
}
.rounded-lg {
  border-radius: 8px;
}
.circle {
  border-radius: 50%;
}

Building interfaces with utility classes:

html
<div class="d-flex justify-between align-center p-2 border-bottom">
  <h2 class="text-bold m-0">Dashboard</h2>
  <button class="button skin-primary rounded">New Item</button>
</div>

<div class="d-grid p-3">
  <div class="bordered rounded-lg p-2 bg-white">
    <h3 class="text-center text-primary">Statistics</h3>
    <p class="text-center m-0">1,234 users</p>
  </div>
</div>

Pros and Cons of OOCSS โ€‹

Advantages:

  • High reusability: Styles can be used anywhere
  • Smaller CSS files: Avoid duplicate code
  • Rapid development: Combine existing classes instead of writing new styles
  • Consistency: Using the same base classes ensures consistency

Disadvantages:

  • HTML can be verbose: Need multiple class names
  • Reduced readability: HTML is filled with utility classes
  • Semantic issues: Class names don't express content meaning
  • Difficult to maintain: Need to change HTML to modify styles

How to Choose the Right Methodology? โ€‹

Project Size Considerations โ€‹

Small projects (1-5 pages):

  • Can avoid strict methodology
  • Keep naming consistent
  • Can learn from OOCSS utility class ideas

Medium projects (5-20 pages):

  • Recommend using BEM
  • Simple and intuitive, easy to get started
  • Suitable for small team collaboration

Large projects (20+ pages or multi-person collaboration):

  • BEM + SMACSS combination
  • BEM for component naming
  • SMACSS for file organization
  • Strict specifications help team collaboration

Team Skill Considerations โ€‹

Beginner teams:

  • Start with BEM
  • Rules are simple and clear
  • Lots of learning resources

Intermediate teams:

  • SMACSS is suitable for experienced teams
  • Need good planning abilities
  • Can establish comprehensive organizational structures

Advanced teams:

  • Can mix multiple methodologies
  • Customize based on project needs
  • Establish own specifications

Project Type Considerations โ€‹

Component libraries / Design systems:

  • OOCSS is very suitable
  • Provides many combinable base classes
  • Extremely flexible

Content websites / Blogs:

  • SMACSS is quite suitable
  • Clear content hierarchy
  • Semantics are more important

Applications / Admin systems:

  • BEM is most suitable
  • Component-based thinking
  • Strong maintainability

Mixing Methodologies โ€‹

In actual projects, we usually mix advantages from multiple methodologies:

css
/* Use SMACSS categorization + BEM naming */

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

/* Module: Card (BEM naming) */
.card {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
}

.card--featured {
  border: 2px solid #3498db;
}

.card__header {
  padding: 20px;
}

.card__title {
  margin: 0;
}

/* OOCSS utility classes */
.d-flex {
  display: flex;
}

.gap-2 {
  gap: 16px;
}

/* State */
.is-hidden {
  display: none;
}

Usage example:

html
<div class="l-container">
  <div class="card card--featured">
    <div class="card__header d-flex gap-2">
      <h2 class="card__title">Featured Article</h2>
    </div>
  </div>
</div>

Common Problems and Solutions โ€‹

Problem 1: Class names are too long โ€‹

BEM class names can be quite long, but this is acceptable:

css
/* Don't sacrifice clarity for brevity */
/* โŒ */
.c-h-t {
  /* What does this mean? */
}

/* โœ… */
.card__header-title {
  /* Although long, it's immediately clear */
}

You can use build tools to compress class names:

css
/* During development */
.navigation__dropdown-menu-item--active {
}

/* In production (after compression) */
.a1b2c3 {
}

Problem 2: Too many class names in HTML โ€‹

This is a common problem with OOCSS:

html
<!-- Might look messy -->
<div
  class="d-flex justify-between align-center p-2 m-3 bg-white rounded border"
>
  <!-- ... -->
</div>

Solution: Balance usage

html
<!-- Create semantic combination classes -->
<div class="panel-header">
  <!-- ... -->
</div>
css
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  margin: 24px;
  background-color: white;
  border-radius: 4px;
  border: 1px solid #e0e0e0;
}

Problem 3: When to use nested selectors? โ€‹

Methodologies encourage flattened selectors, but sometimes nesting is reasonable:

css
/* โŒ Avoid deep nesting */
.header .nav .menu .item .link {
}

/* โœ… BEM approach */
.nav__link {
}

/* โœ… But this kind of nesting is reasonable */
.card:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.card__button:disabled {
  opacity: 0.5;
}

Summary โ€‹

CSS methodologies are not restrictions but tools to help us better organize code.

Core points:

  • BEM: Suitable for small to medium projects, intuitive naming, easy to get started
  • SMACSS: Suitable for large projects, clear categorization, organized structure
  • OOCSS: Suitable for component libraries, highly reusable, flexible combinations

Selection advice:

  • Don't blindly pursue one methodology
  • Choose based on project needs and team situation
  • Can mix advantages from multiple methodologies
  • Most importantly, maintain consistency

Practice principles:

  • Keep selectors flattened
  • Avoid excessive nesting
  • Improve code reusability
  • Establish clear naming conventions
  • Good file organizational structure

The goal of methodologies is to make code more maintainable, easier to collaborate on, and more extensible. Choose the method that suits your project and stick with itโ€”this consistency is more important than which specific method you choose.