CSS Chuyên Sâu – Variables, BEM và Tổ Chức Mã

Bài 6 – CSS Variables, BEM, tổ chức thư mục theo mô hình truyền thống và các lỗi CSS phổ biến.

21/11/2025 DaiPhan
Bài 6 / 6

CSS Chuyên Sâu – Variables, BEM và Tổ Chức Mã

Bài này giúp hoàn thiện nền tảng CSS bằng cách đưa ra những kỹ thuật và quy tắc quan trọng trong dự án thực tế: biến CSS, quy tắc BEM và cách tổ chức CSS có cấu trúc rõ ràng. Đây là bước chuẩn hóa cuối cùng trước khi đi vào dự án lớn.

1. Nội dung chính

  • CSS Variables (custom properties)
  • BEM – Block Element Modifier
  • Tổ chức CSS theo mô hình truyền thống (folder structure, naming conventions)
  • Các lỗi CSS phổ biến và cách phòng tránh

2. Ví dụ

/* CSS Variables */
:root {
  --primary-color: #3498db;
  --secondary-color: #2c3e50;
  --spacing: 16px;
  --border-radius: 8px;
  --transition-speed: 0.3s;
}

button {
  background: var(--primary-color);
  padding: var(--spacing);
  border-radius: var(--border-radius);
  transition: all var(--transition-speed) ease;
}

/* BEM */
.card {}              /* Block */
.card__title {}       /* Element */
.card__content {}     /* Element */
.card--highlight {}   /* Modifier */
.card--large {}       /* Modifier */

Ví dụ BEM thực tế

<article class="card card--highlight">
  <img class="card__image" src="product.jpg" alt="Product">
  <div class="card__content">
    <h3 class="card__title">Product Name</h3>
    <p class="card__description">Product description goes here.</p>
    <button class="card__button card__button--primary">Buy Now</button>
  </div>
</article>
.card {
  background: white;
  border-radius: var(--border-radius);
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  overflow: hidden;
  transition: transform var(--transition-speed) ease;
}

.card--highlight {
  border: 2px solid var(--primary-color);
}

.card--large {
  max-width: 400px;
}

.card:hover {
  transform: translateY(-2px);
}

.card__image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card__content {
  padding: var(--spacing);
}

.card__title {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
  color: var(--secondary-color);
}

.card__description {
  color: #666;
  margin-bottom: 1rem;
}

.card__button {
  background: #f0f0f0;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background var(--transition-speed) ease;
}

.card__button--primary {
  background: var(--primary-color);
  color: white;
}

.card__button:hover {
  opacity: 0.9;
}

Tổ chức folder truyền thống

css/
├── base/
│   ├── reset.css          /* Reset/Normalize CSS */
│   ├── typography.css     /* Font, line-height, heading styles */
│   └── variables.css      /* CSS Variables */
├── components/
│   ├── button.css         /* Button styles */
│   ├── card.css           /* Card component */
│   ├── form.css           /* Form elements */
│   └── navigation.css     /* Navigation styles */
├── layouts/
│   ├── header.css         /* Header layout */
│   ├── footer.css         /* Footer layout */
│   ├── grid.css           /* Grid system */
│   └── sidebar.css        /* Sidebar layout */
├── pages/
│   ├── home.css           /* Home page specific styles */
│   ├── about.css          /* About page styles */
│   └── contact.css        /* Contact page styles */
└── utilities/
    ├── spacing.css        /* Margin/padding utilities */
    ├── text.css           /* Text alignment, color utilities */
    └── helpers.css        /* Helper classes */

3. Kiến thức trọng tâm

  • CSS Variables giúp tái sử dụng giá trị và dễ quản lý theme; thay đổi một nơi, áp dụng nhiều nơi
  • BEM tạo cấu trúc đặt tên rõ ràng, tránh xung đột và tăng khả năng bảo trì
  • Tổ chức CSS theo thư mục giúp quản lý dự án lớn: base → layouts → components → pages
  • Các lỗi thường gặp: lạm dụng !important, đặt tên không nhất quán, selector quá dài, viết CSS trùng lặp

4. Bài tập nhanh

  1. Tạo file CSS có sử dụng biến màu và biến spacing, áp dụng vào 2 component khác nhau:
/* variables.css */
:root {
  --primary-color: #3498db;
  --secondary-color: #2c3e50;
  --spacing-small: 8px;
  --spacing-medium: 16px;
  --spacing-large: 24px;
  --border-radius: 6px;
}

/* button.css */
.btn {
  padding: var(--spacing-small) var(--spacing-medium);
  border-radius: var(--border-radius);
  background: var(--primary-color);
  color: white;
  border: none;
  cursor: pointer;
}

.btn--large {
  padding: var(--spacing-medium) var(--spacing-large);
}

/* card.css */
.card {
  padding: var(--spacing-medium);
  border-radius: var(--border-radius);
  background: white;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.card__header {
  margin-bottom: var(--spacing-small);
}
  1. Xây dựng component “card” theo chuẩn BEM (card, card__title, card__content…):
<div class="card">
  <div class="card__header">
    <h3 class="card__title">Card Title</h3>
    <span class="card__subtitle">Subtitle</span>
  </div>
  <div class="card__body">
    <p class="card__text">Card content goes here.</p>
    <button class="card__button card__button--primary">Action</button>
  </div>
</div>
  1. Tạo cấu trúc thư mục CSS: base, components, layouts, pages và thêm 1 file vào mỗi nhóm:
/* base/typography.css */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  line-height: 1.6;
  color: #333;
}

/* components/alert.css */
.alert {
  padding: 1rem;
  border-radius: 4px;
  margin-bottom: 1rem;
}

.alert--success {
  background: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

/* layouts/container.css */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
}

/* pages/dashboard.css */
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr;
  min-height: 100vh;
}

.dashboard__sidebar {
  background: #f8f9fa;
  padding: 2rem;
}

.dashboard__content {
  padding: 2rem;
}

5. Kết luận

CSS Variables, BEM và tổ chức CSS truyền thống là chìa khóa để giữ mã nguồn sạch, rõ ràng và dễ bảo trì. Đây là bước cần thiết trước khi bạn có thể xây dựng những dự án giao diện lớn và chuyên nghiệp.