Biết cách tạo responsive grid là kỹ năng thiết yếu của web development.
Dù tạo portfolio nhiếp ảnh, trang thương mại điện tử, hay landing page – tất cả dựa trên grid layout. Grid có khắp nơi.
Nếu biết xây dựng grid layout responsive tốt, bạn sẽ ngay lập tức nổi bật như front-end developer.
Đi thẳng vào vấn đề với tổng quan nhanh về grid:
Grid layout là gì?
Grid là phương pháp kiểm chứng thời gian tổ chức element trực quan trong media.
Designer áp dụng grid từ những ngày đầu báo in và quảng cáo in.
Dùng grid tạo ra composition thẩm mỹ, dễ dàng cho não bộ tiếp thu và hiểu. Chắc chắn muốn dùng trong website.
Thiết kế grid chia khu vực thành các cột (column). Giữa các cột là khoảng trống (gutter).
Thường dùng tổng 12 cột vì có thể chia không gian thành ước số 2 hoặc 3.
Thực hành này thấy rõ trên theme Studiopress:

Cột không nhất thiết cùng rộng. Có thể muốn cột trải 2 cột, cột khác trải 4, 6, hoặc hơn.
Chỉ cần đảm bảo mọi element trên trang bắt đầu và kết thúc tại một cột.
Ngoài ra, có thể chia khu vực dọc thành các zone khác nhau, mỗi zone có tổ hợp chiều rộng cột khác.
Không phức tạp như nghe lúc đầu, phải không? Bây giờ, cách tốt nhất xây dựng responsive grid cho website?
Đọc tiếp để biết:
Các phương pháp tạo responsive grid
Gần đây flexbox và CSS Grid Layout được bàn luận nhiều.
Trước công nghệ CSS mới này, phải dùng property float. Tạo element column float, rắc rối percentage width và media query là xong.
(Trước float grid, HTML table là lựa chọn duy nhất. Nhưng chúng ta không nói đến đó 😉 )
Khi học front-end, tôi bắt đầu với responsive framework Zurb Foundation. Nhiều bạn có thể dùng Bootstrap.
Framework responsive làm web dễ dàng hơn. Tiết kiệm thời gian lớn!
Tuy nhiên, phụ thuộc quá nhiều vào framework không tốt. Đặc biệt nếu không hiểu chính xác chúng làm gì bên dưới.
Hãy cố gắng hiểu scaffolding (khung xương) hoạt động như thế nào dưới lớp vỏ framework. Không dễ như vứt class column vào div, nhưng bạn sẽ hiểu nguyên lý CSS tốt hơn.
Kết luận: sẽ làm bạn thành web developer tốt hơn.
Mini-project của chúng ta
Sẽ đi sâu vào cách xây dựng grid 2 cột đơn giản, dùng 3 phương pháp:
- float
- flexbox
- CSS Grid Layout
Sẽ giải thích từng bước với code snippet và đồ họa.
Lập kế hoạch grid
Grid muốn làm: 2 cột cơ bản. Có main content area và sidebar, giống nhiều thiết kế web.
Khi xây dựng layout, điều đầu tiên quyết định: responsive như thế nào. Tức là layout thay đổi ra sao khi xem desktop vs tablet/mobile.
Chiến lược tôi dùng khi bắt đầu build: ghi chú cách design thay đổi across devices. Ghi chú cho bài tập này:
- Mobile: cột xếp chồng (stack), main content trên, sidebar dưới. Cả hai 100% width.
- Tablet: cột cạnh nhau (side by side), mỗi cột 50% width.
- Desktop: main content 2/3 width, sidebar 1/3 width.
Giao diện mong muốn tại từng breakpoint:

Hơi tốn công trước, nhưng kế hoạch này tiết kiệm thời gian vì biết chính xác phải build gì. Kỹ thuật đặc biệt hữu ích cho project lớn, phức tạp.
Đã có thông tin cơ bản, bắt đầu làm grid!
Float Grid
Có thể thắc mắc tại sao vẫn nói float grid, khi flexbox và CSS Grid đang chiếm ưu thế. Vẫn đưa vào vì có thể có edge case cần float, đặc biệt IE cũ.
Property float trong CSS ban đầu dành cho dùng như cho text wrap quanh ảnh. float: left cho ảnh căn lề trái parent element.

