CSS Architecture & Methodologies
Structure and organize CSS for maintainability, scalability, and team collaboration. These methodologies prevent chaos in large projects.
💻 BEM (Block Element Modifier)
/* BEM Naming Convention */
/* Block: standalone component */
.card { }
/* Element: part of block (double underscore) */
.card__title { }
.card__image { }
.card__description { }
.card__button { }
/* Modifier: variation of block or element (double dash) */
.card--featured { }
.card--large { }
.card__button--primary { }
.card__button--disabled { }
/* Complete example */
<div class="card card--featured">
<img class="card__image" src="photo.jpg" alt="Photo">
<h3 class="card__title">Card Title</h3>
<p class="card__description">Description text</p>
<button class="card__button card__button--primary">Read More</button>
</div>
/* CSS */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
}
.card--featured {
border-color: #007bff;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.card__image {
width: 100%;
border-radius: 4px;
}
.card__title {
font-size: 1.5rem;
margin: 1rem 0 0.5rem;
}
.card__description {
color: #666;
margin-bottom: 1rem;
}
.card__button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
.card__button--primary {
background: #007bff;
color: white;
}
.card__button--disabled {
background: #ccc;
cursor: not-allowed;
}
/* Benefits */
/* - Clear relationship between classes */
/* - No specificity issues */
/* - Easy to understand component structure */
/* - Prevents naming conflicts */
🎯 OOCSS (Object Oriented CSS)
/* Principle 1: Separate structure from skin */
/* Structure (layout, positioning) */
.box {
display: block;
padding: 1rem;
margin-bottom: 1rem;
}
/* Skin (colors, fonts) */
.box-primary {
background: #007bff;
color: white;
border-radius: 4px;
}
.box-secondary {
background: #6c757d;
color: white;
border-radius: 4px;
}
/* Use together */
<div class="box box-primary">Primary Box</div>
<div class="box box-secondary">Secondary Box</div>
/* Principle 2: Separate container from content */
/* Bad - tightly coupled */
.sidebar h3 {
font-size: 1.5rem;
color: #333;
}
/* Good - reusable */
.heading-medium {
font-size: 1.5rem;
color: #333;
}
/* Media object pattern */
.media {
display: flex;
gap: 1rem;
}
.media__image {
flex-shrink: 0;
}
.media__body {
flex: 1;
}
/* Reusable in any context */
<div class="media">
<img class="media__image" src="avatar.jpg" alt="Avatar">
<div class="media__body">
<h4>Username</h4>
<p>Bio text</p>
</div>
</div>
📐 SMACSS (Scalable and Modular Architecture)
/* Five categories */
/* 1. Base - element selectors */
/* base.css */
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
color: #333;
}
a {
color: #007bff;
text-decoration: none;
}
/* 2. Layout - major page sections */
/* layout.css */
.l-header {
position: sticky;
top: 0;
z-index: 100;
}
.l-sidebar {
width: 250px;
}
.l-main {
flex: 1;
}
.l-footer {
margin-top: auto;
}
.l-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
/* 3. Module - reusable components */
/* modules/button.css */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-primary {
background: #007bff;
color: white;
}
.btn-large {
padding: 1rem 2rem;
font-size: 1.125rem;
}
/* modules/card.css */
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 1rem;
}
.card-header {
border-bottom: 1px solid #eee;
padding-bottom: 0.5rem;
margin-bottom: 1rem;
}
/* 4. State - how things look in different states */
/* state.css */
.is-hidden {
display: none;
}
.is-visible {
display: block;
}
.is-active {
font-weight: bold;
color: #007bff;
}
.is-disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
.is-loading {
position: relative;
color: transparent;
}
.is-error {
border-color: #dc3545;
color: #dc3545;
}
/* 5. Theme - color schemes */
/* theme.css */
.theme-dark {
--bg-color: #1a1a1a;
--text-color: #f0f0f0;
--border-color: #333;
}
.theme-light {
--bg-color: #ffffff;
--text-color: #333333;
--border-color: #ddd;
}
⚛️ Atomic CSS / Utility-First
/* Single-purpose utility classes */
/* Spacing */
.m-0 { margin: 0; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-3 { margin: 1rem; }
.m-4 { margin: 1.5rem; }
.mt-1 { margin-top: 0.25rem; }
.mr-2 { margin-right: 0.5rem; }
.mb-3 { margin-bottom: 1rem; }
.ml-4 { margin-left: 1.5rem; }
.p-2 { padding: 0.5rem; }
.px-3 { padding-left: 1rem; padding-right: 1rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
/* Display */
.block { display: block; }
.inline { display: inline; }
.inline-block { display: inline-block; }
.flex { display: flex; }
.grid { display: grid; }
.hidden { display: none; }
/* Flexbox */
.flex-row { flex-direction: row; }
.flex-col { flex-direction: column; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.items-center { align-items: center; }
.gap-2 { gap: 0.5rem; }
/* Text */
.text-center { text-align: center; }
.text-left { text-align: left; }
.text-right { text-align: right; }
.font-bold { font-weight: bold; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
/* Colors */
.text-primary { color: #007bff; }
.text-danger { color: #dc3545; }
.bg-white { background: white; }
.bg-gray { background: #f0f0f0; }
/* Borders */
.border { border: 1px solid #ddd; }
.rounded { border-radius: 4px; }
.rounded-full { border-radius: 9999px; }
/* Usage */
<div class="flex items-center gap-2 p-3 border rounded bg-white">
<img class="rounded-full" src="avatar.jpg" alt="Avatar">
<div class="flex-1">
<h3 class="text-lg font-bold m-0">Username</h3>
<p class="text-sm text-gray-600 m-0">Description</p>
</div>
</div>
/* Pros: rapid development, consistent spacing, no naming */
/* Cons: verbose HTML, learning curve, harder to read */
📁 File Organization
/* 7-1 Pattern (Sass) */
sass/
├── abstracts/
│ ├── _variables.scss /* Colors, fonts, spacing */
│ ├── _functions.scss /* Sass functions */
│ ├── _mixins.scss /* Reusable mixins */
├── base/
│ ├── _reset.scss /* CSS reset */
│ ├── _typography.scss /* Font styles */
│ ├── _base.scss /* Base element styles */
├── components/
│ ├── _button.scss
│ ├── _card.scss
│ ├── _form.scss
│ ├── _modal.scss
├── layout/
│ ├── _header.scss
│ ├── _footer.scss
│ ├── _sidebar.scss
│ ├── _grid.scss
├── pages/
│ ├── _home.scss
│ ├── _about.scss
│ ├── _contact.scss
├── themes/
│ ├── _dark.scss
│ ├── _light.scss
├── vendors/
│ ├── _normalize.scss
└── main.scss /* Import all partials */
/* main.scss */
/* Abstracts */
@import 'abstracts/variables';
@import 'abstracts/functions';
@import 'abstracts/mixins';
/* Base */
@import 'base/reset';
@import 'base/typography';
@import 'base/base';
/* Layout */
@import 'layout/header';
@import 'layout/footer';
@import 'layout/sidebar';
@import 'layout/grid';
/* Components */
@import 'components/button';
@import 'components/card';
@import 'components/form';
@import 'components/modal';
/* Pages */
@import 'pages/home';
@import 'pages/about';
/* Themes */
@import 'themes/dark';
@import 'themes/light';
/* Alternative: ITCSS (Inverted Triangle) */
/* Order by specificity (generic to specific) */
styles/
├── settings/ /* Variables, config */
├── tools/ /* Mixins, functions */
├── generic/ /* Reset, normalize */
├── elements/ /* Base element styles */
├── objects/ /* Layout patterns (OOCSS) */
├── components/ /* UI components */
├── utilities/ /* Helper classes */
/* Alternative: Component-based (React/Vue) */
components/
├── Button/
│ ├── Button.jsx
│ ├── Button.module.css
│ └── Button.test.js
├── Card/
│ ├── Card.jsx
│ ├── Card.module.css
│ └── Card.test.js
🎨 CSS-in-JS Patterns
/* Styled Components (React) */
import styled from 'styled-components';
const Button = styled.button`
padding: 0.5rem 1rem;
background: ${props => props.primary ? '#007bff' : '#6c757d'};
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
`;
/* Usage */
<Button primary>Primary</Button>
<Button>Secondary</Button>
/* CSS Modules */
/* Button.module.css */
.button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
.primary {
background: #007bff;
color: white;
}
/* Button.jsx */
import styles from './Button.module.css';
function Button({ primary, children }) {
return (
<button className={`${styles.button} ${primary ? styles.primary : ''}`}>
{children}
</button>
);
}
/* Tailwind CSS */
<button class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
Button
</button>
🎯 Best Practices
/* 1. Use consistent naming convention */
/* Choose one: BEM, SMACSS, or utility-first */
/* 2. Keep specificity low */
/* Bad - high specificity */
div#header nav ul li a.active {
color: blue;
}
/* Good - low specificity */
.nav-link.is-active {
color: blue;
}
/* 3. Avoid !important */
/* Use proper specificity instead */
/* 4. Group related properties */
.element {
/* Positioning */
position: absolute;
top: 0;
left: 0;
/* Display & Box Model */
display: flex;
width: 100%;
padding: 1rem;
margin: 1rem 0;
/* Typography */
font-size: 1rem;
line-height: 1.5;
color: #333;
/* Visual */
background: white;
border: 1px solid #ddd;
border-radius: 4px;
/* Misc */
cursor: pointer;
}
/* 5. Use CSS variables for theming */
:root {
--color-primary: #007bff;
--color-secondary: #6c757d;
--spacing-unit: 0.5rem;
}
.button {
background: var(--color-primary);
padding: calc(var(--spacing-unit) * 2);
}
/* 6. Mobile-first media queries */
/* Base styles (mobile) */
.container {
width: 100%;
padding: 1rem;
}
/* Tablet and up */
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
/* Desktop and up */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
/* 7. Component-based thinking */
/* Each component should be self-contained */
/* 8. Document your CSS */
/**
* Card Component
*
* A flexible card component with optional header and footer.
*
* @example
*
* Header
* Content
*
*
*/
.card { }
/* 9. Use linters and formatters */
/* Stylelint, Prettier for consistent code */
/* 10. Optimize for performance */
/* Minimize file size */
/* Use CSS minification */
/* Leverage caching */
/* Critical CSS for above-the-fold content */
🔍 Practical Example: Complete System
/* Using BEM + SMACSS hybrid */
/* Layout */
.l-page {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.l-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
/* Header Component (BEM) */
.header {
background: white;
border-bottom: 1px solid #eee;
padding: 1rem 0;
}
.header__nav {
display: flex;
gap: 2rem;
list-style: none;
margin: 0;
padding: 0;
}
.header__link {
color: #333;
text-decoration: none;
}
.header__link:hover {
color: #007bff;
}
.header__link--active {
color: #007bff;
font-weight: bold;
}
/* Card Component (BEM) */
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
overflow: hidden;
}
.card--featured {
border: 2px solid #007bff;
}
.card__image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card__content {
padding: 1rem;
}
.card__title {
font-size: 1.5rem;
margin: 0 0 0.5rem;
}
.card__description {
color: #666;
margin: 0 0 1rem;
}
.card__footer {
border-top: 1px solid #eee;
padding: 1rem;
display: flex;
justify-content: space-between;
}
/* Button Component (BEM) */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
text-decoration: none;
text-align: center;
transition: opacity 0.2s;
}
.btn:hover {
opacity: 0.9;
}
.btn--primary {
background: #007bff;
color: white;
}
.btn--secondary {
background: #6c757d;
color: white;
}
.btn--outline {
background: transparent;
border: 1px solid currentColor;
}
.btn--large {
padding: 1rem 2rem;
font-size: 1.125rem;
}
/* State classes (SMACSS) */
.is-hidden {
display: none;
}
.is-loading {
opacity: 0.6;
pointer-events: none;
}
/* Usage */
<div class="l-page">
<header class="header">
<div class="l-container">
<nav>
<ul class="header__nav">
<li><a href="/" class="header__link header__link--active">Home</a></li>
<li><a href="/about" class="header__link">About</a></li>
</ul>
</nav>
</div>
</header>
<main class="l-container">
<div class="card card--featured">
<img class="card__image" src="photo.jpg" alt="Photo">
<div class="card__content">
<h2 class="card__title">Card Title</h2>
<p class="card__description">Description text</p>
</div>
<div class="card__footer">
<button class="btn btn--primary">Learn More</button>
<button class="btn btn--outline">Share</button>
</div>
</div>
</main>
</div>
🎯 Key Takeaways
- BEM: Block__Element--Modifier naming prevents conflicts
- OOCSS: Separate structure from skin, container from content
- SMACSS: Five categories: Base, Layout, Module, State, Theme
- Atomic CSS: Single-purpose utility classes for rapid development
- File organization: 7-1 pattern or ITCSS for large projects
- Low specificity: Avoid overly specific selectors and !important
- Consistency: Choose one methodology and stick with it
- Documentation: Comment complex patterns and component usage