Từng viên gạch: Giúp chúng tôi xây dựng CSS Masonry

Patrick Brosset
Patrick Brosset
Alison Maher
Alison Maher

Xuất bản: Ngày 23 tháng 7 năm 2025

Nhóm Microsoft Edge và Google Chrome rất vui mừng thông báo rằng CSS masonry đã sẵn sàng để nhà phát triển thử nghiệm sớm từ Chrome và Edge 140.

Vì vẫn còn những vấn đề chưa được giải quyết xung quanh cú pháp và quy cách của bố cục dạng khối CSS, nên ý kiến phản hồi của bạn là rất quan trọng để giúp chúng tôi hoàn thiện hình dạng cuối cùng của API. Hãy dùng thử tính năng này và cho chúng tôi biết ý kiến của bạn.

Hãy thử nghiệm CSS Masonry trong Chromium ngay hôm nay

Cách dùng thử CSS Masonry ngay hôm nay:

  1. Sử dụng Chrome hoặc Edge 140 trở lên (hoặc một trình duyệt khác dựa trên Chromium có phiên bản tương ứng).
  2. Chuyển đến about:flags trong một thẻ mới.
  3. Tìm kiếm "CSS Masonry Layout" (Bố cục kiểu Masonry bằng CSS).
  4. Bật cờ.
  5. Khởi động lại trình duyệt.
Mục nhập cho Masonry trên trang thử nghiệm.

Khi bật tính năng này, bạn có thể xem tính năng này hoạt động bằng cách xem các bản minh hoạ của Microsoft Edge (xem mã nguồn của bản minh hoạ) hoặc tiếp tục đọc để tìm hiểu thêm về tính năng này và cú pháp có sẵn.

Masonry là gì?

CSS masonry là một chế độ bố cục cho phép bạn tạo cách sắp xếp các mục giống như viên gạch, theo cách mà bạn khó có thể đạt được bằng lưới CSS, flexbox hoặc bố cục nhiều cột.

Bạn có thể dùng CSS masonry để sắp xếp các mục theo định dạng cột hoặc hàng, trong đó các mục được đặt trong những cột hoặc hàng đó theo cách thu gọn.

Các mục được sắp xếp trong bố cục kiểu xếp gạch.

Hãy coi bố cục dạng khối xây là một đường cao tốc, trong đó hạn chế duy nhất là số lượng và kích thước của các làn đường lái xe khác nhau. Trong các làn đường, xe có thể đi bất kỳ đoạn đường nào mà chúng muốn và luôn cố gắng đi đến gần đích đến nhất có thể, đó là điểm bắt đầu của bố cục kiểu xếp gạch.

Bản minh hoạ sử dụng các phương tiện xếp hàng theo làn đường để minh hoạ bố cục.

Các mục trong bố cục của bạn chỉ bị hạn chế theo một hướng và có thể tự do thay đổi kích thước theo hướng còn lại, bất kể các mục khác ở gần. masonry khác với grid ở chỗ các đường kẻ của nó chỉ được xác định theo một hướng.

Trong bố cục dạng khối, thứ tự hiển thị của các mục ít quan trọng hơn so với thiết kế cuối cùng. Lưới kiểu khối xây cho phép bạn tận dụng tối đa không gian có sẵn, bất kể bạn có mặt hàng nào. Điều này khiến đây là lựa chọn phù hợp cho những trang có nhiều hình ảnh và nơi thứ tự hiển thị nội dung không quan trọng bằng kết quả cuối cùng.

Một khía cạnh thú vị của bố cục dạng khối là nó cũng cho phép các mục trải rộng trên nhiều đường, giống như với lưới. Khi đó, các mục sẽ tiếp tục được đặt theo cách lấp đầy nhiều không gian có sẵn nhất có thể.

Hình ảnh có xe, lần này là xe lớn trải dài trên 2 cột.

