Xuất bản: Ngày 30 tháng 4 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 Chrome rất mong muốn thấy được việc triển khai bố cục kiểu khối xây trên web. Tuy nhiên, chúng tôi cho rằng việc triển khai tính năng này trong quy cách Lưới CSS như đề xuất trong bài đăng gần đây của WebKit sẽ là một sai lầm. Chúng tôi cũng cho rằng bài đăng trên WebKit đã phản đối một phiên bản của bố cục dạng lưới mà không ai đề xuất.
Do đó, bài đăng này nhằm mục đích giải thích lý do khiến chúng tôi tại Chrome lo ngại về việc triển khai bố cục dạng khối như một phần của quy cách Bố cục dạng lưới CSS, đồng thời làm rõ chính xác những gì mà đề xuất thay thế cho phép. Tóm lại:
- Nhóm Chrome rất muốn bỏ chặn bố cục dạng khối, chúng tôi biết đây là điều mà các nhà phát triển mong muốn.
- Việc thêm bố cục dạng khối vào quy cách lưới là vấn đề, không phải vì bạn nghĩ bố cục dạng khối có phải là lưới hay không.
- Việc xác định bố cục dạng lưới bên ngoài quy cách lưới không ngăn chặn nhiều kích thước đường kẻ cho bố cục dạng lưới, hoặc việc sử dụng các thuộc tính như căn chỉnh hoặc khoảng trống, hoặc bất kỳ tính năng nào khác được dùng trong bố cục dạng lưới.
Có nên đưa bố cục dạng khối vào lưới không?
Nhóm Chrome cho rằng bố cục dạng khối xây nên là một phương thức bố cục riêng biệt, được xác định bằng cách sử dụng display: masonry (hoặc một từ khoá khác nếu có tên phù hợp hơn). Trong bài đăng này, bạn có thể xem một số ví dụ về cách đoạn mã có thể trông như thế nào.
Có 2 lý do liên quan khiến chúng tôi cảm thấy rằng bố cục dạng khối được xác định rõ ràng hơn bên ngoài bố cục dạng lưới – khả năng xảy ra các vấn đề về hiệu suất bố cục và thực tế là cả bố cục dạng khối và bố cục dạng lưới đều có những tính năng phù hợp với một phương thức bố cục nhưng không phù hợp với phương thức còn lại.
Hiệu suất
Lưới và bố cục kiểu khối xây có sự khác biệt về cách trình duyệt xử lý việc định cỡ và vị trí. Khi một lưới được bố trí, tất cả các mục sẽ được đặt trước bố cục và trình duyệt biết chính xác nội dung trong mỗi track. Điều này cho phép kích thước nội tại phức tạp rất hữu ích trong lưới. Với bố cục kiểu khối xây, các mục được đặt khi chúng được bố trí và trình duyệt không biết có bao nhiêu mục trong mỗi đường. Đây không phải là vấn đề với tất cả các bản nhạc có kích thước nội tại hoặc tất cả các bản nhạc có kích thước cố định, nhưng sẽ là vấn đề nếu bạn kết hợp các bản nhạc có kích thước cố định và nội tại. Để giải quyết vấn đề này, trình duyệt cần thực hiện bước bố cục trước khi bố trí mọi mục theo mọi cách có thể để đo lường. Với một lưới lớn, điều này sẽ góp phần gây ra các vấn đề về hiệu suất bố cục.
Do đó, nếu có bố cục kiểu xếp gạch với định nghĩa về đường dẫn là grid-template-columns: 200px auto 200px (một việc rất phổ biến khi dùng lưới), bạn sẽ bắt đầu gặp phải vấn đề. Những vấn đề này sẽ tăng lên theo cấp số nhân khi bạn thêm lưới phụ.
Có ý kiến cho rằng hầu hết mọi người sẽ không gặp phải vấn đề này, tuy nhiên, chúng tôi đã biết rằng mọi người có các lưới rất lớn. Chúng tôi không muốn phát hành một thứ gì đó có giới hạn về cách sử dụng, khi có một phương pháp thay thế.
Chúng ta nên làm gì với những thứ không hợp lý trong mỗi phương thức bố cục?
Khi flexbox và lưới trở thành một phần của CSS, các nhà phát triển thường cảm thấy chúng hoạt động theo cách không nhất quán. Sự không nhất quán mà họ gặp phải là do những giả định lâu nay về cách bố cục hoạt động, dựa trên bố cục khối. Theo thời gian, các nhà phát triển đã bắt đầu hiểu được các ngữ cảnh định dạng. Khi chúng ta chuyển sang ngữ cảnh định dạng lưới hoặc linh hoạt, một số thứ sẽ hoạt động khác đi. Ví dụ: bạn biết rằng khi ở trong flexbox, không phải tất cả các phương thức căn chỉnh đều có sẵn, vì flexbox là một chiều.
Việc nhóm masonry vào grid sẽ phá vỡ mối liên kết rõ ràng này giữa ngữ cảnh định dạng và tính sẵn có của những thứ như thuộc tính căn chỉnh, được xác định trong quy cách Căn chỉnh hộp theo ngữ cảnh định dạng.
Nếu quyết định giải quyết vấn đề về hiệu suất đã nêu trước đó bằng cách đưa ra định nghĩa về đường kẻ cố định và đường kẻ nội tại hỗn hợp là bất hợp pháp trong bố cục dạng khối, thì bạn phải nhớ rằng một mẫu rất phổ biến cho bố cục dạng lưới không hoạt động đối với bố cục dạng khối.
Ngoài ra, còn có những mẫu sẽ có ý nghĩa trong bố cục dạng khối, chẳng hạn như grid-template-columns: repeat(auto-fill, max-content), vì bạn không có các ràng buộc chéo, nhưng cần phải giữ nguyên trạng thái không hợp lệ trong lưới. Sau đây là danh sách các thuộc tính mà chúng tôi dự kiến sẽ hoạt động khác hoặc có các giá trị hợp lệ khác.
grid-template-areas: Trong bố cục kiểu khối xây, bạn chỉ có thể chỉ định hàng ban đầu theo hướng không phải kiểu khối xây.grid-template: Cần có ký hiệu viết tắt để giải thích tất cả các điểm khác biệt.- Theo dõi các giá trị kích thước cho
grid-template-columnsvàgrid-template-rowsdo có sự khác biệt về giá trị hợp lệ. grid-auto-flowkhông áp dụng cho bố cục dạng khối vàmasonry-auto-flowkhông áp dụng cho bố cục dạng lưới. Việc hợp nhất chúng sẽ gây ra các vấn đề về những thứ không hợp lệ do phương thức bố cục mà bạn đang sử dụng.- Lưới có 4 thuộc tính vị trí (
grid-column-start, v.v.), trong khi bố cục dạng khối chỉ có 2. - Lưới có thể sử dụng cả 6 thuộc tính
justify-*vàalign-*, nhưng Masonry chỉ sử dụng một số thuộc tính như flexbox.
Bạn cũng sẽ phải chỉ định điều gì sẽ xảy ra trong tất cả các trường hợp lỗi mới do nhà phát triển sử dụng một giá trị không hợp lệ trong grid-with-masonry hoặc grid-without-masonry. Ví dụ: bạn có thể sử dụng grid-template-columns: masonry hoặc grid-template-rows: masonry nhưng không được sử dụng cả hai cùng một lúc. Điều gì sẽ xảy ra nếu bạn sử dụng cả hai cùng một lúc?
Bạn phải chỉ định những thông tin này để tất cả các trình duyệt đều thực hiện cùng một thao tác.
Tất cả những điều này trở nên phức tạp theo quan điểm về quy cách, cả hiện tại và trong tương lai. Chúng ta cần đảm bảo rằng mọi thứ đều tính đến bố cục dạng khối và liệu bố cục đó có hoạt động hay không. Điều này cũng gây nhầm lẫn cho các nhà phát triển. Tại sao bạn cần lưu ý rằng mặc dù sử dụng display: grid nhưng một số thứ không hoạt động do sử dụng bố cục dạng khối?
Một đề xuất thay thế
Như đã đề cập, nhóm Chrome muốn xác định bố cục kiểu khối bên ngoài quy cách lưới. Điều này không có nghĩa là bạn chỉ có thể sử dụng một phương thức bố cục rất đơn giản với kích thước cột giống hệt nhau. Bạn vẫn có thể xem tất cả bản minh hoạ trong bài đăng WebKit.
Bố cục xây gạch cổ điển
Khi nhắc đến bố cục dạng khối, hầu hết mọi người đều nghĩ đến một bố cục có nhiều cột có kích thước bằng nhau. Bạn có thể xác định điều này bằng cách sử dụng CSS sau đây. CSS này cần ít dòng mã hơn so với phiên bản lưới đi kèm tương đương.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1rem;
}

