Tên CSS do tác giả xác định và DOM bóng: Trong quy cách và trong thực tế

Tên CSS do tác giả xác định và DOM tối phải hoạt động cùng nhau. Tuy nhiên, trình duyệt không nhất quán với thông số kỹ thuật, đôi khi mỗi và mỗi tên CSS lại không thống nhất theo một cách hơi khác.

Bài viết này cung cấp tài liệu về trạng thái hiện tại về cách hoạt động của các tên CSS do tác giả xác định trên phạm vi bóng với hy vọng dữ liệu này có thể đóng vai trò định hướng để cải thiện khả năng tương tác trong tương lai gần.

Tên CSS do tác giả xác định là gì?

Tên CSS do tác giả xác định là một cơ chế cú pháp CSS tương đối cũ, ban đầu được giới thiệu cho quy tắc @keyframes, xác định <keyframe-name> là giá trị nhận dạng tuỳ chỉnh hoặc chuỗi. Mục đích của khái niệm này là khai báo nội dung nào đó trong phần này của biểu định kiểu và tham chiếu đến nội dung đó trong phần khác.

/* "fade-in" is a CSS name, representing a set of keyframes */
@keyframes fade-in {
  from { opacity: 0 };
  to { opacity: 1 }
}

.card {
  /* "fade-in" is a reference to the above keyframes */
  animation-name: fade-in;
}

Các tính năng khác của CSS sử dụng tên CSS là phông chữ, khai báo thuộc tính và các truy vấn vùng chứa khác, gần đây là hiệu ứng chuyển đổi chế độ xem, vị trí neo và ảnh động dựa trên thao tác cuộn. Bảng không đầy đủ sau bao gồm tên mà Chrome kiểm tra trạng thái.

Tính năng Khai báo tên Tham chiếu tên
Khung hình chính @keyframes animation-name
Phông chữ @font-face { }
@font-palette-values
font-family
font-palette
Khai báo thuộc tính @property Bất kỳ thuộc tính tuỳ chỉnh nào
Xem hiệu ứng chuyển đổi view-transition-name
view-transition-class
::view-transition-group()
Định vị neo anchor-name position-anchor
Ảnh động dạng cuộn animation-timeline view-timeline-name
scroll-timeline-name
Kiểu bộ đếm @counter-style
Counter-reset
counter-set
counter-increment
list-style
Cụm từ tìm kiếm về vùng chứa container-name @container
Biến CSS --something var(--something)
Trang @page

Như bạn có thể thấy trong bảng, một tên CSS thường có một CSS tương ứng tài liệu tham khảo. Ví dụ: animation-name là tham chiếu đến @keyframes . Tên CSS khác với tên được xác định trong DOM, chẳng hạn như các thuộc tính và tên thẻ, như được khai báo, sau đó được tham chiếu trong ngữ cảnh của biểu định kiểu.

Cách tên liên quan đến DOM bóng

Mặc dù tên CSS được xây dựng để tạo mối quan hệ giữa các phần khác nhau của tài liệu hoặc biểu định kiểu, Shadow DOM là được xây dựng để làm ngược lại. Cơ chế này gói gọn các mối quan hệ để chúng không bị rò rỉ trên các thành phần web vốn có không gian tên riêng.

Bằng cách kết hợp các tên CSS và DOM tối với nhau, trải nghiệm tạo các thành phần web phải tạo cảm giác đủ biểu cảm để linh hoạt nhưng bị hạn chế đủ để ổn định.

Về mặt lý thuyết, đây là điều tốt. Trong thực tế, các trình duyệt không nhất quán theo cách CSS các tên tương tác với DOM tối, cả hai giữa các đối tượng trong cùng một trình duyệt, trên các trình duyệt và giữa các tính năng và thông số kỹ thuật.

Cách tên và DOM tối nên hoạt động cùng nhau

Để hiểu rõ vấn đề, bạn cần tìm hiểu cách các phần này của CSS phải kết hợp với nhau trên lý thuyết.

Quy tắc chung

