- WebKit đang kêu gọi phản hồi từ nhà thiết kế và nhà phát triển trong quá trình chuẩn hóa bố cục masonry/waterfall vốn từ lâu đã khó xử lý trong CSS vào CSS Grid Level 3
- Mô hình được đề xuất hoạt động trên
display: grid với grid-template-rows: masonry, tắt việc tạo hàng và để nội dung lấp đầy khoảng trống như các viên gạch
- Apple cho rằng tính năng này nên nằm trong Grid để có thể kết hợp với các khả năng Grid hiện có như
fr, minmax(), max-content, spanning, định vị tường minh và subgrid
- Cách tiếp cận
display: masonry riêng biệt có thể đơn giản hóa việc tách loại bố cục, nhưng trong thảo luận hiện nay có thể bị giới hạn quanh các cột cùng chiều rộng và khó tận dụng khả năng điều chỉnh kích thước track của Grid
- Sau bản cập nhật tháng 10/2024, CSS Working Group kết luận rằng track có độ rộng biến thiên, định vị tường minh, spanning và subgrid đều đáng để đưa vào masonry và cũng có thể triển khai với hiệu năng tốt, nhưng tranh luận về cú pháp vẫn tiếp diễn
Vị trí hiện tại của CSS Grid Level 3
- Sau bản cập nhật tháng 10/2024, bản Working Draft chính thức của W3C cho CSS Grid Layout Module Level 3 đã được tạo, trong đó cách hoạt động của bố cục masonry được ghi lại bằng tài liệu
- Các thành viên của CSS Working Group đi đến kết luận rằng những tính năng sau đáng để đưa vào bố cục masonry và có thể triển khai với hiệu năng tốt
- track có độ rộng biến thiên
- định vị tường minh
- spanning
subgrid
- Tuy vậy, tranh luận về cú pháp vẫn còn bỏ ngỏ, và WebKit tiếp tục chủ đề này trong bài riêng Help us choose the syntax for Masonry in CSS
Vì sao cần bố cục masonry
- CSS Grid Level 1 được giới thiệu vào năm 2017, giúp giảm gánh nặng về kích thước và sắp đặt của bố cục dựa trên float, còn Grid Level 2 cung cấp Subgrid
- Nhưng ngay cả sau khi CSS Grid ra đời, câu hỏi “viết bố cục masonry bằng CSS như thế nào” vẫn không có câu trả lời rõ ràng trong suốt 7 năm
- Bố cục masonry là kiểu sắp xếp trong đó nội dung được đặt đan khít như gạch hoặc tường đá, còn được gọi là waterfall layout
- Vì có thể xử lý nội dung với nhiều tỷ lệ khung hình khác nhau, nó giúp giảm nhu cầu phải cắt xén hoặc thu nhỏ mọi mục thành cùng một hình chữ nhật
- Nội dung được phân tán trên toàn bộ trang nên có thể giữ trật tự đọc tự nhiên khi cuộn, và khi thêm nội dung bằng lazy-load ở cuối trang cũng không cần dịch chuyển nội dung hiện có
Lịch sử đề xuất và tranh luận chuẩn hóa
- Cơ chế tạo bố cục masonry trong CSS lần đầu được Mozilla đề xuất vào tháng 1/2020 như một mở rộng của CSS Grid, và đã được triển khai thử nghiệm sau cờ tính năng trong Firefox Nightly
- Apple bắt đầu triển khai đề xuất CSS Grid Level 3 trong Safari Technology Preview từ năm 2022, và hiện được bật mặc định
- Trong CSS Working Group từng có bất đồng về hướng đi cơ bản
- một số người cho rằng masonry không nên là một phần của CSS Grid mà phải là một kiểu
display riêng
- một số khác chưa chắc bố cục này có thực sự cần cho web hay các website nổi tiếng có dùng hay không
- WebKit cho rằng để các trình duyệt phát hành tính năng này thì trước hết cần có đồng thuận của CSS Working Group
Cách dùng cơ bản: Grid chỉ dùng cột và tắt hàng
- Bố cục masonry/waterfall cổ điển có thể được viết bằng cách áp dụng
display: grid cho phần tử main, định nghĩa các cột rồi đặt giá trị masonry cho hướng hàng
main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1rem;
grid-template-rows: masonry;
}
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)) lặp lại các cột linh hoạt có chiều rộng tối thiểu 14rem
gap: 1rem tạo khoảng cách 1rem giữa các cột và các mục
grid-template-rows: masonry bảo trình duyệt đừng tạo hàng mà hãy điền nội dung theo mẫu masonry/waterfall
- Ví dụ này tạo ra một bố cục linh hoạt thích ứng với nhiều kích thước màn hình chỉ bằng bốn dòng CSS, không cần media query hay container query
- Hiện tại tên giá trị
masonry vẫn có thể thay đổi trước khi các trình duyệt phát hành chính thức
Vì sao muốn giữ khả năng định nghĩa cột của Grid
- Để chứng minh masonry nên là một phần của CSS Grid, WebKit đã tạo bốn demo và có thể thử trực tiếp tại webkit.org/demos/grid3
- Các demo có thể xem trên trình duyệt hỗ trợ Grid Level 3
- CSS Grid cung cấp nhiều lựa chọn khi định nghĩa cột
- kích thước cố định với nhiều đơn vị như
px, em, rem, cqi, lh, ch, ic, cap, vw, svh
max-content, min-content
- đơn vị
fr
minmax()
- kích thước
%
auto
- Ví dụ, có thể để cột đầu và cột cuối có chiều rộng cố định 14ch, còn các cột giữa là cột linh hoạt với tối thiểu 28ch
main {
display: grid;
grid-template-columns: 14ch repeat(auto-fill, minmax(28ch, 1fr)) 14ch;
grid-template-rows: masonry;
gap: 1rem;
}
- Kết hợp đơn vị
fr với minmax() cho phép tạo độ linh hoạt hai giai đoạn, nơi các cột nở ra và co lại ở những ngưỡng khác nhau
max-content và min-content giúp kích thước cột khớp với kích thước nội dung, mở ra kiểu bố trí khác với cách ép nội dung theo cột
- Cũng có thể tạo các cột có độ rộng khác nhau bằng dãy Fibonacci như
grid-template-columns: 1fr 1fr 2fr 3fr 5fr 8fr;
- Ví dụ mega menu dùng
grid-template-columns: repeat(auto-fill, minmax(max-content, 30ch)); để mỗi cột đủ rộng chứa văn bản liên kết mà không bị xuống dòng
- WebKit cho rằng thảo luận về
display: masonry riêng biệt hiện đang nghiêng về hướng chỉ cho phép các cột cùng kích thước như multicolumn layout ngày nay
Spanning, View Transitions, columnar grid
- CSS Grid cho phép các mục trải qua nhiều cột, nhờ đó bố cục masonry cũng có thể tạo ra nhiều cấu hình thị giác đa dạng
- Trong ví dụ, có thể cho mọi ảnh thứ 5 trải qua hai cột, còn các ảnh khác chỉ chiếm một cột
- Cũng có thể gán lớp
wider cho ảnh có tỷ lệ khung hình rộng hơn để chúng chiếm nhiều cột, hoặc biến thể bằng cách đổi góc thành vuông hay giảm khoảng cách về 0
- Demo Photos kết hợp với View Transitions để khi người dùng nhấp hoặc chạm vào ảnh, ảnh đó sẽ phóng to qua nhiều cột và trình duyệt tự động animate chuyển tiếp
- Demo này yêu cầu Safari Technology Preview 192 trở lên
- WebKit xem cốt lõi của Grid Level 3 không phải là mẫu cụ thể mang tên “masonry” mà là cơ chế tắt hàng
- Cách tiếp cận này tạo ra một columnar grid chỉ gồm cột, đối lập với modular grid của CSS Grid Level 1 vốn căn chỉnh cả hàng lẫn cột
Khác biệt giữa modular grid và columnar grid
- modular grid là kiểu Grid trong đó nội dung khớp theo cả cột và hàng, và CSS Grid Level 1 rất phù hợp cho loại bố trí này
- Bố cục dựa trên float cũng khuyến khích việc dùng modular grid trên web vì muốn float được dọn dẹp đúng thì chiều cao nội dung phải khớp nhau
- Trên các website thực tế, người ta thường làm cho ảnh có cùng tỷ lệ khung hình, làm độ dài văn bản tương đồng, hoặc ép nội dung vào các hộp giống nhau bằng chính sách CMS hay CSS cắt xén và ellipsis
- columnar grid cho phép giữ nguyên kích thước mong muốn của nội dung và để bố cục vận hành theo nội dung
- WebKit cho rằng ngay cả nội dung thiên về văn bản cũng có thể được sắp đặt sinh động hơn, chẳng hạn bài mới nhất chiếm bốn cột, một số bài gần đây chiếm hai cột, còn nội dung cũ hơn chỉ chiếm một cột
Kết hợp với Subgrid và định vị tường minh
- subgrid của CSS Grid Level 2 hiện đã được hỗ trợ trên hầu hết trình duyệt
- Ví dụ trang bảo tàng cho thấy thay vì liệt kê metadata của thẻ tranh trong một cột căn trái duy nhất, có thể dùng
subgrid để đặt năm và số catalog ở bên phải từng thẻ và căn hàng với cùng dữ liệu của các thẻ khác
- Nếu masonry đi vào CSS Grid Level 3 thì các công cụ dành cho nhà phát triển hiện có cũng tiếp tục dùng được nguyên trạng
- có thể thử
grid-template-rows: masonry bằng Grid Inspector trong Safari Technology Preview
- Nếu trở thành một kiểu display riêng thì sẽ không tận dụng được lợi ích của subgrid
- Cũng có thể dùng cùng với định vị tường minh của CSS Grid Level 1; trong ví dụ,
grid-column: -3 / -1 được dùng để đặt header ở góc trên bên phải trang, chiếm hai cột cuối
- WebKit cho rằng chỉ với vài dòng mã bố cục có thể kết hợp các tính năng của Grid Level 1, 2 và 3 để tạo bố cục thay đổi số cột theo không gian sẵn có mà không cần media query hay container query
Điểm tranh cãi với display: masonry
- WebKit và Apple xem Masonry là một tính năng mở rộng CSS Grid để không chỉ tạo modular grid mà còn tạo được columnar grid
- Theo hướng này, có thể dùng cùng các tính năng của Grid như định nghĩa cột, track spanning, định vị tường minh và
subgrid
- Bên ủng hộ kiểu display riêng cho rằng như vậy sẽ tách bạch loại bố cục rõ ràng hơn
display: block;
display: inline;
display: flexbox;
display: grid;
display: masonry;
- CSS Working Group vẫn chưa bàn xong cú pháp cho kiểu Masonry display riêng, nhưng WebKit đưa ra ví dụ về cú pháp giống Multicolumn layout hoặc cú pháp giống Grid nhưng bị giới hạn
main {
display: masonry;
columns: 28ch;
}
main {
display: masonry;
masonry-columns: repeat(5, minmax(28ch, 1fr));
/* where only one repeating width is allowed */
}
- Một loại bố cục riêng có thể tránh phần công việc cần thiết để tiếp tục làm cho Grid và Masonry hoạt động cùng nhau
- mô hình bố cục đơn giản hơn
- trình duyệt dễ triển khai hơn
- ít khả năng rơi vào bẫy hiệu năng hơn
- tập tính năng của Grid và Masonry có thể khác nhau
- Ngược lại, WebKit cho rằng nếu hai kiểu bố cục Grid này được gắn kết với nhau, CSS Working Group sẽ phải định nghĩa các tính năng tương lai cho cả modular grid lẫn columnar grid
- Ví dụ, nếu CSS Grid Level 4 bổ sung các tính năng như styling cho grid area và grid line, màu nền track, hay rule line của gap, thì tốt hơn là chúng hoạt động trên cả hai loại Grid ngay từ đầu
Nên hiểu “Grid” như thế nào
- Bên ủng hộ
display: masonry riêng cho rằng CSS Grid về bản chất là căn chỉnh hai chiều, còn masonry chỉ căn theo một hướng nên không phải Grid
- WebKit cho rằng trong lịch sử thiết kế đồ họa, grid là công cụ sắp xếp văn bản, hình ảnh và nội dung theo các mẫu có quy luật để hỗ trợ khả năng đọc và sử dụng
- Ngay cả trước khi các nhà hiện đại chủ nghĩa ở châu Âu và Mỹ thế kỷ 20 nhấn mạnh việc căn chỉnh cả cột và hàng như một graphic design grid “đúng chuẩn”, vẫn đã có nhiều loại grid khác nhau được sử dụng
- Mark Boulton cho rằng symmetric columnar grid quá hình thức và nhàm chán, đồng thời khuyến khích dùng asymmetrical compound grid trong web design
- CSS Grid Level 1 đã giúp tạo asymmetrical grid và compound grid dễ dàng, nhưng hiện điều đó chỉ đúng khi Grid đó là modular grid
- WebKit cho rằng cả modular grid lẫn columnar grid đều là grid, và CSS Grid cũng nên có khả năng tạo columnar grid
Lời kêu gọi phản hồi dành cho nhà phát triển và nhà thiết kế
- WebKit kêu gọi nhà phát triển và nhà thiết kế tự làm demo, viết ý kiến trên blog hoặc mạng xã hội, và để lại nhận xét trong các issue của CSS Working Group
- Những câu hỏi mà WebKit muốn nhận phản hồi gồm
- “masonry”/“waterfall” có nên là một phần của CSS Grid hay không
- có cần các khả năng columnar grid gồm
subgrid, spanning, định vị tường minh và nhiều kiểu track sizing khác nhau hay không
- chỉ cần bố cục masonry cổ điển với các cột cùng kích thước có đủ hay không
- có thực sự sẽ dùng tính năng này hay không, và có thể làm ra những gì
- có liên kết tới demo đã làm hay không
- có điều gì mô hình này không làm được hay không
- Nhóm WebKit đã làm việc về Masonry trong một năm rưỡi, và tính năng này được bật mặc định từ Safari Technology Preview 163 vào tháng 2/2023
- Họ muốn sớm phát hành tính năng, nhưng trước đó các chi tiết bao gồm cả tên gọi và những câu hỏi mang tính nền tảng cần được giải quyết
Tranh luận về tên gọi: masonry, waterfall, off
- WebKit cho rằng
masonry có lẽ không phải là tên tốt nhất cho giá trị mới này
- Tên trong CSS thường là những từ đơn giản mô tả trực tiếp kết quả như
center, contain, clip, wrap, smooth
masonry là một phép ẩn dụ cần giải thích nền tảng nên có thể khó nhớ với các nhà phát triển không dùng tiếng Anh
- Ở một số khu vực, bố cục này được gọi là
waterfall nhiều hơn, nên grid-template-rows: waterfall cũng có thể là một ứng viên
- WebKit xem tính năng này gần với cơ chế “hãy tạo Grid nhưng đừng tạo hàng” hơn là bản thân kiểu bố cục giống Pinterest
grid-template-rows: none; có thể hợp nghĩa, nhưng none đã là giá trị mặc định của grid-template-* với ý nghĩa “không có hàng tường minh, chỉ dùng hàng ngầm định”, nên không thể dùng
- Một phương án khác được đưa ra là
grid-template-rows: off;
main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
grid-template-rows: off;
}
- CSSWG đang thảo luận tên gọi tại issue này
- Hiện tại Safari Technology Preview và các demo đang dùng giá trị
masonry theo Editor’s Draft, nhưng tên đó có thể thay đổi trong tương lai
1 bình luận
Ý kiến trên Hacker News
Bối cảnh là những người phụ trách quan hệ nhà phát triển của CSSWG từ các hãng trình duyệt đã thảo luận về cách chính thức đưa bố cục Masonry vào CSS. Cuộc thảo luận này đã kéo dài ít nhất từ năm 2020, khi Firefox lần đầu đề xuất
Điểm đáng chú ý lần này là phía WebKit đã đưa cuộc thảo luận này ra công khai và kêu gọi nhà thiết kế cũng như nhà phát triển hành động theo kiểu “đăng lên mạng xã hội, viết bài blog”
Nhìn bề ngoài, việc này có thể trông như một thủ tục mang tính hình thức, nhưng nó có thể trở thành một tiền lệ quan trọng. Vấn đề cốt lõi là nên xử lý mọi tùy chọn bố cục như một phần của CSS Grid, hay tiếp tục bổ sung các thuộc tính CSS Display mới mỗi khi cần
Cách thứ nhất sẽ làm đặc tả CSS Grid vốn đã phức tạp trở nên phức tạp hơn, còn cách thứ hai có thể làm đặc tả CSS phình to với các thuộc tính và thuộc tính con mới. Dù chọn bên nào thì cũng không dễ như vẻ ngoài
Grid trước hết đặt tất cả mục vào lưới, chẳng hạn như đặt ở
col:2,row:3, rồi sau đó mới xác định kích thước lưới. Masonry, lý tưởng mà nói, muốn xác định kích thước track trước rồi mới đặt các mục vào các track đóBản triển khai đầu tiên của Firefox và đặc tả khi đó về cơ bản nói rằng, ngoại trừ hàng đầu tiên và một vài quy tắc phức tạp, các mục Masonry không được tính đến khi tính kích thước track, nên rất dễ xảy ra việc mục làm tràn track
Đặc tả hiện tại yêu cầu thử đặt mọi mục vào mọi track có thể. Trong trường hợp xấu nhất, mà cũng khá phổ biến, sẽ có hiệu năng bậc hai O(N_tracks * N_items), và hiệu năng bậc hai là tệ[1]; hầu như không có thuật toán bố cục nào khác như vậy
Nếu thêm cả lồng nhau, hiệu năng sẽ xấu đi theo kiểu gần hàm mũ, và CPU nhanh cũng không tốt. Có thể nói những trường hợp như vậy không phổ biến, nhưng trong các chế độ bố cục CSS, mọi người luôn thử các ranh giới, nên mặc định nó phải nhanh
Trong Grid, một mục có thể tự xác định kích thước khác nhau tùy theo nó được đặt vào track nào, nên cần thử đặt nó ở mọi vị trí có thể. Để giảm nhẹ vấn đề này, Masonry có thể cần một thuật toán khác cho việc tính kích thước track, nhưng bài blog không bàn đủ về điểm này. Có thể từng tồn tại một phiên bản tính kích thước Grid không phụ thuộc vào vị trí mục, nhưng con thuyền đó đã rời bến rồi
[1] https://randomascii.wordpress.com/2019/12/08/on2-again-now-i...
Nhìn chung, chỉ cần dùng
grid-row-template: masonrylà phần còn lại vẫn hoạt động tốt. Đây là điểm hay, và tôi không nghĩ nó khiến bố cục Grid khó dùng hơn hiện nayNhược điểm chủ yếu nằm ở phía những người viết engine trình duyệt. Lý do là tiêu chuẩn để được xem là “hỗ trợ CSS Grid đầy đủ” sẽ cao hơn. Ngoài ra, họ nói rằng cũng có thể tránh được các bẫy hiệu năng khiến một triển khai phải hỗ trợ mọi tính năng của Grid trở nên chậm hơn trong một số bố cục Grid so với khi đặc tả còn đơn giản hơn
Nếu có một chế độ display riêng, sẽ phải lặp lại đặc tả
grid-columncho bố cục Masonry, và như vậy thì đáng tiếcKhông liên quan trực tiếp đến CSS Masonry, nhưng gần đây tôi đã tạo nguyên mẫu vòng lặp thứ hai của một giao diện có sự căng thẳng tương tự. Vấn đề là nên tăng thêm các kiểu tương tự nhưng khác nhau trong mô hình dữ liệu, hay tăng thêm các sắc thái chi tiết trong kiểu hiện có để hỗ trợ tinh chỉnh
Lúc bắt đầu, tôi rất nghiêng về phương án sau, nhưng khi thực sự khám phá các lựa chọn, hóa ra việc tiêu thụ một giao diện “phình to” rồi suy luận mã ứng dụng từ kết quả đó lại đơn giản hơn nhiều
Tôi không có lập trường mạnh về CSS Masonry, nhưng có thể cũng sẽ có một bất ngờ tương tự giữa sự căng thẳng mà mọi người nghĩ theo trực giác và cảm giác khi sử dụng thực tế. Riêng với CSS, chắc chắn khó biện minh cho việc “phình to”, tức là tăng thêm ngữ nghĩa theo từng trường hợp sử dụng, nhưng người dùng cũng có thể có xu hướng thấy các API đậm đặc như Grid khó hơn
Tôi đã thử nghiệm trên Firefox và Safari từ năm ngoái và không có phàn nàn gì về triển khai. Có người càu nhàu về vị trí và tên thuộc tính, nhưng cần thừa nhận rằng có lẽ không có lời giải hoàn hảo và nên triển khai theo hướng thực dụng
Tôi từ chối dùng JavaScript làm triển khai thay thế. Vì vậy phương án thay thế có rất nhiều CSS xấu xí không sắp thứ tự đúng được, nhưng với dự án tôi đang làm thì không phải vấn đề lớn. Hiện tại phần lớn sẽ thay thế bằng JavaScript, nhưng nếu lời giải cho bố cục lại là JavaScript thì ngay từ đầu đã ở thế thua rồi
Tôi thật sự không thích bản demo mega menu <https://webkit.org/demos/grid3/megamenu/>, và việc dùng Masonry ở đó trông hoàn toàn không phù hợp. Nó làm rối hướng luồng và phá vỡ kỳ vọng một cách nghiêm trọng
Thứ tự đọc được mong đợi: https://temp.chrismorgan.info/2024-04-23-masonry-megamenu-2....
Thứ tự mà demo thực tế đưa ra: https://temp.chrismorgan.info/2024-04-23-masonry-megamenu-1..... Điều này ảnh hưởng đến thứ tự đọc đúng và tab index. Người dùng thị giác trên thực tế hầu như luôn đọc theo thứ tự “sai”
Rốt cuộc, nó cho thấy đây chỉ là một túi liên kết phi cấu trúc, không có cấu trúc gì cả. Nhưng nếu đi theo thứ tự số thì trông như thể đã có một thứ tự khá logic, rồi bị phá hỏng hoàn toàn vì bị áp Masonry không phù hợp
Trong ảnh chụp màn hình tôi đã bật “hiển thị số thứ tự mục”. Bình thường nó trông như các cột thông thường không có nền
Cách triển khai lẽ ra nên dùng cột và thêm
break-inside: avoidcho từng section. Demo đã bỏ sót điều nàyDemo báo chí cũng hơi đáng ngờ vì lý do tương tự, nhưng vấn đề nhỏ hơn nhiều
Với những khối độc lập hơn như phương tiện hình ảnh, nơi thứ tự đọc không ăn sâu đến vậy, bố cục Masonry phù hợp hơn. Dù vẫn có vài điểm hơi mơ hồ quanh tab index, nó không còn rõ ràng là sai nữa
Kỳ vọng của người dùng thị giác trong bố cục Masonry là sự tiếp nối theo các hàng trực quan, chứ không phải có tính liên tục giữa các cột. Thứ tự mà bạn nêu là “ngoài dự kiến” cũng đang đi theo điều đó
Vấn đề có vẻ nằm ở chỗ thứ tự tab bỏ qua thứ tự nội dung gốc và cố bắt chước phần thị giác, và gần như chắc chắn đó là dấu vết còn sót lại từ cách triển khai hiện tại
Điểm hay của tính năng này là khi xem demo trên các trình duyệt không hỗ trợ, tức là tất cả trình duyệt stable hiện nay nếu không bật flag đặc biệt, nó vẫn hiển thị dưới dạng hàng cố định khá hợp lý vì được xây trực tiếp trên Grid layout: https://webkit.org/demos/grid3/
Trong từng trường hợp, nếu là bố cục Masonry đúng nghĩa thì nhìn sẽ đẹp hơn nhiều, nhưng ngay cả khi không phải vậy thì vẫn đủ dùng. Nếu không thích, cũng có thể dùng feature detection để cung cấp phương án hiển thị thay thế tốt hơn
Tôi rất thích tổng thể hình dáng và cảm giác của bố cục Masonry/dạng thác nước. Có lẽ vì tôi lớn lên cùng báo giấy và đến giờ vẫn đọc, nên bố cục dựa trên cột tạo cảm giác như một cách trực quan để chia trang
Tuy nhiên tôi muốn có lựa chọn thay thế cho cách căn Masonry mặc định. Theo tôi biết, quy tắc cơ bản là “đặt mục tiếp theo vào cột mà nó có thể nằm cao nhất”, và vì vậy từ hàng thứ hai trở đi, thứ tự trái phải bị xáo trộn đáng kể
Cách tốt hơn mà tôi hình dung là một bố cục bảo toàn nhiều hơn luồng đọc trái→phải, hoặc nếu hướng ưu tiên là phải→trái thì theo hướng đó. Ví dụ như “mục tiếp theo đặt vào cột bên phải của mục trước; nếu đã ở ngoài cùng bên phải thì đưa về ngoài cùng bên trái; và nếu đáy mới không thấp hơn quá nhiều so với ranh dưới của cột bên trái thì có thể đặt mục thứ hai vào cùng cột”
Nó linh hoạt hơn so với trái→phải nghiêm ngặt nên cũng ít làm hỏng căn chỉnh hơn, đồng thời vẫn giữ được phần nào ý nghĩa của hướng đọc trái→phải
Masonry không thể bao quát mọi công thức mà người ta có thể ưu tiên, nhưng với nội dung mà thứ tự có dù chỉ một chút quan trọng, chẳng hạn như tạp chí dù có thể không phải Pinterest, tôi cho rằng cách này là mặc định hợp lý hơn so với quy tắc Masonry cổ điển
Nếu là bố cục kiểu tạp chí, chẳng phải ta đọc cột từ trên→dưới trước rồi sau đó mới từ trái→phải sao? Trong CSS, điều này đã có thể làm bằng
columnshoặc Flexbox hướng dọcMột vấn đề khác của bố cục Masonry này là phần đáy lởm chởm. Nếu là tạp chí thì có lẽ người ta sẽ căn đều, và điều này cũng có thể làm bằng cột hoặc Flexbox
Trên web dường như có một giả định ngầm rằng nội dung cuộn vô tận nên hình dạng ở cuối trang không quan trọng. Nếu vậy thì đó không hẳn là một giả định đáng khuyến khích
{ /* khi cập nhật, chỉ di chuyển phần tử sang trái hoặc phải tối đa 2 cột */ grid-template-max-horizontal-shift: 2 col; }Nếu giả sử có thể tạo ra một hệ thống không tương thích ngược để thay thế CSS thì nên làm thế nào?
Có cuốn sách hay bài nghiên cứu nào về cách tạo ra một hệ thống layout nhất quán không?
Các phương án thay thế như Qt, Tk, SwiftUI thì sao? Ngoài CSS ra thì tôi chưa từng dùng cái nào. Nếu trong các hệ thống đã được triển khai rộng rãi thực sự có cái tốt hơn, thì điều gì khiến nó tốt hơn?
Tôi muốn một hệ thống mang lại giao diện tốt hơn cho lập trình viên, nhưng không biết nên làm thế nào. Nếu có thể bắt đầu lại từ đầu, các nguyên tắc thiết kế nên là gì?
Thuộc tính nên tường minh và tách bạch hơn. Loại bỏ những trò vô lý như margin âm, và mọi khoảng cách nên được tạo thành nhiều cấp. Ví dụ như
padding = max(el.paddings[])Hộp biên nên được làm tường minh, còn đường viền nên trở thành một phần tử đúng nghĩa. Bản thân box model không tệ; CSS mới là thứ triển khai nó một cách khủng khiếp. Nó đầy những bùa chú mong manh mà cứ đụng vào là 99% sẽ vỡ, cùng các giới hạn phi lý, và chính những giới hạn đó lại sinh ra thêm nhiều vấn đề và “giải pháp”
Cách này được thiết kế để giải quyết sự thay đổi về kích thước và hình dạng màn hình. Apple đã chuyển sang SwiftUI và có thể đã rời khỏi cách tiếp cận này
Flutter và XAML cũng có vẻ đáng để xem xét
Đăng lại thành bình luận cấp cao nhất để dễ thấy hơn
Tôi có một website ảnh và không dùng JavaScript cho layout. Khi xây dựng, tôi đã xem xét các thư viện JavaScript Masonry nhưng kết quả không làm tôi hài lòng
Một layout Masonry đúng nghĩa, thực sự lấp đầy mọi không gian khả dụng, sẽ cắt bớt một số ảnh. Nếu muốn giữ tỷ lệ khung hình mà không cắt, phải để lại khoảng trống quanh ảnh. Cách duy nhất để không làm vậy là cuộn vô hạn, và có lẽ đó là điều các cỗ máy gây nghiện kiểu doanh nghiệp muốn, nhưng không phải điều tôi muốn trên website của mình
Tôi đã làm như thế này:
https://yakubin.com/photography/albumless/
https://yakubin.com/photography/album/kenya-2023/
Để đạt được kết quả này, tôi dùng
display:inline-block, về cơ bản coi ảnh như văn bản cần được reflow sang dòng mới. Tôi rất hài lòng với kết quả và thích cách này hơn cách mà các thư viện Masonry làmVấn đề là thứ tự. Nếu thứ tự không quan trọng thì các giải pháp chỉ dùng CSS hiện nay cũng hoạt động tốt. Tuy nhiên, nếu nhớ không nhầm thì phần dưới các cột có thể để lại hình dạng kỳ lạ
Liên quan đến chủ đề này, tôi đã làm một demo tương tác về các nguyên lý Grid:
https://cssprinciples.com/3/grid/
Đã có float truyền thống, lại có cả các layout hiện đại như Flexbox và Grid, nên cũng thắc mắc liệu có đúng khi cứ tiếp tục thêm các tùy chọn “layout” vào CSS hay không
Nếu vẫn còn những trường hợp chưa được bao quát, có thể một giải pháp tốt hơn là có một hệ thống dựa trên ràng buộc cuối cùng, dù phức tạp hơn, bao quát mọi trường hợp layout. Khi đó các framework CSS và thư viện tiện ích có thể xây dựng Masonry Grid thế hệ tiếp theo, v.v. trên nền tảng đó
Dù vậy, đề xuất Houdini layout là thứ gần nhất với ý tưởng này. Đó là cách chuyển layout sang một ngữ cảnh JavaScript được cô lập: https://github.com/w3c/css-houdini-drafts/blob/main/css-layo...
Nhưng nói thật, vì Flexbox, Grid và những thứ như containment đã giải quyết rất nhiều vấn đề, nên nhu cầu cải tiến đã giảm đi nhiều so với thời trước Flexbox
display: grid;grid-template-rows: masonry;Tuy nhiên nó bị giới hạn ở WebKit. Tôi từng triển khai trong chế độ gallery của news feed cá nhân, rồi đã bỏ từ tháng 10/2023
Một hệ thống dựa trên ràng buộc có vẻ sẽ nằm lưng chừng một cách gượng gạo giữa Grid và JavaScript, nên tôi không rõ nó có giúp được nhiều không
Tôi đã dùng cái này rồi. Trên Firefox thì bật trong tùy chọn và dùng cho bookmark. Trên mobile thì không thành vấn đề vì đơn giản là chúng xếp chồng từ trên xuống dưới. Trên mobile không có
about:configẢnh cuối là trạng thái đã tắt
https://imgur.com/a/o7OyZEW
Vì vậy khi thay đổi kích thước cửa sổ, thứ tự bookmark sẽ thay đổi
Có thể xem thêm nhiều bối cảnh hơn và lập luận phía đối lập, tức vì sao
display: masonrytốt hơndisplay:grid+grid-template-rows: masonry, tại đây: https://github.com/w3c/csswg-drafts/issues/9041