Hành vi tự động đặt này có thể mang lại kết quả rất thú vị mà các nhà thiết kế web đã cố gắng đạt được trong một thời gian dài. Ví dụ: hãy xem bản minh hoạ thư viện ảnh Thành phố New York. Bản minh hoạ này cho thấy cách hiển thị ảnh theo cách nhỏ gọn dọc theo nhiều cột, đồng thời cho phép một số mục (tiêu đề trong ví dụ này) trải dài trên nhiều cột:

Một thư viện nơi tiêu đề trải dài trên các cột.

Sau đây là một số ví dụ khác về những trường hợp có thể sử dụng bố cục dạng khối.

Bố cục blog, cho thấy hình thu nhỏ và nội dung mô tả của từng bài đăng.

Một trang web tin tức sử dụng bố cục dạng khối cho thẻ bài viết.
Xem bản minh hoạ blog tại đây.

Một trang web tin tức, trong đó các bài viết xuất hiện theo cột, một số bài viết có chiều rộng lớn hơn các bài viết khác và hình ảnh chính trải rộng toàn bộ chiều rộng của trang.

Một trang web tin tức có một số bài viết trải dài trên nhiều cột.
Xem bản minh hoạ trang web tin tức tại đây.

Một bộ sưu tập ảnh, với nhiều kích thước cột và một số bức ảnh trải dài trên nhiều cột.

Bố cục dạng khối của một trang web nhiếp ảnh.
Xem bản minh hoạ về thiên nhiên tại đây.

Giải pháp thay thế và các hạn chế của giải pháp

Để triển khai mẫu thiết kế này trên web hiện nay, bạn phải sử dụng thư viện JavaScript hoặc giải pháp thay thế sử dụng lưới CSS, flexbox hoặc nhiều cột. Tuy nhiên, việc này có thể gây ra một số nhược điểm, chẳng hạn như:

  • Hiệu suất kém hơn: Việc dựa vào các thư viện JavaScript hoặc mã tuỳ chỉnh để mô phỏng bố cục dạng khối CSS sẽ đi kèm với những hạn chế về hiệu suất, có thể dẫn đến trải nghiệm tiêu cực cho người dùng.
  • Độ phức tạp của mã cao hơn:
    • Rất khó để đảm bảo vị trí chính xác của các mục và phân phối không gian trong lưới CSS, flexbox hoặc nhiều cột để mô phỏng bố cục kiểu xếp gạch CSS.
    • Việc xử lý các tính năng cụ thể như các mục trải dài trên nhiều cột hoặc hàng, thứ tự tuỳ chỉnh của các mục hoặc điều chỉnh theo khung hiển thị cũng có thể dẫn đến sự phức tạp và hạn chế.
  • Gánh nặng bảo trì lớn hơn: mã CSS hoặc JavaScript tuỳ chỉnh phức tạp sẽ khó duy trì hơn.

Lưới CSS là một chế độ bố cục tuyệt vời, rất linh hoạt và cho phép bạn tạo nhiều kiểu bố cục khác nhau, cho dù là cho toàn bộ trang web, thành phần hay chỉ để căn chỉnh các mục riêng lẻ. Tuy nhiên, nó không có các đặc điểm giống như kiểu xếp gạch.

Trong lưới CSS, các hàng và cột được xác định một cách cứng nhắc và các mục chỉ có thể tồn tại trong các ô lưới. Nếu đang cố gắng đóng gói các mục dọc theo một trong các trục, nhưng các mục không có kích thước phù hợp với các ô tương ứng, bạn sẽ phải chọn giữa việc để lại khoảng trống giữa các mục hoặc kéo dài chúng để lấp đầy khoảng trống.

Lưới đặt các mục vào các đường cố định.

Giống như masonry, flexbox chỉ quan tâm đến một hướng và cho phép các mục quyết định khoảng trống mà chúng muốn chiếm theo hướng khác. Điều này có nghĩa là bạn có thể nhận được một bố cục trông giống như bố cục kiểu xếp gạch bằng cách sử dụng flexbox, miễn là bạn hài lòng với việc các mục được bố trí theo hướng khối, mỗi lần một cột. Vùng chứa linh hoạt cũng sẽ cần có chiều cao hoặc kích thước khối được xác định để các mục chuyển sang dòng linh hoạt mới, do đó tạo ra một cột mới.