Quy tắc chung về cách tên CSS hoạt động trên cây bóng đổ được xác định trong Quy cách CSS Scoping cấp 1. Tóm lại: tên CSS là tên chung trong phạm vi được xác định, nghĩa là có thể truy cập được từ cây bóng con cháu, nhưng không truy cập được từ đồng cấp hoặc cây bóng đổ của đối tượng cấp trên. Lưu ý rằng điều này không giống với tên gọi trên nền tảng web như mã phần tử, được đóng gói trong cùng một phạm vi cây.

Trường hợp ngoại lệ đối với quy tắc: @property

Không giống như các tên CSS khác, thuộc tính CSS không được gói gọn trong DOM bóng. Thay vào đó, chúng là phương tiện phổ biến để truyền các tham số qua các bóng đổ khác nhau cây xanh. Điều này khiến Phần mô tả @property đặc biệt: mã phải hoạt động giống như khai báo kiểu tài liệu chung xác định cách hoạt động của một tài sản được đặt tên cụ thể. Vì các cơ sở lưu trú phải khớp giữa các cây đổ bóng, thông tin khai báo thuộc tính không khớp sẽ dẫn đến việc không mong muốn kết quả, vì vậy, @property khai báo sẽ được chỉ định để làm phẳng và giải quyết theo thứ tự chứng từ.

Cách quy tắc sẽ hoạt động với ::part

Các thành phần trong bóng hiển thị một phần tử bên trong cây bóng đổ với cây mẹ của phần tử đó. Bằng cách làm như vậy, cây mẹ có thể truy cập vào phần tử đó, cũng như tạo kiểu cho phần tử bằng ::part .

::part cho phép 2 phạm vi cây tạo kiểu cho cùng một phần tử, nên thứ tự tầng được chỉ định:

  1. Trước tiên, hãy kiểm tra kiểu bên trong ngữ cảnh đổ bóng. Đây là chế độ cài đặt "mặc định" kiểu của phần này.
  2. Sau đó, áp dụng kiểu bên ngoài như xác định trong ::part. Đây là "tuỳ chỉnh" kiểu của phần này.
  3. Sau đó, áp dụng kiểu nội bộ bất kỳ được xác định cùng với !important. Điều này cho phép một phần tử tuỳ chỉnh khai báo rằng một thuộc tính nhất định của một trang web cụ thể không thể tuỳ chỉnh bởi ::part.

Tức là các tên từ bên trong DOM bóng không thể được tham chiếu từ một ::part, vì ::part là một kiểu trong phạm vi máy chủ lưu trữ chứ không phải trong phạm vi bóng đổ phong cách. Ví dụ:

// inside the shadow DOM:
@keyframes fade-in {
  from { opacity: 0}
}

// This shouldn't work!
// The host style shouldn't know the name "fade-in"
::part(slider) {
  animation-name: fade-in;  
}

Cách quy tắc sẽ hoạt động với các kiểu cùng dòng

Không giống như ::part, kiểu cùng dòng có thuộc tính style hoặc các kiểu đó lập trình kiểu bằng cách sử dụng tập lệnh, trong phạm vi vị trí mà phần tử thuộc phạm vi. Đó là vì để áp dụng một kiểu cho một phần tử mà bạn cần quyền truy cập ô điều khiển phần tử và theo đó dẫn đến chính gốc bóng.

Cách tên CSS và DOM tối hoạt động cùng nhau trong thực tế

Mặc dù các quy tắc trước được định nghĩa rõ ràng và nhất quán, không phải lúc nào cũng phản ánh được điều đó. Trong thực tế, @property hoạt động khác với thông số kỹ thuật theo cách nhất quán trên nhiều trình duyệt và hầu hết các tính năng khác đều có lỗi chưa được xử lý (một vài trong số đó chưa được phát hành, vì vậy, sẽ có thời gian để khắc phục chúng).

