Welcome to Part 39 of the CSS Mastery & Responsive Layouts Course. In this part, we will explore CSS Architecture: BEM, SMACSS, & OOCSS.
As websites grow, stylesheets can quickly become a messy tangle of unmaintainable selectors, duplicate styles, and high specificity battles. To prevent this, front-end developers use CSS architectures. These design patterns dictate how code is structured, named, and modularized to ensure readability, scalability, and ease of maintenance across large teams and codebases.
Chapter 196: BEM (Block, Element, Modifier) Methodology
BEM is a naming convention that makes CSS selectors clear, self-documenting, and independent of DOM nesting hierarchies.
⬢ The BEM Selector Anatomy
- Block (
block): A standalone, reusable component (e.g.,.card,.nav,.menu). - Element (
block__element): A child part of the block that cannot exist independently (demarcated by double underscores, e.g.,.card__title,.card__button). - Modifier (
block--modifier): A flag used to change look, behavior, or state (demarcated by double dashes, e.g.,.card--featured,.card__button--disabled).
/* Card Block */
.card {
border: 1px solid #ddd;
padding: 15px;
}
/* Card Element */
.card__title {
font-size: 1.5rem;
margin-bottom: 10px;
}
/* Card Element with Modifier */
.card__title--accent {
color: #3b82f6;
}
Chapter 197: SMACSS (Scalable and Modular Architecture)
SMACSS (pronounced “smacks”) divides CSS rules into five clear categories.
▪ The Five Categories of SMACSS
- Base: Global reset rules, default margins, element selectors (
html,body,a,h1). No class names. - Layout: Major page shell grids and structure elements (e.g.,
#header,#footer,.layout-sidebar). Usually prefixed withl-orlayout-. - Module: Reusable component designs (e.g.,
.product-grid,.media-card). - State: Temporary modifications to layouts or modules (e.g.,
.is-active,.is-collapsed). State classes are typically triggered by JavaScript. - Theme: Color skins, fonts, and borders that override default module appearances for dark themes or specific branding options.
/* Layout rule */
.l-container {
max-width: 1200px;
margin: 0 auto;
}
/* Module rule */
.alert-box {
padding: 10px;
border-radius: 4px;
}
/* State rule */
.alert-box.is-visible {
display: block;
}
Chapter 198: OOCSS (Object-Oriented CSS)
OOCSS encourages developers to treat CSS styles as reusable objects rather than unique declarations for specific elements.
⬢ Separation of Structure and Skin
Avoid styling layouts and styling skins (colors/gradients/shadows) in the same class. Keep container geometries separate from visual aesthetics.
/* Geometries / Structure */
.box {
width: 250px;
padding: 20px;
box-sizing: border-box;
}
/* Skins */
.skin-primary {
background-color: #3b82f6;
color: #ffffff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.skin-secondary {
background-color: #f3f4f6;
color: #1f2937;
}
▪ Separation of Container and Content
Do not tie child styles directly to the parent container. Use generic element selectors instead:
- Bad:
.sidebar h3 { font-size: 1.2rem; }(H3 cannot be reused elsewhere). - Good:
.widget-title { font-size: 1.2rem; }(Title class can be used anywhere).
Chapter 199: Architecture Practice & Self-Check
⬢ Practice Exercises
- Exercise 1: BEM Search Form: Create a search widget component following BEM naming conventions. It must include a parent block (
.search-form), child elements (.search-form__input,.search-form__submit), and modifiers (.search-form--dark-theme).
▪ Self-Check Questions
- What does the abbreviation BEM stand for?
- Answer: Block, Element, Modifier.
- In BEM, what separator denotes an element?
- Answer: Two underscores (
__).
- Answer: Two underscores (
- In BEM, what separator denotes a modifier?
- Answer: Two dashes (
--).
- Answer: Two dashes (
- What are the five structural categories of SMACSS?
- Answer: Base, Layout, Module, State, and Theme.
- Under SMACSS, what naming prefix is typically given to layout classes?
- Answer:
l-orlayout-.
- Answer:
- Under SMACSS, what prefix denotes states?
- Answer:
is-(e.g.,.is-active,.is-disabled).
- Answer:
- What are the two core principles of Object-Oriented CSS (OOCSS)?
- Answer: Separation of structure and skin, and separation of container and content.
- Why does BEM discourage deep nested CSS selectors like .card .body .btn?
- Answer: Deep nesting raises selector specificity, making overrides difficult and locking styles to a specific HTML structure.
- What SMACSS category handles styling tag selectors directly without class names?
- Answer: The Base category.
- How does separation of structure and skin improve codebase sizes?
- Answer: It allows you to reuse structural wrappers with different visual skins without duplicating margin, padding, or width values in your stylesheet.
Discussion
Loading comments...