Cải tiến bố cục logic với cách viết tắt tương đối về luồng

Các ký hiệu viết tắt thuộc tính logic mới và các thuộc tính lồng ghép mới cho Chromium.

Kể từ Chromium 69 (ngày 3 tháng 9 năm 2018), các giá trị và thuộc tính logic đã giúp nhà phát triển duy trì quyền kiểm soát bố cục quốc tế thông qua các kiểu logic, thay vì kiểu chiều, hướng và kích thước thực tế. Trong Chromium 87, các ký hiệu viết tắt và độ dời đã được cung cấp để giúp bạn dễ dàng viết các thuộc tính và giá trị logic này hơn một chút. Điều này giúp Chromium bắt kịp Firefox, trình duyệt đã hỗ trợ các từ viết tắt kể từ phiên bản 66. Safari đã sẵn sàng cung cấp các tính năng này trong bản xem trước công nghệ.

Các ngôn ngữ Latinh, Hebrew và Nhật Bản được hiển thị dưới dạng văn bản giữ chỗ trong khung thiết bị. Các mũi tên và màu sắc đi theo văn bản để giúp liên kết 2 hướng của khối và cùng dòng.

Quy trình tài liệu

Nếu đã quen thuộc với các thuộc tính logic, trục nội tuyến và trục khối và không muốn làm mới, bạn có thể bỏ qua phần này. Nếu không, hãy tham khảo phần ôn tập ngắn sau đây.

Trong tiếng Anh, các chữ cái và từ được sắp xếp từ trái sang phải, còn các đoạn văn được xếp chồng từ trên xuống dưới. Trong tiếng Trung truyền thống, các chữ cái và từ được viết từ trên xuống dưới, còn các đoạn văn được xếp chồng từ phải sang trái. Chỉ trong 2 trường hợp này, nếu viết CSS để đặt "margin top" (lề trên) vào một đoạn văn, chúng ta chỉ giãn cách một kiểu ngôn ngữ một cách thích hợp. Nếu trang được dịch từ tiếng Anh sang tiếng Trung phồn thể, thì lề có thể không có ý nghĩa trong chế độ viết dọc mới.

Do đó, mặt thực của hộp không hữu ích lắm trên phạm vi quốc tế. Như vậy, quá trình hỗ trợ nhiều ngôn ngữ bắt đầu; tìm hiểu về các khía cạnh thực tế và logic của mô hình hộp.

Bạn đã từng kiểm tra phần tử p trong Chrome DevTools chưa? Nếu có, bạn có thể nhận thấy rằng các kiểu Tác nhân người dùng mặc định không phải là kiểu thực tế mà là kiểu logic.

p {
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
}

CSS từ Trang định kiểu tác nhân người dùng của Chromium

Lề không nằm ở trên cùng hoặc dưới cùng như người đọc tiếng Anh có thể tin. Đó là block-startblock-end! Các thuộc tính logic này tương tự như phần trên cùng và dưới cùng của trình đọc tiếng Anh, nhưng cũng tương tự như trình đọc tiếng Nhật là bên phải và bên trái. Viết một lần, dùng được ở mọi nơi.

Luồng thông thường là khi trang web cố ý là một phần của luồng đa hướng này. Khi nội dung trang cập nhật theo các thay đổi về hướng tài liệu, bố cục và các phần tử của bố cục đó sẽ được xem xét trong luồng. Đọc thêm về "trong" và "ngoài" luồng trên MDN hoặc trong thông số kỹ thuật của Mô-đun hiển thị CSS. Mặc dù không bắt buộc phải có thuộc tính logic trong luồng, nhưng các thuộc tính này sẽ giúp bạn thực hiện nhiều thao tác nặng khi hướng thay đổi. Luồng ngụ ý hướng, chữ cái, từ và nội dung cần di chuyển theo. Điều này dẫn chúng ta đến các hướng dẫn logic chặn và nội tuyến.

