Đề xuất thay thế cho khối xây CSS

Nhóm Chrome rất muốn xem cách 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 lớp này như một phần của thông số kỹ thuật Lưới CSS như đề xuất trong bài đăng gần đây trên WebKit thì là sai lầm. Chúng tôi cũng cảm thấy rằng bài đăng WebKit phản bác lại một phiên bản khối xây mà không ai đề xuất.

Do đó, bài đăng này nhằm giải thích lý do tại sao chúng tôi ở Chrome lại lo ngại về triển khai khối xây trong thông số kỹ thuật Bố cục lưới CSS và làm rõ chính xác những gì đề xuất thay thế cho phép. Nói ngắn gọn:

  • Nhóm Chrome rất muốn bỏ chặn khối xây, chúng tôi biết rằng đây là vấn đề mà nhà phát triển mong muốn.
  • Việc thêm khối xây vào thông số lưới là sự cố đối với ngoài việc bạn cho rằng khối xây có là lưới hay không.
  • Xác định khối xây Việc nằm ngoài thông số kỹ thuật lưới không ngăn được việc có nhiều kích thước kênh cho khối xây hoặ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ỳ các tính năng được dùng trong bố cục lưới.

Khối xây có nên nằm trong lưới không?

Nhóm Chrome cho rằng khối xây nên là một bố cục riêng biệt phương thức, được xác định bằng display: masonry (hoặc một từ khoá khác nên có tên hay hơn quyết định). Trong phần sau của bài đăng này, bạn có thể xem một số ví dụ về những việc có thể trông như thế nào trong mã.

Có hai lý do liên quan khiến chúng tôi cho rằng khối xây được xác định rõ hơn ở bên ngoài của bố cục lưới—tiềm năng của các vấn đề về hiệu suất bố cục và thực tế là cả khối xây và lưới đều có các tính năng có ý nghĩa trong một phương thức bố cục nhưng không ứng dụng khác.

Hiệu suất

Lưới và khối xây trái ngược nhau về cách trình duyệt xử lý kích thước và khối xây vị trí. Khi 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 của từng kênh. Điều này khiến hàm nội tại phức tạp Điều này rất hữu ích trong lưới. Với khối xây, các mục được đặt nguyên trạng và trình duyệt không biết có bao nhiêu trong mỗi kênh. Đây không phải là vấn đề với mọi bản nhạc có kích thước nội tại hoặc với mọi bản nhạc có kích thước cố định. Tuy nhiên, nếu bạn kết hợp kênh cố định và nội tại. Để giải quyết vấn đề, trình duyệt cần thực hiện bước bố cục trước để bố trí mọi mục theo mọi cách có thể nhằm với một lưới lớn, điều này sẽ góp phần cải thiện hiệu suất bố cục vấn đề.

Do đó, nếu bạn có bố cục khối xây với định nghĩa theo dõi là grid-template-columns: 200px auto 200px — một hoạt động rất phổ biến để thực hiện trong lưới — bạn gặp phải vấn đề. Các bài toán này sẽ trở thành cấp số nhân khi bạn cộng lưới phụ.

Có tranh luậ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ó rất nhiều lưới. Chúng tôi không muốn vận chuyển điều gì đó có giới hạn về cách sử dụng, khi có phương án thay thế phương pháp tiếp cận.

Chúng ta làm gì đối với những điều không có ý nghĩa 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 rằng họ hoạt động không nhất quán. Sự không nhất quán mà họ gặp phải là vì các giả định lâu dài 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 định dạng ngữ cảnh. Khi chúng ta chuyển sang bối cảnh định dạng lưới hoặc linh hoạt, một số nội dung sẽ hành xử theo cách khác. Ví dụ: bạn biết rằng khi bạn đang ở trong flexbox, không phải tất cả các phương pháp căn chỉnh có sẵn, vì hộp linh hoạt là một chiều.

Việc nhóm khối xây thành lưới sẽ phá vỡ mối liên hệ rõ ràng này giữa bối cảnh định dạng và tình trạng sẵn có của những tính năng như thuộc tính căn chỉnh, được xác định trong Hộp Thông số kỹ thuật về căn chỉnh theo ngữ cảnh định dạng.

Nếu chúng tôi quyết định giải quyết vấn đề về hiệu suất đã nêu trước đó bằng cách thực hiện định nghĩa đường ray cố định và hàm nội tại lẫn nhau là bất hợp pháp trong khối xây, thì bạn sẽ bạn phải nhớ rằng một mẫu rất phổ biến cho bố cục lưới không phù hợp với khối xây.

Cũng có những mẫu phù hợp trong khối xây, ví dụ: grid-template-columns: repeat(auto-fill, max-content), vì bạn không có các điều kiện ràng buộc chéo, nhưng cần vẫn không hợp lệ trong lưới. Sau đây là một danh sách thuộc tính mà chúng ta dự kiến sẽ hoạt động khác một chút hoặc có các giá trị hợp lệ khác nhau.

  • grid-template-areas: Trong khối xây, bạn chỉ có thể chỉ định hàng đầu tiên trong hướng không phải là khối xây.
  • grid-template: Viết tắt cần tính đến tất cả điểm khác biệt.
  • Theo dõi các giá trị kích thước cho grid-template-columnsgrid-template-rows do những khác biệt về giá trị pháp lý.
  • grid-auto-flow không áp dụng cho khối xây và masonry-auto-flow không áp dụng cho lưới. Hợp nhất các từ khoá sẽ tạo ra vấn đề về những nội dung không hợp lệ do phương thức bố cục mà bạn đang tham gia.
  • Lưới có 4 thuộc tính vị trí (grid-column-start, v.v.), khối xây chỉ có hai.
  • Lưới có thể sử dụng cả 6 justify-*align-* nhưng Masonry chỉ sử dụng một tập hợp con như flexbox.