Sử dụng tính năng định cỡ rãnh kiểu lưới cho nhiều chiều rộng cột
Ngoài vấn đề đã đề cập trước đó về việc sử dụng kích thước cố định và kích thước nội tại hỗn hợp của các phần tử, bạn có thể sử dụng tất cả kích thước phần tử mà bạn yêu thích trong lưới. Chẳng hạn như ví dụ trong bài đăng trên blog của WebKit, một mẫu gồm các cột hẹp và rộng lặp lại.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
gap: 1rem;
}

Kích thước đường dẫn bổ sung cho bố cục dạng lưới
Có những lựa chọn định cỡ đường chạy khác mà chúng tôi không cho phép trong lưới vì lưới là một phương thức bố cục hai chiều. Những thuộc tính này sẽ hữu ích trong bố cục kiểu khối xây nhưng sẽ gây nhầm lẫn nếu chúng không hoạt động trong bố cục dạng lưới.
Tự động điền các bản nhạc có kích thước max-content.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, max-content);
gap: 1rem;
}
Tự động điền các bản phụ đề có kích thước auto. Thao tác này sẽ tạo ra các bản phụ đề có cùng kích thước, tự động điều chỉnh kích thước để phù hợp với bản phụ đề lớn nhất.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
gap: 1rem;
}