Tạo grid với float
Tạo grid: cho nhiều element property float, khiến chúng căn lề một bên (trái hoặc phải).
.column { display: block; float: left; }
Có vẻ đơn giản?
Tuy nhiên, điểm phiền toái của float: nó lấy element ra khỏi normal flow của document.
Ảnh dưới minh họa chuyện gì xảy ra khi column float xanh bị lấy ra khỏi normal display. Div cha xám sẽ collapse (thu gọn) về chiều cao như không có con.

Sửa được 2 cách.
Cách 1: thêm display: table cho parent element. Cách 2: clear float bằng pseudo-element :after cho parent với style:
.parent:after { clear: both; content: ""; display: block; }
Lưu ý khác: nếu dùng padding và margin (gần như luôn) → cần set box-sizing: border-box cho mọi element.
Khai báo này đưa padding, margin vào tính toán width/height cuối cùng. Đảm bảo element không tràn ra ngoài trang.
*, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
Chris Coyier có giải thích rất hay tại đây.
Dùng Media Query làm grid responsive
Để grid responsive, dùng media query. Nhờ đó grid có layout cụ thể tại chiều rộng thiết bị nhất định.
Từ ghi chú: mobile – cả main và sidebar 100%; tablet – cả hai 50% side by side; desktop – main 2/3, sidebar 1/3 side by side.
HTML: tạo parent div, 2 child column div với class phân biệt main/sidebar.
<div class="parent"> <div class="column main"></div> <div class="column sidebar"></div> </div>
Mobile:
CSS mobile-first: mặc định set cả 2 column 100%.
.column { display: block; width: 100%; }
Tablet:
Width tablet trở lên: float column trái, width 50%.
@media only screen and (min-width: 641px){ .column { width: 50%; float: left; } }
Desktop:
Media query khác cho desktop: đổi width main/sidebar thành 2/3 và 1/3.
@media only screen and (min-width: 1025px){ .main { width: 66.66%; } .sidebar { width: 33.33%; } }
Xem code hoạt động trên CodePen.
Có vẻ đơn giản, phải không? Float không tệ – từng là tất cả chúng ta có.
Nhưng chuyển sang flexbox, bạn sẽ thấy float grid hơi "hacky", flexbox trực quan hơn.
Flexbox Grid
Tạo responsive grid với flexbox: dùng cùng HTML trên, parent div có 2 child column div.
Điều đầu tiên: khai báo parent dùng flexbox:
.parent { display: flex; }
Sau đó set flex property cho column div:
.column { flex: 1; }
flex: 1 nghĩa là mỗi column div có width bằng nhau. Giống tỷ lệ.
Muốn cột đầu gấp đôi cột sau: set flex cột đầu = 2, cột sau = 1 (một nửa).
Đó là tất cả cần để bắt đầu!
Flexbox khá thông minh, tự chia đều không gian grid giữa các column bất kể số lượng.
So với CSS float grid, bạn sẽ đồng ý flexbox đơn giản hơn.
Tạo flex grid responsive
Làm như float grid: set style mặc định mobile-first.
Mobile:
Mobile không cần flexbox, chỉ tablet/desktop. Parent div chưa cần display: flex.
Muốn column div 100% width. Có thể set explicit width: 100% cho column.
Hoặc không khai báo width. Div mặc định display: block → tự động 100% width.
Tablet:
Từ tablet trở lên: thêm flexbox, media query cho style width ≥ tablet.
Đầu tiên: tạo flexbox, set parent display: flex.
Muốn column chia đều ở width này → dùng flex: 1 cho tất cả column div. Giá trị 1 = cùng width relative to nhau.
@media only screen and (min-width: 641px){ .parent { display: flex; } .column { flex: 1; } }
Desktop:
Desktop: main content 2/3 width, sidebar 1/3 còn lại.
Tăng flex value main column thành 2. Sidebar flex giữ 1 từ tablet, không cần khai báo lại desktop.
@media only screen and (min-width: 1025px){ .main { flex: 2; } }
Nghĩa: main content gấp đôi sidebar.
Vì 2 cột → main 2/3 width, sidebar một nửa đó = 1/3 width.
Flexbox mạnh mẽ và trực quan
Ngay lập tức thấy flexbox cần CSS rất ít. Và grid tạo ra giống hệt float grid.
Điều tôi yêu thích flexbox: nó chỉ làm việc. Trực quan.
Sau khi vật vã với CSS float nhiều năm, không tin được việc làm grid dễ đến thế.
Flexbox còn có property nâng cao:
- Căn chỉnh item column cả ngang và dọc (có, dọc!!).
- Căn giữa item hoặc kéo dài tới mép trái/phải parent grid.
- Thay đổi thứ tự item ở breakpoint khác nhau.
Đọc thêm flexbox trên CSS Tricks và Mozilla.
CodePen flex grid tại đây.
Không bao giờ phải dùng float nữa. Trừ khi wrap text quanh ảnh, 당 nhiên.
Sẵn sàng thêm fun? Chuyển sang phương pháp grid cuối:
CSS Grid Layout
CSS Grid là phương pháp mới nhất xây dựng grid. Tương tự nhưng rất khác flexbox.
Theo Rachel Andrew – chuyên gia CSS Grid hàng đầu – mỗi thứ có điểm mạnh:
- Flexbox hữu ích cho element sắp xếp một chiều: hàng hoặc cột.
- CSS Grid hữu ích cho sắp xếp hai chiều: hàng VÀ cột.
Bà giải thích thêm tại sao CSS Grid tốt hơn cho layout website điển hình (header, footer, content, sidebar) so với flexbox.
Hiện tại, nhược điểm chính CSS Grid: chưa được hỗ trợ universal bởi mọi browser.
Chrome cũ, iOS Safari cũ, Android cũ không support. IE và Edge support lúng túng.
Muốn dùng CSS Grid, có 2 lựa chọn:
- Dùng kèm CSS fallback cho browser không support.
- Hoặc dùng flexbox chờ support browser phổ biến hơn.
CSS Grid hoạt động như thế nào
Giống flexbox, CSS Grid yêu cầu set display property trên parent element. Ở đây: display: grid.
Tuy nhiên, khác biệt lớn: thay vì set grid setting trên từng child element, ta set grid template trên parent.
Để set grid template: khai báo số cột/hàng muốn có, và kích thước mỗi cái.
Dùng grid-template-columns cho nhiều cột, grid-template-rows cho nhiều hàng.
Property theo sau bởi giá trị độ dài cho mỗi child element.
Grid 2 cột: chỉ dùng grid-template-columns.
Property này có 2 giá trị, mỗi giá trị cho 1 cột:
.parent { display: grid; grid-template-columns: 1fr 1fr; }
Fr đơn vị là gì?!
"fr" = fraction (phân số) – đơn vị đo mới. Chỉ phần không gian khả dụng mỗi item grid chiếm.
Tương tự số flex – cả hai đều biểu thị width relative của child element so với nhau.
Tạo CSS Grid responsive
Style grid theo mobile-first lần nữa.
Mobile:
Child column stack mobile → không set CSS Grid style.
Tablet:
Muốn 2 child element width bằng nhau cho tablet.
.parent { display: grid; grid-template-columns: 1fr 1fr; }
Desktop:
Tương tự tỷ lệ main gấp đôi sidebar → 2/3 và 1/3.
@media only screen and (min-width: 1025px){ .parent { grid-template-columns: 2fr 1fr; } }
Thú vị: không cần set grid style trên column con, chỉ parent!
CSS Grid mạnh mẽ phi thường
Giống flexbox, CSS Grid làm được nhiều hơn grid 2 cột đơn giản.
Có thể tạo layout phức tạp với width, height, arrangement đa dạng. Tôi chỉ cào bề mặt khả năng CSS Grid.
Muốn đọc thêm: Grid by Example của Rachel Andrew hoặc bài Mozilla "Basic concepts of grid layout".
CodePen CSS Grid tại đây.
Kết thúc
Vẫn băn khoăn phương pháp nào tốt nhất? Theo tôi, flexbox là lựa chọn tốt nhất hiện nay.
Đã tồn tại đủ lâu để có browser support tốt, và cách hiệu quả tạo grid. Cũng不会完全被CSS Grid取代, vì flexbox có điểm mạnh phối hợp tốt với CSS Grid.
Cuối cùng, CSS Grid vẫn đang hoàn thiện browser support. Nhưng nên bắt đầu học ngay, dù chỉ chút. Sẽ không lâu CSS Grid trở thành tiêu chuẩn ngành cho layout website.
Bạn có phương pháp ưa thích? Đã bị kẹt học flexbox hoặc CSS Grid? Comment bên dưới nhé!