"Nên dùng Grid hay Flexbox?" là câu hỏi mà gần như lập trình viên front-end nào cũng từng đặt ra. Cả hai đều là công cụ layout hiện đại, được mọi trình duyệt phổ biến hỗ trợ, và đều giúp ta thoát khỏi thời kỳ dùng float hay bảng để dàn trang. Thực tế, đây không phải cuộc đối đầu mà là hai công cụ bổ trợ nhau. Hiểu rõ thế mạnh của từng cái sẽ giúp bạn viết CSS ngắn hơn, ít "hack" hơn và dễ bảo trì hơn.

Khác biệt cốt lõi: một chiều và hai chiều

Đây là điểm phân biệt quan trọng nhất:

  • Flexbox làm việc trên một chiều tại một thời điểm: hoặc hàng, hoặc cột. Các phần tử được sắp xếp dọc theo một trục, có thể xuống dòng, nhưng mỗi dòng được tính toán độc lập với dòng khác.
  • Grid làm việc trên hai chiều cùng lúc: hàng và cột. Bạn định nghĩa một lưới, rồi đặt phần tử vào các ô hoặc vùng trên lưới đó, và các phần tử thẳng hàng theo cả hai trục.

Một cách nghĩ khác cũng hữu ích: Flexbox đi từ nội dung ra ngoài, kích thước phần tử quyết định cách chúng chia sẻ không gian. Grid đi từ bố cục vào trong, bạn vẽ khung trước rồi đặt nội dung vào.

Khi nào Flexbox là lựa chọn tốt

Flexbox phù hợp với các thành phần nhỏ, nơi phần tử xếp thành một hàng hoặc một cột:

  • Thanh điều hướng với logo bên trái, menu bên phải.
  • Nhóm nút bấm, nhóm tag, breadcrumb.
  • Căn giữa một phần tử theo cả chiều ngang lẫn dọc.
  • Card có phần footer luôn bám đáy dù nội dung dài ngắn khác nhau.
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

Chỉ bốn dòng là đủ để logo và menu dàn hai bên, căn giữa theo chiều dọc. Thuộc tính flex: 1 cũng rất tiện khi bạn muốn một phần tử "chiếm hết phần còn lại", chẳng hạn ô tìm kiếm giữa thanh header.

Khi nào Grid là lựa chọn tốt

Grid tỏa sáng khi bạn cần kiểm soát cả hàng lẫn cột:

  • Bố cục trang tổng thể: header, sidebar, nội dung chính, footer.
  • Lưới sản phẩm, gallery ảnh, dashboard nhiều widget.
  • Form có nhãn và ô nhập thẳng hàng theo cột.
  • Thiết kế có phần tử trải qua nhiều hàng hoặc nhiều cột.

Một mẫu lưới responsive rất phổ biến, không cần media query:

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.5rem;
}

Trình duyệt sẽ tự tính số cột vừa với chiều rộng màn hình, mỗi cột tối thiểu 220px. Với bố cục trang, grid-template-areas cho phép mô tả layout gần như bằng hình vẽ, rất dễ đọc:

.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}

Khi chuyển sang màn hình nhỏ, bạn chỉ cần khai báo lại grid-template-areas trong media query thay vì sửa từng phần tử.

Kết hợp cả hai: cách làm phổ biến nhất

Trong dự án thực tế, câu trả lời thường là "dùng cả hai". Grid dựng khung trang và các lưới lớn, còn Flexbox xử lý bố cục bên trong từng thành phần. Ví dụ một trang danh sách sản phẩm:

  1. Toàn trang dùng Grid để chia header, sidebar bộ lọc và vùng nội dung.
  2. Vùng nội dung dùng Grid để dàn các card sản phẩm.
  3. Bên trong mỗi card dùng Flexbox theo cột để đẩy nút "Mua ngay" xuống đáy.
  4. Hàng giá và đánh giá trong card dùng Flexbox theo hàng.

Ngoài ra, tính năng subgrid hiện đã được các trình duyệt lớn hỗ trợ, cho phép lưới con kế thừa đường kẻ của lưới cha. Nhờ đó, tiêu đề và giá của các card nằm cạnh nhau có thể thẳng hàng tuyệt đối, điều mà trước đây phải dùng nhiều thủ thuật mới làm được.

Một vài câu hỏi giúp ra quyết định nhanh

  • Bố cục chỉ có một hàng hoặc một cột? Bắt đầu với Flexbox.
  • Cần phần tử thẳng hàng theo cả hàng lẫn cột? Dùng Grid.
  • Kích thước do nội dung quyết định và bạn muốn chúng "co giãn tự nhiên"? Flexbox.
  • Bạn đã có khung thiết kế cố định từ designer? Grid thường biểu diễn trực tiếp hơn.
  • Thấy mình đặt width: 33.33% và margin âm để giả lập lưới trong Flexbox? Đó là dấu hiệu nên chuyển sang Grid.

Cả hai đều dùng chung thuộc tính gap và các thuộc tính căn chỉnh như align-items, justify-content, nên kiến thức học được ở bên này phần lớn dùng được ở bên kia.

Kết luận

Flexbox và Grid không cạnh tranh mà phân công nhau: Flexbox cho bố cục một chiều và các thành phần nhỏ, Grid cho bố cục hai chiều và khung trang. Thay vì chọn phe, hãy luyện thói quen tự hỏi "mình đang sắp xếp theo một trục hay hai trục?" trước khi viết dòng display đầu tiên. Khi kết hợp nhuần nhuyễn, bạn sẽ thấy CSS layout không còn là nỗi ám ảnh nữa.

Nguồn tham khảo