Bố cục linh hoạt sắp xếp các mục theo cột.

Bố cục nhiều cột cũng có thể tạo ra một bố cục trông giống như bố cục kiểu khối xây, sắp xếp các mục trong cột. Ngoài ra, bố cục nhiều cột không cho phép bạn thay đổi kích thước từng cột theo cách khác nhau. Tất cả đều có cùng kích thước, trong khi bố cục dạng khối mang lại nhiều tính linh hoạt khi xác định các rãnh mà các mục được đóng gói bên trong.

Điều cần nhớ ở đây không phải là bố cục lưới, flexbox hoặc nhiều cột tệ hơn bố cục kiểu khối xây. Đây là những loại bố cục tuyệt vời và có nhiều trường hợp sử dụng. Vấn đề là: nếu bạn muốn có bố cục kiểu xếp gạch, thì CSS kiểu xếp gạch sẽ cung cấp cho bạn bố cục đó.

Trạng thái của bố cục dạng lưới CSS

Nhóm công tác CSS đang soạn thảo masonry trong quy cách CSS Grid Level 3. Quy cách này vẫn đang được xây dựng và tạm thời bao gồm 2 cú pháp được đề xuất khác nhau. Cách đầu tiên sử dụng một từ khoá mới cho thuộc tính display, trong khi cách thứ hai tích hợp trực tiếp masonry vào bố cục lưới CSS.

Sử dụng display: masonry

Cú pháp này giới thiệu CSS masonry dưới dạng loại display riêng. Bạn có thể xem thêm thông tin chi tiết về phương pháp này và động lực của phương pháp này trong bài đăng trên blog Cần có ý kiến phản hồi: Chúng ta nên xác định bố cục dạng khối CSS như thế nào? của nhóm Google Chrome, cũng như trong phần còn lại của bài đăng này. Nguyên mẫu hiện tại trong Chromium dựa trên đề xuất này.

display: grid; grid-template-*: masonry;

Trong cú pháp này, bố cục dạng khối CSS được tích hợp trực tiếp vào lưới CSS. Chế độ bố cục dạng lưới được kích hoạt bằng cách áp dụng từ khoá masonry cho định nghĩa grid-template-columns trong trường hợp bố cục dạng lưới dựa trên hàng hoặc cho định nghĩa grid-template-rows trong trường hợp bố cục dạng lưới dựa trên cột.

Bạn có thể xem thêm thông tin chi tiết về đề xuất này và lý do đưa ra đề xuất trong bài đăng Giúp chúng tôi chọn cú pháp cuối cùng cho Masonry trong CSS trên WebKit.

Xin lưu ý rằng một lựa chọn thay thế cho đề xuất này là thuộc tính item-pack và từ khoá collapse. Lựa chọn này sẽ kích hoạt bố cục dạng khối CSS thay vì sử dụng một trong hai thuộc tính mẫu lưới.

Kể từ khi các nhóm Chrome và WebKit xuất bản bài đăng, CSSWG đã tiếp tục thảo luận về cú pháp tổng thể để tiến hành. Ý kiến phản hồi của bạn có thể giúp chúng tôi phát triển thêm trong các diễn đàn này.

Để biết thêm thông tin chi tiết về trạng thái hiện tại của các cuộc thảo luận, hãy xem vấn đề 11593, trong đó nêu ra bộ chủ đề thảo luận hiện tại về cú pháp bố cục dạng lưới và vấn đề 11243 để biết nội dung tóm tắt về cuộc tranh luận về cú pháp cho đến nay.

Tạo bố cục kiểu xếp gạch CSS của riêng bạn

Hãy cùng tạo một bố cục kiểu khối xây bằng CSS.