Để kiểm tra và minh hoạ cách hoạt động của các tính năng này trong thực tế, chúng tôi đã tạo trang sau: https://css-names-in-the-shadow.glitch.me/. Trang này có một số iframe, mỗi iframe tập trung vào một trong các tính năng và đang thử nghiệm sáu trường hợp:

  • Tham chiếu bên ngoài đến tên ngoài: không liên quan đến DOM bóng, điều này nên cơ quan.
  • Tham chiếu bên ngoài đến tên nội bộ: tên này không nên hoạt động, vì như vậy có nghĩa là tên được xác định trong ngữ cảnh đổ bóng đã bị rò rỉ.
  • Tham chiếu bên trong đến tên bên ngoài: tham chiếu này sẽ hoạt động dưới dạng tên trong phạm vi cây được kế thừa bởi gốc bóng.
  • Tham chiếu nội bộ đến tên bên trong: tham chiếu này sẽ hoạt động, vì cả tên của tham chiếu đều thuộc cùng phạm vi.
  • Tham chiếu ::part đến tên ngoài: thuộc tính này sẽ hoạt động vì cả ::part và tên được khai báo trong cùng một phạm vi.
  • Tham chiếu ::part đến tên bên trong: thuộc tính này không nên hoạt động vì là phạm vi bên ngoài không nên biết về các tên được khai báo bên trong DOM bóng.

@keyframes

Như được xác định trong thông số kỹ thuật, bạn có thể tham chiếu tên khung hình chính từ trong gốc bóng, miễn là quy tắc at @keyframes nằm trong đối tượng cấp trên phạm vi. Trong thực tế, không có trình duyệt nào triển khai hành vi này và khung hình chính định nghĩa chỉ có thể được tham chiếu trong phạm vi mà các định nghĩa đó được định nghĩa. Xem vấn đề 10540.

@property

Như đã xác định trong phần đặc tả, mọi nội dung khai báo của @property sẽ được làm phẳng thành phạm vi tài liệu. Tuy nhiên, hiện nay, trong tất cả các trình duyệt, bạn chỉ có thể khai báo @property trong phạm vi của tài liệu và @property nội dung khai báo trong phạm vi gốc bóng đổ sẽ bị bỏ qua.
Xem vấn đề 10541.

Lỗi cụ thể về trình duyệt

Các tính năng khác không cho thấy hành vi nhất quán trên các trình duyệt:

  • @font-face được làm phẳng thành phạm vi gốc trong Safari.
  • Chromium không cho phép kế thừa các quy tắc @anchor-name trong thư mục gốc của bóng đổ
  • @scroll-timeline-name@view-timeline-name không nằm trong phạm vi chính xác trên ::part (cũng có trong Chromium).
  • Không có trình duyệt nào cho phép khai báo @font-palette-values trong gốc đổ bóng.
  • Có thể xác định view-transition-class bên trong một gốc bóng (phần chuyển đổi) nằm ngoài shadow-root).
  • Firefox cho phép ::part truy cập tên bóng bên trong (truy vấn vùng chứa, khung hình chính).
  • Firefox và Safari không tuân theo @counter-style trong thư mục gốc bóng.

Lưu ý rằng counter-reset, counter-set, counter-increment có một chút các quy tắc khác nhau vì chúng là tên ngầm ẩn và khai báo các thuộc tính CSS có một bộ quy tắc được thiết lập và kiểm tra kỹ lưỡng.

Kết luận

Tin xấu là khi kiểm tra ảnh chụp nhanh của trạng thái tương tác hiện tại đối với tên CSS và DOM tối, trải nghiệm này không nhất quán và xe lôi. Không có tính năng nào mà chúng tôi đã xem xét ở đây hoạt động nhất quán trên trình duyệt và theo thông số kỹ thuật. Điều đáng mừng là việc duy trì trải nghiệm nhất quán là rất hữu hạn danh sách lỗi và các vấn đề về thông số kỹ thuật. Hãy khắc phục vấn đề này. Trong thời gian chờ đợi, hy vọng thông tin tổng quan này có thể giúp ích nếu bạn đang gặp khó khăn với những điểm không thống nhất được mô tả trong bài viết này.