Cho phép nội dung trải dài trên các cột và đặt các mục trên bố cục kiểu xếp gạch
Không có lý do gì để không có nội dung trải dài trên các cột trong một quy cách riêng về bố cục dạng lưới. Thao tác này có thể sử dụng thuộc tính masonry-track, là một cách viết tắt của masonry-track-start và masonry-track-end vì bạn chỉ có một phương diện để trải rộng mọi thứ khi ở bố cục kiểu xếp gạch.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
}
.span-2 {
masonry-track: span 2; /* spans two columns */
}
.placed {
masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

Lưới con hoặc lưới phụ sử dụng các đường lưới
Điều này có thể được hỗ trợ bằng một quy cách riêng về bố cục dạng khối, một lần nữa với điều kiện là không được phép sử dụng các thành phần có kích thước cố định và kích thước nội tại hỗn hợp. Bạn cần xác định chính xác hình thức của thông báo đó. Chúng tôi không thấy lý do gì khiến việc này không hiệu quả.
Kết luận
Chúng tôi muốn đạt đến một điểm của quy cách có thể được vận chuyển một cách tương tác. Tuy nhiên, chúng tôi muốn thực hiện việc đó theo cách hoạt động hiệu quả ở hiện tại và trong tương lai, đồng thời có thể được các nhà phát triển tin tưởng. Cách duy nhất để giải quyết các vấn đề về hiệu suất đã nêu là làm cho vấn đề thứ hai (vấn đề có các phần lưới bất hợp pháp trong bố cục kiểu gạch) trở nên tồi tệ hơn. Chúng tôi không cho rằng đó là một giải pháp hay, đặc biệt là khi bạn có thể sử dụng tất cả các tính năng lưới mà mình muốn trong khi vẫn tách biệt rõ ràng những thứ khác nhau.
Nếu bạn có ý kiến phản hồi, hãy tham gia thảo luận trong Vấn đề 9041.
Cảm ơn Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick và Chris Harrelson đã xem xét bài đăng này và những cuộc thảo luận liên quan.