Mặc dù cú pháp cho bố cục dạng khối CSS vẫn đang được thảo luận, nhưng bạn có thể thử nghiệm việc triển khai tính năng này trong Chromium ngay hôm nay bằng cách bật cờ Bố cục dạng khối CSS như được giải thích trong bài viết Thử nghiệm bố cục dạng khối CSS ngay hôm nay. Các ví dụ sau đây minh hoạ những tính năng có trong bản dùng thử dành cho nhà phát triển.

Tạo vùng chứa kiểu xếp gạch

Để tạo vùng chứa kiểu xếp gạch dựa trên cột đầu tiên, hãy dùng display:masonry và xác định kích thước cột bằng cách dùng grid-template-columns. Vì masonry-direction mặc định là column, nên bạn không bắt buộc phải đặt thuộc tính này.

.masonry {
  display: masonry;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}
Bố cục dạng khối nơi tất cả các cột đều có cùng kích thước.
Xem bản minh hoạ các cột có cùng kích thước tại đây

Thay vào đó, đối với một vùng chứa kiểu xếp gạch dựa trên hàng, hãy sử dụng display:masonry, xác định kích thước hàng bằng grid-template-rows, rồi đặt masonry-direction:row.

.masonry {
 display: masonry;
 masonry-direction: row;
 grid-template-rows: repeat(auto-fit, minmax(160px, 1fr));
 gap: 10px;
}
Bố cục dạng khối xây nơi tất cả các hàng đều có cùng kích thước.
Xem bản minh hoạ các hàng có cùng kích thước tại đây

Như bạn có thể nhận thấy, cú pháp này hơi khác so với đề xuất ban đầu của Google. Bất kể bạn dùng trình kích hoạt nào cho CSS Masonry, Nhóm công tác CSS đã quyết định sử dụng lại các thuộc tính kích thước và vị trí của mẫu lưới trong bố cục CSS Masonry.

Mặc dù điều này cho phép sử dụng lại nhiều thuộc tính hơn giữa các loại bố cục, nhưng bạn có thể thấy khó hiểu. Chúng tôi rất mong nhận được ý kiến của bạn về vấn đề này. Chúng tôi có thể xem xét việc tạo các bí danh chung hơn cho các thuộc tính như grid-template-columnsgrid-template-rows, chẳng hạn như template-columns hoặc template-rows. Các bí danh này có thể dùng cho cả lưới và bố cục dạng khối.

Sử dụng kích thước đường đua mặc định

Với một loại màn hình mới, bạn có cơ hội suy nghĩ lại về các giá trị mặc định của thuộc tính.

Trong lưới, grid-template-columnsgrid-template-rows mặc định là none. Theo định nghĩa hiện tại, điều này thường dẫn đến một cột hoặc hàng duy nhất. Đối với bố cục dạng khối, chế độ mặc định này thường dẫn đến bố cục không mong muốn.

Việc triển khai trong Chromium sẽ thêm định nghĩa đề xuất mới cho none, định nghĩa này sẽ thay thế kích thước của các thành phần mặc định trong bố cục dạng khối CSS. Kích thước mặc định mới của đường chạy là giá trị repeat(auto-fill, auto). Giá trị này tạo ra một bố cục dạng khối đẹp mà không cần xác định kích thước của các phần tử:

.masonry {
  display: masonry;
  gap: 10px;
}
Bố cục kiểu khối xây với các cột có kích thước tự động.
Xem bản minh hoạ kích thước đường đua mặc định tại đây

Như trong hình minh hoạ, vùng chứa kiểu xếp gạch sẽ tạo nhiều cột có kích thước tự động nhất có thể để vừa với không gian có sẵn.

