CSS Grid

CSS Grid là gì?

CSS Grid là mô hình layout 2 chiều — kiểm soát cả hàng và cột cùng lúc. Phù hợp cho bố cục toàn trang hoặc các component phức tạp.

.container { display: grid; }

Định nghĩa cột và hàng

.grid {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;  /* 3 cột: cột 1 200px, cột 2-3 chia đều */
  grid-template-rows: auto 300px;        /* Hàng 1 tự động, hàng 2 300px */
  gap: 16px;                             /* Khoảng cách giữa cells */
}

Đơn vị fr (fraction)

fr biểu diễn phần không gian dư — chia tỉ lệ linh hoạt.

grid-template-columns: 1fr 2fr 1fr;   /* Tỉ lệ 1:2:1 */

repeat()minmax()

grid-template-columns: repeat(3, 1fr);       /* 3 cột bằng nhau */
grid-template-columns: repeat(3, minmax(100px, 1fr)); /* Mỗi cột tối thiểu 100px */

auto-fillauto-fit (responsive tự động)

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* Tự thêm/bỏ cột tuỳ chiều rộng — không cần media query */

Span: item chiếm nhiều cột/hàng

.item {
  grid-column: 1 / 3;     /* Từ line 1 đến line 3 (chiếm 2 cột) */
  grid-column: span 2;    /* Chiếm 2 cột từ vị trí hiện tại */
  grid-row: 1 / 3;        /* Chiếm 2 hàng */
  grid-row: span 2;
}

grid-template-areas (layout bằng tên)

.layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Căn chỉnh trong grid

/* Căn chỉnh tất cả items trong cells */
.grid {
  justify-items: start | end | center | stretch;   /* Theo trục ngang */
  align-items:   start | end | center | stretch;   /* Theo trục dọc */
}

/* Căn chỉnh toàn bộ grid trong container */
.grid {
  justify-content: start | end | center | space-between | space-around | space-evenly;
  align-content:   start | end | center | space-between | space-around | space-evenly;
}

/* Căn từng item riêng */
.item {
  justify-self: start | end | center | stretch;
  align-self:   start | end | center | stretch;
}

Demo: Grid 3 cột cơ bản

Kết quả
<h3>Grid 3 cột với repeat(3, 1fr)</h3>
<div class="grid-basic">
  <div class="gi">1</div>
  <div class="gi">2</div>
  <div class="gi">3</div>
  <div class="gi">4</div>
  <div class="gi">5</div>
  <div class="gi gi-wide">6 — span 2 cột</div>
  <div class="gi gi-tall">7 — span 2 hàng</div>
  <div class="gi">8</div>
  <div class="gi">9</div>
</div>
body { font-family: sans-serif; padding: 1rem; }
h3 { font-size: 1rem; color: #555; margin: 0 0 .5rem; }
.grid-basic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.gi {
  background: #4472c4; color: white;
  padding: 20px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-weight: bold; font-size: 1.1rem;
}
.gi-wide { grid-column: span 2; background: #ed7d31; }
.gi-tall { grid-row: span 2; background: #70ad47; }

Demo: grid-template-areas

Kết quả
<div class="page-layout">
  <header class="p-header">Header</header>
  <aside class="p-sidebar">Sidebar</aside>
  <main class="p-main">Main Content<br>Vùng nội dung chính</main>
  <footer class="p-footer">Footer</footer>
</div>
body { font-family: sans-serif; padding: 1rem; margin: 0; }
.page-layout {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  grid-template-columns: 160px 1fr;
  grid-template-rows: 48px 1fr 40px;
  gap: 8px;
  height: 300px;
}
.p-header  { grid-area: header;  background: #4472c4; color: white; }
.p-sidebar { grid-area: sidebar; background: #70ad47; color: white; }
.p-main    { grid-area: main;    background: #f0f4ff; }
.p-footer  { grid-area: footer;  background: #595959; color: white; }

.page-layout > * {
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px; font-weight: bold;
}

Demo: auto-fill + minmax() (responsive)

Kết quả
<h3>Card grid tự động — thay đổi cổng xem (resize iframe) để thấy hiệu ứng</h3>
<div class="card-grid">
  <div class="card">Card 1<p>Nội dung ngắn</p></div>
  <div class="card">Card 2<p>Nội dung dài hơn một chút</p></div>
  <div class="card">Card 3<p>Nội dung</p></div>
  <div class="card">Card 4<p>Đây là card với nội dung khá dài để test chiều cao tự động</p></div>
  <div class="card">Card 5<p>Nội dung</p></div>
  <div class="card">Card 6<p>Card cuối</p></div>
</div>
body { font-family: sans-serif; padding: 1rem; }
h3 { font-size: .9rem; color: #555; margin: 0 0 .5rem; }
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}
.card {
  background: white;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0,0,0,.08);
  transition: box-shadow .2s;
}
.card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.15); }
.card > p { margin: .5rem 0 0; color: #555; font-size: .9rem; }
.card { font-weight: bold; color: #4472c4; }

Bình luận