Xuất bản: Ngày 19 tháng 9 năm 2024, Lần cập nhật gần đây nhất: Ngày 13 tháng 2 năm 2026
Nhóm công tác CSS đã kết hợp 2 đề xuất về bố cục dạng khối CSS thành một bản nháp quy cách. Nhóm hy vọng rằng điều này sẽ giúp họ dễ dàng so sánh hai lựa chọn và đưa ra quyết định cuối cùng. Nhóm Chrome vẫn tin rằng một cú pháp riêng biệt sẽ là cách tốt nhất để tiếp tục. Mặc dù vấn đề lớn nhất về hiệu suất được đề cập trong bài đăng trước của chúng tôi đã được giải quyết, nhưng vẫn còn những lo ngại về cú pháp, giá trị ban đầu và mức độ dễ học của một phiên bản kết hợp với lưới.
Tuy nhiên, để kiểm tra các giả định của mình, chúng tôi đã xem xét một số ví dụ để cho thấy cách bố cục dạng lưới hoạt động với từng phiên bản. Hãy xem các ví dụ trong bài đăng này và gửi ý kiến phản hồi cho chúng tôi để chúng tôi có thể đưa ra quyết định và tiếp tục triển khai tính năng này.
Bài đăng này không đề cập đến tất cả các trường hợp sử dụng có thể, tuy nhiên, rõ ràng là việc tách bố cục dạng khối khỏi bố cục dạng lưới sẽ không khiến tính năng này thiếu chức năng. Trên thực tế, điều ngược lại có thể đúng. Như bạn sẽ thấy trong bài đăng này, phiên bản display: masonry tạo ra những cơ hội mới và cú pháp đơn giản hơn.
Ngoài ra, nhiều nhà phát triển đã bày tỏ lo ngại về khả năng sắp xếp lại các mục bằng bố cục dạng khối có thể gây ra các vấn đề về khả năng tiếp cận. Vấn đề này cũng đang được giải quyết cho cả hai phiên bản cú pháp thông qua thuộc tính reading-flow được đề xuất.
Bố cục cơ bản kiểu khối xây
Đây là bố cục mà hầu hết mọi người hình dung khi nghĩ về bố cục dạng khối. Các mục hiển thị theo hàng và sau khi hàng đầu tiên được đặt, các mục tiếp theo sẽ di chuyển vào khoảng trống do các mục ngắn hơn để lại.
Thông qua display: masonry
Để tạo một bố cục kiểu xếp gạch, hãy sử dụng giá trị masonry cho thuộc tính display. Thao tác này sẽ tạo một bố cục kiểu xếp gạch với các cột mà bạn xác định (hoặc do nội dung xác định) và kiểu xếp gạch ở trục còn lại. Mục đầu tiên được hiển thị ở đầu khối và đầu dòng (do đó, ở trên cùng bên trái trong tiếng Anh) và các mục được bố trí theo hướng nội tuyến.
Để xác định các đường kẻ, hãy dùng masonry-template-tracks với các giá trị liệt kê đường kẻ như được dùng trong bố cục lưới CSS.
.masonry {
display: masonry;
masonry-template-tracks: repeat(3, 1fr);
gap: 10px;
}
Thông qua display: grid
Để tạo bố cục kiểu xếp gạch, trước tiên, hãy tạo bố cục dạng lưới bằng cách sử dụng giá trị grid cho thuộc tính display. Xác định các cột bằng thuộc tính grid-template-columns, sau đó gán giá trị masonry cho grid-template-rows.
Thao tác này sẽ tạo một bố cục như bạn mong đợi với các mục lưới được đặt tự động, tuy nhiên, các mục trong mỗi hàng sẽ sử dụng bố cục kiểu xếp gạch và sẽ sắp xếp lại để chiếm không gian còn lại của các mục nhỏ hơn trong hàng trước đó.
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: masonry;
gap: 10px;
}
Những điểm cần cân nhắc giữa hai lựa chọn
Một điểm khác biệt đáng chú ý giữa các phương thức này là với phiên bản display: masonry, bạn sẽ có được bố cục kiểu khối xây ngay cả khi không chỉ định bất kỳ bản nhạc nào bằng masonry-template-tracks. Do đó, display: masonry có thể là tất cả những gì bạn cần.
Nguyên nhân là do giá trị ban đầu của masonry-template-tracks là repeat(auto-areas, auto). Bố cục này sẽ tạo nhiều bản nhạc có kích thước tự động vừa với vùng chứa.
Luồng đảo ngược với khối xây
Quy cách này bao gồm các cách thay đổi hướng của luồng bố cục dạng khối. Ví dụ: bạn có thể thay đổi luồng để hiển thị từ cuối khối trở lên.
Thông qua display: masonry
Tạo bố cục kiểu khối xây bằng display: masonry, sau đó dùng masonry-direction với giá trị là column-reverse.
.masonry {
display: masonry;
masonry-template-tracks: repeat(3, 1fr);
masonry-direction: column-reverse;
}
Thông qua display: grid
Tạo bố cục kiểu xếp gạch bằng display: grid và grid-template-rows: masonry.
Sau đó, hãy dùng thuộc tính grid-auto-flow với giá trị mới là row-reverse để khiến các mục bố trí từ cuối khối của vùng chứa lưới.
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: masonry;
grid-auto-flow: row-reverse;
}
Những điểm cần cân nhắc giữa hai lựa chọn
Phiên bản display: masonry có nhiều điểm tương đồng với cách hoạt động của flexbox. Thay đổi hướng mà các cột chảy bằng cách sử dụng thuộc tính masonry-direction có giá trị là column-reverse.
Phiên bản lưới CSS sử dụng grid-auto-flow. Theo định nghĩa hiện tại, grid-auto-flow: row-reverse và grid-auto-flow: column-reverse sẽ mang lại hiệu ứng tương tự. Điều này có thể gây nhầm lẫn vì bạn có thể mong đợi chúng làm điều gì đó khác.
Khối xây cho các hàng
Bạn cũng có thể thay đổi hướng để xác định các hàng.
Thông qua display: masonry
Tạo bố cục kiểu khối xây bằng display: masonry, sau đó đặt giá trị của masonry-direction thành row. Trừ phi muốn các hàng có kích thước khối cụ thể, bạn không cần chỉ định kích thước của bất kỳ đường kẻ nào vì kích thước mặc định là auto. Do đó, các đường kẻ sẽ có kích thước phù hợp với nội dung mà chúng chứa.
.masonry {
display: masonry;
masonry-direction: row;
}
Thông qua display: grid
.masonry {
display: grid;
grid-template-columns: masonry;
grid-template-rows: repeat(3, 1fr);
}
Những điểm cần cân nhắc giữa hai lựa chọn
Tương tự như luồng đảo ngược, việc thay đổi phiên bản display: masonry từ cột thành hàng có nghĩa là thay đổi giá trị của masonry-direction. Với phiên bản lưới, bạn sẽ cần chuyển đổi các giá trị của thuộc tính grid-template-columns và grid-template-rows. Hoặc nếu bạn đang dùng cú pháp rút gọn, hãy thay đổi thứ tự của cú pháp.
Với cả hai ví dụ này về quy trình chuyển đổi, phiên bản display: masonry mang lại cảm giác trực quan hơn. Có một thuộc tính duy nhất kiểm soát luồng masonry-direction, thuộc tính này nhận một trong các giá trị sau:
rowcolumnrow-reversecolumn-reverse
Sau đó, bạn thêm mọi thông tin về kích thước cần thiết vào masonry-template-tracks, giả sử giá trị tự động mặc định không phải là giá trị bạn cần.
Với lưới, để đảo ngược hướng, bạn cần sử dụng thuộc tính grid-auto-flow và để chuyển đổi hàng, hãy chuyển đổi giá trị của các thuộc tính grid-template-*. Bạn cũng không thể bỏ qua giá trị cho trục lưới trong cú pháp lưới hiện tại. Bạn luôn cần chỉ định các thuộc tính grid-template-* trên trục không có giá trị masonry.
Định vị các mục
Trong cả hai phiên bản, bạn có thể đặt các mục một cách rõ ràng bằng cách sử dụng vị trí dựa trên dòng mà bạn sẽ quen thuộc trong bố cục lưới. Trong cả hai phiên bản, bạn chỉ có thể đặt các mục trong trục lưới. Đây là trục có các đường theo dõi được xác định trước, bạn không thể đặt các mục trên trục đang thực hiện bố cục kiểu xếp gạch.
Thông qua display: masonry
CSS sau đây xác định bố cục dạng khối xây với 4 cột. Do đó, trục lưới là các cột. Mục có lớp a được đặt từ dòng cột đầu tiên đến dòng cột thứ ba, trải dài trên 2 đường bằng các thuộc tính masonry-track-* mới. Bạn cũng có thể xác định đây là một dạng viết tắt của masonry-track: 1 / 3;.
.masonry {
display: masonry;
masonry-template-tracks: repeat(4, 1fr);
}
.a {
masonry-track-start: 1;
masonry-track-end: 3;
}
Thông qua display: grid
CSS sau đây xác định bố cục dạng khối xây với 4 cột. Do đó, trục lưới là các cột. Mục có lớp a được đặt từ dòng cột đầu tiên đến dòng cột thứ ba, trải dài trên 2 đường bằng các thuộc tính grid-column-*. Bạn cũng có thể xác định đây là một dạng viết tắt của grid-column: 1 / 3;.
Nếu trục lưới là cột thì các thuộc tính grid-row-* sẽ bị bỏ qua, còn nếu trục lưới là hàng thì các thuộc tính grid-columns-* sẽ bị bỏ qua.
.masonry {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
.a {
grid-column-start: 1;
grid-column-end: 3;
}
Bạn có thể sử dụng các dòng được đặt tên bằng cả hai cú pháp. Các ví dụ sau đây cho thấy một lưới có hai đường cột có tên là a.
Thông qua display: masonry
Các dòng có tên được xác định trong giá trị danh sách bài hát của masonry-template-tracks. Bạn có thể đặt mục này sau bất kỳ dòng nào có tên là a.
.masonry {
display: masonry;
masonry-template-tracks: 100px [a] auto [a] auto 100px;
}
.item {
masonry-track: a;
}
Thông qua display: grid
Các dòng có tên được xác định trong giá trị danh sách bài hát của grid-template-columns. Mục này được đặt sau dòng đầu tiên có tên là a. Nếu bạn xác định thuộc tính grid-row, thì thuộc tính này sẽ bị bỏ qua.
.masonry {
display: grid;
grid-template-columns: 100px [a] auto [a] auto 100px;
grid-template-rows: masonry;
}
.item {
grid-column: a;
grid-row: a; /* ignored */
}
Bạn cũng có thể sử dụng các vùng được đặt tên trong cả hai cú pháp. Các ví dụ sau đây minh hoạ một lưới có 3 bản nhạc có tên "a", "b" và "c".
Thông qua display: masonry
Các bản nhạc được đặt tên là giá trị của masonry-template-areas. Vì không có kích thước bản nhạc nào được xác định, nên cả ba đều có kích thước mặc định là auto. Mục này được đặt trong bản nhạc "a".
.masonry {
display: masonry;
masonry-template-areas: "a b c";
}
.item {
masonry-track: a;
}
Cách này hoạt động giống nhau cho dù bạn đang xác định hàng hay cột; điểm khác biệt duy nhất là thuộc tính masonry-direction.
Thông qua display: grid
Đối với cột, cú pháp về cơ bản là giống nhau. Tương tự, vì không có kích thước nào của các thành phần được xác định, nên cả 3 thành phần đều có kích thước mặc định là auto, nhưng bạn vẫn cần phải nói rõ rằng trục còn lại là masonry:
.masonry {
display: grid;
grid-template-areas: "a b c";
grid-template-rows: masonry;
}
.item {
grid-column: a;
}
Tuy nhiên, đối với hàng, bạn phải viết giá trị theo cách khác, vì grid-template-areas thực sự xác định một vùng hai chiều và mỗi hàng được viết dưới dạng một chuỗi riêng biệt:
.masonry {
display: grid;
grid-template-areas: "a" "b" "c"; /* Note the difference, each row is quoted. */
grid-template-columns: masonry;
}
.item {
grid-row: a;
}
Những điểm cần cân nhắc giữa hai lựa chọn
Với mọi vị trí, cú pháp display: masonry sẽ hoạt động hiệu quả hơn khi chuyển hướng. Vì thuộc tính masonry-track-* hoạt động theo bất kỳ hướng nào là trục lưới, nên tất cả những gì bạn cần làm để thay đổi hướng là thay đổi giá trị của masonry-direction. Với phiên bản lưới, ít nhất bạn sẽ cần các thuộc tính dự phòng để bật tính năng chuyển đổi. Tuy nhiên, hãy xem các ví dụ trước để biết những cách khác mà việc thay đổi hướng sẽ phức tạp hơn với phiên bản lưới.
Chữ viết tắt
Trong bài đăng này, các phiên bản đầy đủ đã được dùng để làm rõ những thuộc tính đang được sử dụng, tuy nhiên, cả phiên bản display: masonry và display: grid đều có thể được xác định bằng cách dùng các phiên bản rút gọn.
Thông qua display: masonry
Cú pháp rút gọn display: masonry sử dụng từ khoá masonry. Để tạo bố cục dạng khối cơ bản, hãy dùng CSS sau:
.masonry {
display: masonry;
masonry: repeat(3, 1fr);
}
Cách tạo một bố cục dạng khối đơn giản dựa trên hàng:
.masonry {
display: masonry;
masonry: row;
}
Để xác định các đường và bố cục dựa trên hàng bằng cú pháp rút gọn:
.masonry {
display: masonry;
masonry: repeat(3, 1fr) row;
}
Thông qua display: grid
Cách tạo bố cục cơ bản dạng khối xây bằng cách dùng cú pháp viết tắt grid.
.masonry {
display: grid;
grid: masonry / repeat(3, 1fr);
}
Cách tạo một bố cục dạng khối đơn giản dựa trên hàng:
.masonry {
display: grid;
grid: repeat(3, auto) / masonry;
}
Trong các ví dụ phức tạp hơn, vì cú pháp display:masonry tổng thể đơn giản hơn, nên bạn có thể kết hợp nhiều thuộc tính hơn vào cú pháp viết tắt mà không làm cho cú pháp này trở nên quá phức tạp.
Ví dụ: giả sử bạn tạo 3 cột có tên là "a", "b" và "c", được điền từ dưới lên.
Thông qua display:masonry
Trong display: masonry, bạn có thể đặt cả 3 thuộc tính này cùng nhau trong cú pháp rút gọn:
.masonry {
display: masonry;
masonry: column-reverse "a b c";
}
Vì các thành phần này có kích thước tự động, nên bạn không cần chỉ định kích thước. Tuy nhiên, nếu muốn một kích thước cụ thể, bạn có thể thêm kích thước đó. Ví dụ:masonry: column-reverse 50px 100px 200px "a b c";.
Ngoài ra, bạn có thể tự do sắp xếp lại từng thành phần mà không cần phải nhớ một thứ tự cụ thể. Nếu muốn thực hiện theo hàng, bạn chỉ cần hoán đổi column-reverse với row hoặc row-reverse; phần còn lại của cú pháp vẫn giữ nguyên.
Thông qua display: grid
Trong display: grid, bạn phải thiết lập riêng 3 khía cạnh này:
.masonry {
display: grid;
grid-template-rows: masonry;
grid-template-areas: "a b c";
grid-auto-flow: wrap-reverse;
}
Giống như ví dụ về kiểu xếp gạch, điều này sẽ làm cho tất cả các cột có kích thước auto, nhưng nếu muốn cung cấp kích thước rõ ràng, bạn có thể làm như sau:
.masonry {
display: grid;
grid: masonry / 50px 100px 200px;
grid-template-areas: "a b c";
grid-auto-flow: wrap-reverse;
}
Hoặc nếu bạn muốn sử dụng "grid" để đặt kích thước và tên vùng cùng một lúc:
.masonry {
display: grid;
grid: "a b c" masonry / 50px 100px 200px;
grid-auto-flow: wrap-reverse;
}
Trong cả hai ví dụ này, thứ tự là bắt buộc và sẽ khác nếu bạn muốn có các hàng. Ví dụ: thay đổi thành hàng sẽ có dạng như sau:
.masonry {
display: grid;
grid: 50px 100px 200px / masonry;
grid-template-areas: "a" "b" "c";
}
Hoặc để đưa tất cả vào một ký hiệu viết tắt:
.masonry {
display: grid;
grid: "a" 50px "b" 100px "c" 200px / masonry;
}
Những điểm cần cân nhắc giữa hai lựa chọn
Đường tắt display: masonry có thể được sử dụng rộng rãi vì đây là một đường tắt tương đối đơn giản. Trong nhiều trường hợp, đối với bố cục "tiêu chuẩn" kiểu xếp gạch, bạn chỉ cần đặt các định nghĩa về đường dẫn; tất cả các giá trị khác có thể giả định giá trị mặc định.
Phiên bản display: grid sử dụng từ viết tắt grid hiện có. Đây là một từ viết tắt khá phức tạp và theo kinh nghiệm của chúng tôi, các nhà phát triển ít sử dụng từ viết tắt này. Như trong các ví dụ trước, ngay cả khi được dùng cho bố cục dạng khối đơn giản, bạn cũng cần cẩn thận khi đặt thứ tự của các giá trị.
Lưu ý khác
Bài đăng này xem xét một số trường hợp sử dụng phổ biến hiện nay, tuy nhiên, chúng ta không biết tương lai sẽ ra sao đối với lưới hoặc bố cục dạng khối. Một lý do quan trọng để sử dụng cú pháp display: masonry riêng biệt là cú pháp này cho phép hai cú pháp này khác nhau trong tương lai. Đặc biệt là với các giá trị ban đầu (chẳng hạn như các giá trị cho masonry-template-tracks), bạn nên làm điều gì đó khác biệt trong bố cục dạng khối so với bố cục dạng lưới. Chúng tôi không thể thay đổi các giá trị mặc định của lưới nếu sử dụng phiên bản display: grid. Điều này có thể hạn chế những việc chúng tôi muốn làm trong tương lai.
Trong những ví dụ này, bạn có thể thấy những vị trí mà trình duyệt phải bỏ qua các thuộc tính hợp lệ trong lưới nếu sử dụng bố cục kiểu khối.
Ví dụ: grid-template-areas, trong đó hầu hết các giá trị đều được truyền qua vì nó xác định bố cục lưới hai chiều, trong bố cục kiểu xếp gạch, chúng ta chỉ xác định đầy đủ một hướng.
Đưa ra ý kiến phản hồi
Hãy xem những ví dụ này, cũng như bản nháp quy cách trình bày từng phiên bản bên cạnh phiên bản khác. Hãy cho chúng tôi biết ý kiến của bạn bằng cách bình luận về Vấn đề 9041. Hoặc nếu bạn muốn viết một bài đăng trên blog của riêng mình hoặc trên mạng xã hội, hãy nhớ cho chúng tôi biết trên X hoặc LinkedIn.