Bạn cũng cần phải nêu rõ điều gì sẽ xảy ra trong tất cả các lỗi mới các trường hợp do nhà phát triển sử dụng một giá trị không hợp lệ trong lưới có khối hoặc lưới không có khối xây. Ví dụ: URL hợp lệ để sử dụng grid-template-columns: masonry hoặc grid-template-rows: masonry nhưng không thể thực hiện cả hai cùng một lúc. Điều gì xảy ra nếu bạn sử dụng cả hai cùng một lúc? Những chi tiết này phải được chỉ định để tất cả trình duyệt làm tương tự.

Điều này trở nên phức tạp từ khía cạnh chỉ số kỹ thuật, hiện nay và trong tương lai. Chúng tôi cần đảm bảo rằng mọi công việc đều tính đến khối xây, và liệu nó có hoạt động trong khối xây hay không. Thông tin này cũng khó hiểu của nhiều nhà phát triển. Tại sao bạn cần luôn nghĩ rằng dù khi sử dụng display: grid, một số tính năng không hoạt động được do dùng khối xây?

Một đề xuất thay thế

Như đã đề cập, nhóm Chrome muốn xác định tường xây bên ngoài thông số lưới. Điều này không có nghĩa là chúng tôi chỉ giới hạn ở phương thức bố cục đơn giản có kích thước cột giống hệt nhau. Tất cả các bản minh hoạ trong WebKit thì vẫn có thể đăng bài.

Bố cục khối xây cổ điển

Khi nhắc đến khối xây, hầu hết mọi người sẽ nghĩ đến một bố cục có nhiều khối đồng đều cột có kích thước tối đa. Điều này sẽ được xác định bằng cách sử dụng CSS sau đây, vốn cần một dòng ít mã hơn so với lưới đi kèm lưới tương đương phiên bản.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

Bản nhạc có kích thước bằng nhau.

Sử dụng kích thước thành phần theo dõi dạng lưới cho các chiều rộng cột khác nhau

Khác với vấn đề đã đề cập trước đó, kết hợp cả kênh nội tại và kênh cố định bạn có thể sử dụng tất cả kích thước bản nhạc mà mình yêu thích từ lưới. Chẳng hạn như ví dụ từ bài đăng trên blog WebKit, 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;
}

Mẫu gồm các bản nhạc có kích thước rộng và hẹp.

Kích thước thanh ray bổ sung cho khối xây

Có thêm các tùy chọn định kích thước bản nhạc mà chúng tôi không cho phép ở dạng lưới do thực tế rằng lưới là một phương thức bố cục hai chiều. Những thông tin này sẽ hữu ích trong khối xây nhưng sẽ khó hiểu nếu sau đó chúng không hoạt động trong lưới.

Tự động điền max-content kênh có kích thước.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

Tự động điền auto kênh có kích thước để tạo ra những kênh có cùng kích thước, tự động điều chỉnh kích thước để phù hợp với kích thước lớn nhất.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

Khối xây có các thanh ray được tự động điều chỉnh kích thước.

Cho phép nội dung trải rộng các cột và đặt các mục trên bố cục khối xây

Chẳng có lý do gì mà không có nội dung nằm trên các cột trong một khối xây riêng biệt đặc điểm kỹ thuật. Thao tác này có thể sử dụng thuộc tính masonry-track, là cách viết tắt của masonry-track-startmasonry-track-end vì bạn chỉ có một phương diện để mở rộng các vật thể khi ở bố cục khối xây.

.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 */
}

Khối xây với các hạng mục được đặt và mở rộng.

Khối xây phụ hoặc lưới phụ sử dụng các tuyến đường khối xây

Điều này có thể được hỗ trợ với thông số kỹ thuật riêng của khối xây, một lần nữa với cho biết rằng chúng tôi không cho phép phối hợp các kênh nội tại và kênh có kích thước cố định. Chính xác giống như cần được xác định. Chúng tôi thấy rằng không có lý do nào khiến việc này cơ quan.

Kết luận

Chúng tôi rất muốn có được thông số kỹ thuật có thể được giao một cách tương tác. Tuy nhiên, chúng tôi muốn làm điều đó theo cách hiệu quả ngay bây giờ và trong tương lai mà các nhà phát triển có thể dựa vào. Cách duy nhất để giải quyết các vấn đề về hiệu suất đã nêu, có thể là vấn đề thứ hai, đó là có các phần của lưới không hợp lệ trong khối xây, và tệ hơn nữa. Chúng tôi không nghĩ như vậy một giải pháp, đặc biệt là khi có thể có tất cả các đối tượng lưới mà bạn muốn trong khi vẫn tách biệt rõ ràng các nội dung 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 lại bài đăng này cũng như các cuộc thảo luận dẫn đến bài đăng này.