Lưới CSS – Bố cục bảng đã hoạt động trở lại. Luôn hiện diện và cân bằng

Surma
Surma

TL;DR

Nếu bạn đã quen thuộc với Flexbox, đây là Grid (Lưới). 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 có vẻ rất tốt (trừ phi bạn là một trong những người nghèo phải hỗ trợ IE9 trở xuống). Flexbox giúp nhiều tác vụ bố cục phức tạp trở nên dễ dàng hơn, chẳng hạn như khoảng cách cách đều giữa các phần tử, bố cục từ trên xuống dưới hoặc ưu tiên của trình hướng dẫn CSS: căn giữa theo chiều dọc.

Không có cách nào để căn chỉnh các phần tử trên nhiều vùng chứa Flexbox.

Tuy nhiên, màn hình thường có một chiều thứ hai mà chúng ta cần phải quan tâm. Bạn không thể tự mình định kích thước các thành phần. Tuy nhiên, đáng tiếc là bạn không thể có cả nhịp điệu dọc và ngang nếu chỉ sử dụng flexbox. Đây chính là lúc CSS Grid hỗ trợ bạn.

Lưới CSS đã được phát triển, phía sau một lá cờ trong hầu hết các trình duyệt trong hơn 5 năm và chúng tôi dành thêm thời gian cho khả năng tương tác để tránh lỗi khởi chạy như Flexbox. Vì vậy, nếu sử dụng Lưới để triển khai bố cục trong Chrome, bạn có thể 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 Grid của Microsoft cho Edge đã lỗi thời (giống như đã có trong IE11.) và bản cập nhật là "đang được xem xét".

Mặc dù khái niệm và cú pháp có nhiều điểm tương đồng, nhưng bạn đừ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. Chúng ta sẽ phối hợp với nhau khi sử dụng cả hai.

Xác định lưới

Để làm quen với các thuộc tính riêng lẻ của Grid, tôi xin giới thiệu Grid by Example (Lưới theo ví dụ) của Rachel Andrew hoặc Bản tóm tắt về thủ thuật CSS của Rachel Andrew. Nếu đã quen thuộc với Flexbox, bạn sẽ biết rất nhiều thuộc tính và ý nghĩa của chúng.

Hãy xem bố cục lưới 12 cột tiêu chuẩn. Bố cục 12 cột cổ điển phổ biến vì số 12 chia hết cho 2, 3, 4 và 6, do đó hữu ích cho nhiều thiết kế. Hãy triển khai bố cục này:

Không có cách nào để căn chỉnh các phần tử trên nhiều vùng chứa Flexbox.

Hãy bắt đầu với mã đánh dấu của chúng ta:

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

Trong biểu định kiểu, chúng ta bắt đầu bằng cách mở rộng body để bao phủ toàn bộ khung nhìn và chuyển thành 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 tôi có thể triển khai tất cả 12 cột trong bản minh hoạ của mình, nhưng vì chúng tôi không sử dụng hết mọi cột, nên làm như vậy sẽ khiến CSS trở nên lộn xộn không cần thiết. Để đơn giản hoá, chúng tôi sẽ triển khai bố cục theo cách sau:

Ví dụ về bố cục đơn giản

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. Thành phần điều hướng cũng sẽ có thể thay đổi ở cả hai chiều, nhưng chúng tôi sẽ áp dụng chiều rộng tối thiểu là 200px cho chiều rộng đó. (Tại sao? Tất nhiên, để thể hiện các tính năng của CSS Grid.)

Trong Lưới CSS, tập hợp các cột và hàng được gọi là đường theo dõi. Hãy bắt đầu bằng việc 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 sẽ tăng chiều cao cho 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, tức là hàng này sẽ điều chỉnh theo chiều cao cần thiết để phù hợp với các mục trong lưới (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-shrink, 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 tôi đang 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 đó. (Tương tự như min-widthmax-width thuộc một.) Như chúng ta đã thảo luận trước đó, chiều rộng tối thiểu là 200px. 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à từ viết tắt của "fraction unit", nhưng cũng có thể có nghĩa là đơn vị miễn phí sắp tới. 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 sẽ hoạt động chính xác và tạo ra hành vi mà chúng ta mong muốn:

Sắp xếp 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 xem xét thứ tự DOM. (Mặc dù trình đọc màn hình điều hướng DOM, nên để có thể truy cập đúng cách, bạn nên lưu ý đến cách sắp xếp lại các phần tử.) Nếu không có vị trí thủ công nào được thực hiện, 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ự lấp đầy 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ó lẽ cách dễ nhất để đặt các mục trong lưới là xác định những cột và hàng mà các mục đó che phủ. Lưới cung cấp 2 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. Ở phần thứ hai, bạn xác định điểm bắt đầu và khoảng cách:

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
Đặt theo cách thủ công

Chúng ta muốn tiêu đề bắt đầu trong cột đầu tiên và kết thúc trước cột thứ 3. Điều hướng của chúng ta sẽ bắt đầu ở hàng thứ hai và kéo dài tổng cộng 2 hàng.

Về mặt kỹ thuật, chúng ta đã triển khai xong 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 cho bạn để giúp bạn đặt vị trí dễ dàng 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ộ vùng trong lưới:

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 mỗi ô. 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.

Có nữa không?

Vâng, có, có quá nhiều nội dung để đề cập trong một bài đăng trên blog. Rachel Andrew, đồng thời là 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 Grid đơn giản hoá việc thiết kế web. Cô thậm chí còn viết một sách lên đó. Trang web Grid by Example (Lưới theo ví dụ) của cô là một tài nguyên đáng giá để làm quen với Grid. Nhiều người nghĩ rằng Grid là một bước cách mạng cho việc thiết kế web và 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.