Hướng khối là hướng mà các khối nội dung mới tuân theo, chẳng hạn như tự hỏi "nên đặt đoạn văn tiếp theo ở đâu?". Bạn có thể coi đó là "khối nội dung" hoặc "khối văn bản". Mỗi ngôn ngữ sắp xếp các khối và sắp xếp các khối đó theo block-axis tương ứng. block-start là bên đặt đoạn văn đầu tiên, còn block-end là bên mà các đoạn văn mới sẽ chuyển đến.

Ví dụ: trong chữ viết tay Nhật Bản truyền thống, hướng khối văn bản sẽ từ phải sang trái:

Hướng nội tuyến là hướng của các chữ cái và từ. Hãy xem xét hướng di chuyển của cánh tay và bàn tay khi bạn viết; chúng di chuyển dọc theo inline-axis. inline-start là bên bạn bắt đầu viết, còn inline-end là bên kết thúc hoặc gói dữ liệu. Trong video ở trên, inline-axis chạy từ trên xuống, nhưng trong video tiếp theo, inline-axis chạy từ phải sang trái.

Việc là flow-relative nghĩa là các kiểu được viết cho một ngôn ngữ sẽ được áp dụng theo ngữ cảnh và phù hợp với các ngôn ngữ khác. Nội dung sẽ được phân phối theo ngôn ngữ của nội dung đó.

Các ký hiệu viết tắt mới

Một số viết tắt sau đây không phải là tính năng mới cho trình duyệt, mà là cách dễ dàng hơn để viết kiểu bằng cách tận dụng khả năng thiết lập giá trị trên cả cạnh khối hoặc nội tuyến cùng một lúc. Các thuộc tính logic inset-* mang lại các khả năng mới, vì trước đó không có cách nào để chỉ định các vị trí tuyệt đối bằng các thuộc tính logic. Mặc dù phần lồng ghép và viết tắt rất phù hợp với nhau, nhưng tôi sẽ giới thiệu cho bạn tất cả các tính năng mới về thuộc tính logic trong Chromium 87 cùng một lúc.

Ký hiệu viết tắt lề

Không có khả năng mới nào được cung cấp, nhưng một số viết tắt siêu tiện dụng đã được cung cấp:
margin-blockmargin-inline.

Chữ viết tay
margin-block-start: 2ch;
margin-block-end: 2ch;
Chữ viết tắt mới
margin-block: 2ch;
/* or */
margin-block: 2ch 2ch;

Trước đây, chúng tôi chưa có ký hiệu viết tắt cho "trên và dưới" hoặc "trái và phải"! Bạn có thể tham chiếu cả 4 cạnh bằng cách sử dụng ký hiệu viết tắt margin: 10px;. Giờ đây, bạn có thể dễ dàng tham chiếu 2 cạnh bổ sung bằng cách sử dụng ký hiệu viết tắt thuộc tính logic.

Chữ viết tay
margin-inline-start: 4ch;
margin-inline-end: 2ch;
Chữ viết tắt mới
margin-inline: 4ch 2ch;

Ký hiệu nhanh về khoảng đệm

Không có tính năng mới nào được cung cấp, nhưng có nhiều ký hiệu viết tắt siêu tiện lợi hơn:
padding-blockpadding-inline.


Chữ viết tay
padding-block-start: 2ch;
padding-block-end: 2ch;
Chữ viết tắt mới
padding-block: 2ch;
/* or */
padding-block: 2ch 2ch;

Và bộ ký hiệu viết tắt bổ sung inline:

Chữ viết tay
padding-inline-start: 4ch;
padding-inline-end: 2ch;
Chữ viết tắt mới
padding-inline: 4ch 2ch;

Phần lồng ghép và viết tắt

Bạn có thể viết tất cả các thuộc tính vật lý top, right, bottomleft dưới dạng giá trị cho thuộc tính inset. Bất kỳ giá trị nào của position đều có thể hưởng lợi từ việc đặt các cạnh có phần lồng ghép.

.cover {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  inset: 0;
}


