CSS Grid cho người mới: dựng bố cục lưới hai chiều dễ dàng

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Nếu Flexbox giỏi xếp các phần tử theo một hàng hoặc một cột, thì CSS Grid sinh ra để xử lý bố cục theo cả hai chiều cùng lúc: hàng và cột. Từ trang chủ có header, sidebar, nội dung, footer cho đến lưới ảnh, Grid làm những việc đó gọn hơn rất nhiều so với các mẹo float ngày xưa.

Bắt đầu với một lưới ba cột

Đặt display: grid lên phần tử cha, rồi khai báo các cột bằng grid-template-columns:

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

Đơn vị fr (fraction) nghĩa là một phần của không gian còn trống. Ba cột 1fr chia đều chiều rộng. Nếu viết 1fr 2fr 1fr, cột giữa sẽ rộng gấp đôi hai cột bên. Thuộc tính gap tạo khoảng cách giữa các ô, cả theo hàng lẫn cột.

Bạn có thể trộn đơn vị: grid-template-columns: 240px 1fr cho bố cục sidebar cố định và nội dung co giãn.

Lưới tự thích ứng không cần media query

Đây là công thức được dùng rất nhiều cho danh sách thẻ:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

Cách đọc: tạo càng nhiều cột càng tốt, mỗi cột rộng tối thiểu 220 pixel và tối đa chia đều phần còn lại. Trên màn hình rộng bạn có bốn năm cột, trên điện thoại chỉ còn một cột, mà không phải viết một media query nào.

Đặt phần tử vào đúng vị trí

Mặc định các item lấp vào ô theo thứ tự. Bạn có thể chỉ định vị trí và độ phủ bằng các đường lưới (grid line), được đánh số từ 1:

.featured {
  grid-column: 1 / 3;  /* từ đường 1 đến đường 3, phủ hai cột */
  grid-row: span 2;    /* phủ hai hàng */
}

Cú pháp span tiện hơn khi bạn chỉ quan tâm số ô phủ, không quan tâm vị trí tuyệt đối.

Đặt tên vùng với grid-template-areas

Cách này cho phép bạn "vẽ" bố cục bằng chữ, rất dễ đọc:

.page {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    'header header'
    'sidebar main'
    'footer footer';
  min-height: 100vh;
}
.page header { grid-area: header; }
.page aside  { grid-area: sidebar; }
.page main   { grid-area: main; }
.page footer { grid-area: footer; }

Muốn đổi bố cục trên điện thoại, bạn chỉ cần khai báo lại grid-template-areas trong media query, ví dụ xếp tất cả thành một cột. Phần HTML không phải thay đổi gì.

Căn chỉnh trong Grid

Grid dùng các thuộc tính quen thuộc từ Flexbox:

  • justify-items và align-items: căn nội dung của từng item trong ô theo chiều ngang và dọc.
  • justify-content và align-content: căn cả lưới trong container khi lưới nhỏ hơn container.
  • place-items: center: viết tắt, căn giữa mọi item trong ô của nó.

Muốn căn giữa một phần tử duy nhất theo cả hai chiều, display: grid; place-items: center; là một trong những cách ngắn nhất hiện nay.

Grid ngầm định và hàng tự tạo

Bạn không cần khai báo số hàng. Khi có nhiều item hơn số ô đã định nghĩa, trình duyệt tự tạo thêm hàng. Dùng grid-auto-rows: minmax(120px, auto) để các hàng này có chiều cao tối thiểu hợp lý nhưng vẫn giãn theo nội dung.

Những lỗi người mới hay gặp

  1. Đặt grid-template-columns lên item thay vì lên container.
  2. Quên rằng đường lưới đánh số từ 1 chứ không phải từ 0, và một lưới ba cột có bốn đường.
  3. Dùng auto-fill và auto-fit lẫn lộn. Với auto-fit, các cột trống bị thu lại nên item giãn ra, còn auto-fill giữ lại cột trống.
  4. Ép item có nội dung dài (như đoạn code hoặc URL dài) vào cột 1fr làm tràn lưới. Hãy thử minmax(0, 1fr) để cột được phép co nhỏ.

Ví dụ: trang chủ blog với lưới bài viết

Hãy ghép những mảnh trên thành một mẫu thực tế. Bài viết đầu tiên được làm nổi bật bằng cách phủ hai cột, các bài còn lại tự xếp vào lưới:

.posts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
}
.posts article:first-child {
  grid-column: span 2;
}

Khi màn hình quá hẹp để có hai cột, bài đầu tiên có thể gây tràn lưới. Bạn xử lý bằng cách chỉ áp dụng span 2 bên trong một media query cho màn hình đủ rộng. Đây là minh họa cho thói quen nên kiểm tra bố cục ở nhiều kích thước khác nhau, thay vì chỉ nhìn ở một cửa sổ.

Ngoài ra, DevTools của Firefox và Chrome đều có lớp phủ hiển thị đường lưới, rất hữu ích để hiểu vì sao một item nằm ở chỗ nó đang nằm.

Kết luận

Grid cho bạn quyền kiểm soát cả hai chiều với rất ít mã. Hãy bắt đầu bằng ba công cụ: repeat cùng fr, minmax với auto-fit, và grid-template-areas. Chỉ cần chừng đó là đủ dựng phần lớn các bố cục trang thông dụng.

Để thực hành Grid cùng Flexbox trên các dự án giao diện hoàn chỉnh, bạn có thể xem qua các khóa học web tại codebem.com khi có thời gian.

author_photo
Nguyễn Đình Cường

0 comment