Với lưới CSS, tất cả các mục đều được đặt trước khi các đường kẻ được định cỡ, tức là bạn không thể sử dụng định nghĩa tự động định cỡ đường kẻ này. Tuy nhiên, với bố cục dạng lưới CSS, quy định hạn chế này không còn áp dụng nữa, vì việc đặt và định cỡ được kết hợp và đơn giản hoá. Khi quy định hạn chế này được dỡ bỏ, chúng tôi có thể cung cấp kích thước mặc định của một bản nhạc hữu ích hơn cho bố cục dạng khối.

Hãy thử thuộc tính viết tắt masonry

Như đã đề cập trước đó, việc triển khai hiện tại trong Chromium dựa vào các thuộc tính grid-template-* để xác định rãnh kiểu xếp gạch trong bố cục của bạn. Tuy nhiên, vì bố cục kiểu xếp gạch chỉ có một phương diện, nên chúng tôi cũng đã triển khai thuộc tính viết tắt masonry. Bạn có thể dùng thuộc tính này để xác định cả hướng của bố cục kiểu xếp gạch và định nghĩa về đường kẻ cùng một lúc mà không cần thuộc tính có tiền tố grid- gây nhầm lẫn.

Ví dụ: 2 đoạn mã sau đây sẽ tạo các vùng chứa tương đương trong bố cục dạng khối CSS.

.masonry {
 display: masonry;
 masonry: "a a b" 50px 100px 200px row;
}

.masonry {
  display: masonry;
  masonry-direction: row;
  grid-template-rows: 50px 100px 200px;
  grid-template-areas: "a" "a" "b"
}
Bố cục dạng lưới có 3 hàng tăng dần kích thước.
Xem bản minh hoạ về cú pháp rút gọn của bố cục dạng lưới tại đây

Chữ viết tắt masonry vẫn đang được Nhóm công tác CSS thảo luận. Hãy dùng thử ngay hôm nay và cho chúng tôi biết ý kiến của bạn.

Sử dụng kích thước đường lưới tuỳ chỉnh

Khi xác định kích thước của các đường kẻ, bố cục kiểu xếp gạch linh hoạt như lưới trong việc cho phép bạn điều chỉnh số lượng và kích thước của các đường kẻ bố cục. Các khối trong bố cục dạng lưới không nhất thiết phải có cùng kích thước, ví dụ:

.masonry {
 display: masonry;
 masonry: repeat(2, 3rem) repeat(auto-fit, 5rem) 12rem;
}
Bố cục dạng khối xây với nhiều kích thước rãnh khác nhau.
Xem bản minh hoạ về kích thước đường lưới tuỳ chỉnh tại đây

Trong ví dụ này, chúng ta sẽ xác định 2 đường 3rem đầu tiên, theo sau là một số lượng đường 5rem thay đổi, theo sau là một đường 12rem duy nhất.

Trải rộng trên nhiều kênh

Trong bố cục dạng khối, các mục không nhất thiết phải bị giới hạn trong các đường dẫn mà chúng được đặt vào vì chúng có thể trải rộng trên nhiều đường dẫn nếu cần. Điều này có thể rất hữu ích khi một số mục quan trọng hơn các mục khác và cần nhiều không gian hơn.

Ví dụ:

.masonry {
  display: masonry;
  masonry: repeat(auto-fill, minmax(12rem, 1fr));
}

.important-item {
  grid-column: span 2;
}
Bố cục dạng khối với các mục trải rộng trên nhiều đường.
Xem bản minh hoạ về tính năng trải rộng trên nhiều kênh tại đây

Bạn cũng có thể dùng tính năng này để trải rộng nhiều bản nhạc nhằm tạo ra một số mục có độ dài bằng toàn bộ vùng chứa:

.masonry {
 display: masonry;
 masonry: repeat(auto-fill, minmax(12rem, 1fr));
}

.full-bleed {
 grid-column: 1 / -1;
}

Đây là những gì bản minh hoạ trang tin tức sử dụng để hiển thị quảng cáo dựa trên lượt đăng ký trong các bài viết.

Bố cục trang web tin tức có một biểu ngữ trải rộng trên toàn bộ khu vực.

Tinh chỉnh vị trí đặt các mục trong bố cục dạng lưới