Chữ viết tay dài
position: absolute;
top: 1px;
right: 2px;
bottom: 3px;
left: 4px;
Chữ viết tắt thực tế mới
position: absolute;
inset: 1px 2px 3px 4px;

Việc này sẽ rất tiện lợi! Phần lồng ghép là viết tắt của các cạnh thực tế và hoạt động giống như lề và khoảng đệm.

Tính năng mới

Mặc dù các ký hiệu viết tắt cho các mặt vật lý rất thú vị, nhưng các tính năng logic mà các ký hiệu viết tắt inset bổ sung mang lại còn thú vị hơn nữa. Các viết tắt này giúp nhà phát triển tạo nội dung thuận tiện hơn (vì phải nhập ít ký tự hơn) nhưng cũng tăng phạm vi tiếp cận tiềm năng cho bố cục vì các viết tắt này liên quan đến luồng.

Chữ viết tay dài
position: absolute;
top: 10px;
bottom: 10px;
Chữ viết tắt logic
position: absolute;
inset-block: 10px;


Chữ viết tay dài
position: absolute;
left: 10px;
right: 20px;
Chữ viết tắt logic
position: absolute;
inset-inline: 10px 20px;

Bạn có thể đọc thêm và xem danh sách đầy đủ các ký hiệu viết tắt và viết dài của phần lồng ghép trên MDN.

Đường viền viết tắt

Border (Đường viền) cùng với các thuộc tính color, stylewidth lồng nhau đều có các ký hiệu viết tắt logic mới.


Chữ viết tay dài
border-top-color: hotpink;
border-bottom-color: hotpink;
Chữ viết tắt logic
border-block-color: hotpink;
/* or */
border-block-color: hotpink hotpink;


Chữ viết tay dài
border-left-style: dashed;
border-right-style: dashed;
Chữ viết tắt logic
border-inline-style: dashed;
/* or */
border-inline-style: dashed dashed;


Chữ viết tay dài
border-left-width: 1px;
border-right-width: 1px;
Chữ viết tắt logic
border-inline-width: 1px;
/* or */
border-inline-width: 1px 1px;

Bạn có thể đọc thêm và xem danh sách đầy đủ các viết tắt và viết dài của đường viền trên MDN.

Ví dụ về thuộc tính logic <figure>

Hãy cùng xem một ví dụ nhỏ về cách kết hợp tất cả các thành phần này. Các thuộc tính logic có thể bố cục hình ảnh bằng chú thích để xử lý các hướng viết và tài liệu khác nhau.

Hoặc hãy thử!

Bạn không cần phải làm gì nhiều để tạo một thẻ thích ứng trên toàn cầu bằng <figure> và một vài thuộc tính logic. Nếu bạn tò mò về cách tất cả các CSS quốc tế này hoạt động cùng nhau, tôi hy vọng đây sẽ là một phần giới thiệu nhỏ nhưng ý nghĩa.

Tính năng tự động điền và hỗ trợ nhiều trình duyệt

Công cụ Cascade hoặc công cụ xây dựng là những lựa chọn khả thi để có trình duyệt cũ và mới giống nhau, có khoảng cách phù hợp với các thuộc tính logic đã cập nhật. Đối với phương thức dự phòng Cascade, hãy theo một thuộc tính thực bằng một thuộc tính logic và trình duyệt sẽ sử dụng thuộc tính "cuối cùng" mà trình duyệt tìm thấy trong quá trình phân giải kiểu.

p {
  /* for unsupporting browsers */
  margin-top: 1ch;
  margin-bottom: 2ch;

  /* for supporting browsers to use */
  /* and unsupporting browsers to ignore and go 🤷‍♂️ */
  margin-block: 1ch 2ch;
}

Tuy nhiên, đó chưa phải là giải pháp đầy đủ cho mọi người. Dưới đây là một phương án dự phòng viết tay tận dụng bộ chọn giả :lang() để nhắm đến các ngôn ngữ cụ thể, điều chỉnh khoảng cách thực tế của các ngôn ngữ đó cho phù hợp, sau đó cung cấp khoảng cách logic cho các trình duyệt hỗ trợ:

