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 thực tế, hướng và kích thước. Trong Chromium 87, chữ viết tắt và giá trị chênh lệch đã được chuyển để giúp các thuộc tính và giá trị logic này dễ viết 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.

Luồng 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, tôi sẽ ôn lại kiến thức ngắn gọn sau đây.

Trong tiếng Anh, các chữ cái và từ chạy từ trái sang phải trong khi các đoạn được xếp chồng lên nhau 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) trên 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 hợp lý trong chế độ viết dọc mới.

Do đó, khía cạnh vật lý của hộp không thực sự hữu ích 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 đã bao giờ kiểm tra phần tử p trong Công cụ của Chrome cho nhà phát triển 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 phải ở 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, hoạt động ở 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. Flow ngụ ý hướng, chữ cái, từ và nội dung cần di chuyển. Điều này sẽ khiến chúng tôi chặn và cùng dòng các chỉ dẫn logic.

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 đây là một "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 chảy 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 đang 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 ở trên cùng và dưới cùng, nhưng trong video tiếp theo này, inline-axis sẽ di chuyển từ phải sang trái.

flow-relative có nghĩa là các kiểu được viết cho một ngôn ngữ sẽ theo ngữ cảnh và được áp dụng phù hợp cho 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.

Viết tắt của 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.

Tay dài
margin-block-start: 2ch;
margin-block-end: 2ch;
Cá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 mặt bằng cách sử dụng viết tắt margin: 10px;. Giờ đây, bạn có thể dễ dàng tham chiếu 2 mặt bổ sung bằng cách sử dụng 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;

Viết tắt của 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;
Viết tắt mới thực
position: absolute;
inset: 1px 2px 3px 4px;

Việc đó trông sẽ thuận tiện ngay lập tức! 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 ký hiệu 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 ký hiệu 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;


Dài tay
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;


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


Dài tay
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ì để thẻ có thể phản hồi ở phạm vi quốc tế 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, đó không phải là giải pháp hoàn chỉnh cho tất cả 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à những bên khác có các dịch vụ gói và/hoặc thời gian xây dựng tự động có nhiều giải pháp hoặc giải pháp 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 nháp hiện tại có nghĩa là bạn phải viết logical trong mọi cú pháp viết tắt để áp dụng quy tắc tương đương về mặt logic, điều này có vẻ không DRY nhất đối với một số đề xuất.

Có một số đề 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ách sử dụng logic thành các kiểu vẫn giả định các mặt thực tế.

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.