TL;DR
Nếu bạn đã quen thuộc với Flexbox, thì chắc hẳn bạn cũng sẽ thấy quen thuộc với Grid. Rachel Andrew duy trì một trang web tuyệt vời dành riêng cho CSS Grid để giúp bạn bắt đầu. Lưới hiện đã có trong Google Chrome.
Hộp linh hoạt? Lưới?
Trong vài năm qua, CSS Flexbox đã được sử dụng rộng rãi và khả năng hỗ trợ trình duyệt đang rất tốt (trừ phi bạn là một trong những người phải hỗ trợ IE9 trở xuống). Flexbox giúp thực hiện nhiều thao tác phức tạp liên quan đến bố cục dễ dàng hơn, chẳng hạn như khoảng cách bằng nhau giữa các phần tử, bố cục từ trên xuống dưới hoặc mục tiêu tối thượng của phép thuật CSS: căn giữa theo chiều dọc.
Tuy nhiên, màn hình thường có chiều thứ hai mà chúng ta cần phải quan tâm. Rất tiếc, bạn không thể có cả nhịp điệu dọc và ngang chỉ bằng cách sử dụng flexbox. Đây chính là lúc CSS Grid hỗ trợ bạn.
CSS Grid đã được phát triển, ẩn sau một cờ trong hầu hết các trình duyệt trong hơn 5 năm và đã dành thêm thời gian cho khả năng tương tác để tránh việc ra mắt có lỗi như Flexbox. Vì vậy, nếu sử dụng Lưới để triển khai bố cục trong Chrome, rất có thể bạn sẽ nhận được kết quả tương tự trong Firefox và Safari. Tại thời điểm viết bài, cách triển khai Lưới của Microsoft Edge đã lỗi thời (tương tự như đã có trong IE11) và bản cập nhật này đang "được xem xét".
Mặc dù có những điểm tương đồng về khái niệm và cú pháp, nhưng đừng coi Flexbox và Grid là các kỹ thuật bố cục cạnh tranh. Lưới sắp xếp theo hai chiều, trong khi Flexbox bố trí ở một chiều. Có sự cộng hưởng khi sử dụng cả hai cùng lúc.
Xác định lưới
Để làm quen với từng thuộc tính của Lưới, bạn nên tham khảo Grid By Example (Lưới theo ví dụ) của Rachel Andrew hoặc Cheat Sheet (Bảng tra cứu nhanh) của CSS Tricks. Nếu bạn đã quen thuộc với Flexbox, thì nhiều thuộc tính và ý nghĩa của các thuộc tính đó sẽ quen thuộc với bạn.
Hãy cùng xem bố cục lưới 12 cột tiêu chuẩn. Bố cục 12 cột cổ điển rất phổ biến vì số 12 có thể chia hết cho 2, 3, 4 và 6, do đó rất hữu ích cho nhiều thiết kế. Hãy triển khai bố cục này:
Hãy bắt đầu với mã đánh dấu:
<!DOCTYPE html>
<body>
<header></header>
<nav></nav>
<main></main>
<footer></footer>
</body>
Trong tệp stylesheet, chúng ta bắt đầu bằng cách mở rộng body
để nó bao phủ toàn bộ khung nhìn và biến thành một vùng chứa lưới:
html, body {
width: 100vw;
min-height: 100vh;
margin: 0;
padding: 0;
}
body {
display: grid;
}
Bây giờ, chúng ta đang sử dụng Lưới CSS. Thật tuyệt!
Bước tiếp theo là triển khai các hàng và cột trong lưới. Chúng ta có thể triển khai tất cả 12 cột trong bản minh hoạ, nhưng vì chúng ta không sử dụng mọi cột, nên việc này sẽ khiến CSS của chúng ta trở nên lộn xộn một cách không cần thiết. Để đơn giản, chúng ta sẽ triển khai bố cục theo cách sau:
Tiêu đề và chân trang có chiều rộng thay đổi và nội dung có thể thay đổi ở cả hai chiều. Thanh điều hướng cũng sẽ thay đổi theo cả hai kích thước, nhưng chúng ta sẽ áp đặt chiều rộng tối thiểu là 200px cho thanh điều hướng. (Tại sao? Đương nhiên là để giới thiệu các tính năng của CSS Grid.)
Trong CSS Grid, tập hợp các cột và hàng được gọi là đường dẫn. Hãy bắt đầu bằng cách xác định nhóm kênh đầu tiên, các hàng:
body {
display: grid;
grid-template-rows: 150px auto 100px;
}
grid-template-rows
lấy một trình tự kích thước để xác định từng hàng.
Trong trường hợp này, chúng ta đặt chiều cao của hàng đầu tiên là 150px và hàng cuối cùng là 100px.
Hàng giữa được đặt thành auto
, nghĩa là hàng này sẽ điều chỉnh theo chiều cao cần thiết để chứa các mục trong lưới (các phần tử con của vùng chứa lưới) trong hàng đó. Vì phần thân của chúng ta bị kéo giãn trên toàn bộ khung nhìn, nên kênh chứa nội dung (màu vàng trong hình trên) ít nhất sẽ lấp đầy mọi không gian có sẵn, nhưng sẽ phát triển (và khiến tài liệu cuộn) nếu cần.
Đối với các cột, chúng ta muốn có cách tiếp cận linh hoạt hơn: chúng ta muốn cả thành phần điều hướng và nội dung đều phát triển (và thu nhỏ), nhưng chúng ta muốn thành phần điều hướng không bao giờ thu nhỏ dưới 200px và chúng ta muốn nội dung lớn hơn thành phần điều hướng. Trong Flexbox, chúng ta sẽ sử dụng flex-grow và flex-zoom, nhưng trong Grid có một chút khác biệt:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
}
Chúng ta sẽ xác định 2 cột. Cột đầu tiên được xác định bằng hàm minmax()
. Hàm này nhận 2 giá trị: Kích thước tối thiểu và tối đa của kênh đó.
(Giống như min-width
và max-width
trong một.) Chiều rộng tối thiểu là 200px, như chúng ta đã thảo luận trước đó. Chiều rộng tối đa là 3fr
. fr
là một đơn vị dành riêng cho lưới cho phép bạn phân phối không gian có sẵn cho các phần tử lưới. fr có thể là viết tắt của "fraction unit" (đơn vị phân đoạn), nhưng cũng có thể có nghĩa là đơn vị miễn phí sắp ra mắt.
Giá trị ở đây có nghĩa là cả hai cột sẽ mở rộng để lấp đầy màn hình, nhưng cột nội dung sẽ luôn rộng gấp 3 lần cột điều hướng (miễn là cột điều hướng vẫn rộng hơn 200px).
Mặc dù vị trí của các mục trong lưới chưa chính xác, nhưng kích thước của các hàng và cột hoạt động chính xác và mang lại hành vi mà chúng ta nhắm đến:
Đặt các mục
Một trong những tính năng mạnh mẽ nhất của Lưới là có thể đặt các mục mà không cần quan tâm đến thứ tự DOM. (Mặc dù trình đọc màn hình điều hướng DOM, nhưng bạn nên lưu ý đến cách sắp xếp lại các phần tử để có thể truy cập đúng cách.) Nếu bạn không đặt vị trí theo cách thủ công, các phần tử sẽ được đặt trong Lưới theo thứ tự DOM, sắp xếp từ trái sang phải và từ trên xuống dưới. Mỗi phần tử chiếm một ô. Bạn có thể thay đổi thứ tự điền lưới bằng cách sử dụng grid-auto-flow
.
Vậy chúng ta đặt các phần tử như thế nào? Có thể nói, cách dễ nhất để đặt các mục trong lưới là xác định cột và hàng mà các mục đó bao phủ. Grid cung cấp hai cú pháp để thực hiện việc này: Trong cú pháp đầu tiên, bạn xác định điểm bắt đầu và điểm kết thúc. Trong phần tử thứ hai, bạn xác định điểm bắt đầu và span:
header {
grid-column: 1 / 3;
}
nav {
grid-row: 2 / span 2;
}
Chúng ta muốn tiêu đề bắt đầu ở cột đầu tiên và kết thúc trước cột thứ 3. Thanh điều hướng của chúng ta sẽ bắt đầu ở hàng thứ hai và tổng cộng có 2 hàng.
Về mặt kỹ thuật, chúng ta đã hoàn tất việc triển khai bố cục, nhưng tôi muốn giới thiệu cho bạn một số tính năng tiện lợi mà Grid cung cấp để bạn dễ dàng đặt bố cục hơn. Tính năng đầu tiên là bạn có thể đặt tên cho đường viền theo dõi và sử dụng các tên đó cho vị trí:
body {
display: grid;
grid-template-rows: 150px [nav-start] auto 100px [nav-end];
grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
grid-column: header-start / header-end;
}
nav {
grid-row: nav-start / nav-end;
}
Mã ở trên sẽ tạo ra bố cục giống như mã trước.
Mạnh mẽ hơn nữa là tính năng đặt tên cho toàn bộ khu vực trong lưới của bạn:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
grid-template-areas: "header header"
"nav content"
"nav footer";
}
header {
grid-area: header;
}
nav {
grid-area: nav;
}
grid-template-areas
lấy một chuỗi tên được phân tách bằng dấu cách, cho phép nhà phát triển đặt tên cho từng ô. Nếu 2 ô liền kề có cùng tên, thì các ô đó sẽ được liên kết vào cùng một khu vực. Bằng cách này, bạn có thể cung cấp thêm ngữ nghĩa cho mã bố cục và giúp các truy vấn nội dung nghe nhìn trở nên trực quan hơn. Xin nhắc lại, mã này sẽ tạo bố cục giống như trước.
Bạn có cần thêm thông tin nào khác không?
Có, có rất nhiều điều cần đề cập trong một bài đăng trên blog. Rachel Andrew, đồng thời là một GDE, là Chuyên gia được mời trong Nhóm làm việc về CSS và đã làm việc với họ ngay từ đầu để đảm bảo rằng Lưới đơn giản hoá thiết kế web. Cô thậm chí còn viết một sách về chủ đề này. Trang web Grid By Example (Lưới theo ví dụ) của cô là một tài nguyên có giá trị để làm quen với Lưới. Nhiều người cho rằng Lưới là một bước đột phá trong thiết kế web và tính năng này hiện được bật theo mặc định trong Chrome để bạn có thể bắt đầu sử dụng ngay hôm nay.