/* physical side styles */
p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

/* adjusted physical side styles per language */
:lang(ja) {
  p {
    /* zero out styles not useful for traditional Japanese */
    margin-top: 0;
    margin-bottom: 0;

    /* add appropriate styles for traditional Japanese */
    margin-right: 1ch;
    margin-left: 2ch;
  }
}

/* add selectors and adjust for languages all supported */
:lang(he) {}
:lang(mn) {}

/* Logical Sides */
/* Then, for supporting browsers to use */
/* and unsupporting browsers to ignore #TheCascade */
p {
  /* remove any potential physical cruft.. */
  margin: 0;
  /* explicitly set logical value */
  margin-block: 1ch 2ch;
}

Bạn cũng có thể sử dụng @supports để xác định xem có cung cấp phương án dự phòng cho thuộc tính thực tế hay không:

p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

@supports (margin-block: 0) {
  p {
    margin-block: 1ch 2ch;
  }
}

Sass, PostCSS, Emotion và các công cụ khác có trình tạo gói tự động và/hoặc các dịch vụ thời gian tạo bản dựng có nhiều giải pháp hoặc phương án dự phòng. Hãy kiểm tra từng chiến lược để xem chiến lược nào phù hợp với chuỗi công cụ và chiến lược tổng thể của trang web.

Bước tiếp theo

CSS sẽ cung cấp nhiều thuộc tính logic hơn, nhưng chưa hoàn tất! Tuy nhiên, vẫn còn một bộ ký hiệu viết tắt lớn bị thiếu và giải pháp vẫn đang chờ xử lý trong vấn đề trên GitHub này. Có một giải pháp tạm thời trong bản nháp. Nếu bạn muốn tạo kiểu cho tất cả các cạnh logic của một hộp bằng ký hiệu viết tắt thì sao?

Chữ viết tắt thực tế
margin: 1px 2px 3px 4px;
margin: 1px 2px;
margin: 2px;
Chữ viết tắt logic
margin: logical 1px 2px 3px 4px;
margin: logical 1px 2px;
margin: logical 2px;

Đề xuất dự thảo hiện tại có nghĩa là bạn phải viết logical trong mọi ký hiệu viết tắt để áp dụng giá trị tương đương logic, điều này nghe có vẻ không DRY (Khô khan) đối với một số người.

Có các đề xuất khác để thay đổi thuộc tính này ở cấp khối hoặc cấp trang, nhưng điều đó có thể làm rò rỉ các trường hợp sử dụng logic vào các kiểu vẫn giả định các mặt thực.

html {
  flow-mode: physical;
  /* or */
  flow-mode: logical;
  /* now all margin/padding/etc references are logical */
}

/* hopefully no 3rd/1st party code is hard coded to top/left/etc ..? */

Đây là một câu hỏi khó! Hãy bỏ phiếu, bày tỏ ý kiến của bạn. Chúng tôi rất mong được nghe ý kiến của bạn.

Bạn muốn tìm hiểu hoặc nghiên cứu thêm về các thuộc tính logic? Dưới đây là tài liệu tham khảo chi tiết, cùng với hướng dẫn và ví dụ trên MDN 🤓

Phản hồi

  • Để đề xuất thay đổi cú pháp CSS của các từ viết tắt tương đối theo luồng, trước tiên, hãy kiểm tra các vấn đề hiện có trên kho lưu trữ csswg-drafts. Nếu không có vấn đề nào hiện có khớp với đề xuất của bạn, hãy tạo vấn đề mới.
  • Để báo cáo lỗi về việc triển khai các ký hiệu viết tắt tương đối theo luồng của Chromium, trước tiên, hãy kiểm tra các vấn đề hiện có trên Công cụ theo dõi lỗi của Chromium. Nếu không có vấn đề nào hiện có khớp với lỗi của bạn, hãy tạo vấn đề mới.