Trong CSS Masonry, các mục được đặt trong cột hoặc hàng có vị trí chạy ngắn nhất.

Hãy tưởng tượng một vùng chứa kiểu xếp gạch có hai cột. Nếu vùng chứa có một mục cao 110 px ở cột đầu tiên và một mục cao 100 px ở cột thứ hai, thì mục thứ ba sẽ được đặt ở cột thứ hai, nơi mục này sẽ gần với điểm bắt đầu của hướng bố cục dạng lưới 10 px.

Bố cục dạng lưới có hai cột.

Nếu bạn cho rằng sự khác biệt 10px về vị trí chạy là đủ nhỏ cho trường hợp của mình và muốn mục thứ ba được đặt ở cột đầu tiên thay vì cột thứ hai để phù hợp hơn với thứ tự nguồn, hãy sử dụng thuộc tính item-tolerance.

Thuộc tính item-tolerance mới kiểm soát độ nhạy trong việc đặt mục.

Trong ví dụ trước, bạn có thể áp dụng item-tolerance: 10px; cho vùng chứa để tuỳ chỉnh mức độ biến đổi trong việc đặt mục:

.masonry {
  display: masonry;
  masonry: 200px 200px;
  gap: 10px;
  item-tolerance: 10px;
}
Bố cục dạng khối hai cột.
Xem bản minh hoạ về dung sai của mặt hàng tại đây

Xin lưu ý rằng quy cách nháp gọi thuộc tính này là item-slack. Gần đây, Nhóm công tác CSS đã quyết định sử dụng item-tolerance làm tên thay thế và thông số kỹ thuật sẽ sớm được cập nhật.

Các thuộc tính khác có sẵn

Bạn có thể sử dụng các thuộc tính kích thước và vị trí của mẫu tương tự để định kích thước và đặt các mục trong trục lưới của một vùng chứa kiểu xếp gạch như bạn có thể làm với Lưới CSS, chẳng hạn như grid-row, grid-column, grid-area, grid-template-areas hoặc order. Trải nghiệm toàn bộ sức mạnh của lưới CSS khi tạo bố cục kiểu xếp gạch.

Kêu gọi phản hồi

Chúng tôi rất mong bạn khám phá bố cục dạng khối CSS, thoả sức sáng tạo và khám phá những khả năng mới mà bố cục này có thể giúp bạn khai thác. Một cách hay để bắt đầu là kiểm tra các bản minh hoạmã nguồn của chúng, đồng thời bắt đầu tạo các ví dụ của riêng bạn trong Chromium (hãy nhớ bật cờ trước).

Ý kiến phản hồi của bạn rất quan trọng trong việc giúp chúng tôi định hình API và kiểm tra để đảm bảo API được thiết kế nhằm đáp ứng nhu cầu của bạn trên web. Hãy dùng thử bố cục dạng lưới và cho chúng tôi biết ý kiến của bạn!

Nếu bạn có ý kiến hoặc phản hồi về hình dạng của API, hãy cho chúng tôi biết bằng cách bình luận về Vấn đề 11243 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.

CSS masonry vẫn đang được triển khai trong Chromium. Nếu bạn kiểm thử tính năng này, hãy lưu ý rằng chúng tôi vẫn đang tích cực phát triển tính năng này và bạn có thể gặp phải những trường hợp tính năng này không hoạt động như mong đợi. Một số hạn chế hiện tại bao gồm đóng gói dày đặc, vị trí đảo ngược, hỗ trợ lưới phụ, hỗ trợ ngoài luồng, hỗ trợ đường cơ sở, hỗ trợ Công cụ cho nhà phát triển, hỗ trợ phân mảnh, hỗ trợ trang trí khoảng trống, cùng nhiều hạn chế khác.

Nếu bạn phát hiện thấy lỗi trong khi dùng thử tính năng này, hãy chia sẻ ý kiến phản hồi bằng cách mở một lỗi mới trên Chromium.