Tên CSS do tác giả xác định và DOM bóng sẽ hoạt động cùng nhau. Tuy nhiên, các trình duyệt không nhất quán với thông số kỹ thuật, đôi khi với nhau và mọi tên CSS đều không nhất quán theo một cách hơi khác.
Bài viết này ghi lại trạng thái hiện tại của cách tên CSS do tác giả xác định hoạt động trên các phạm vi bóng, với hy vọng rằng bài viết này có thể đóng vai trò là hướng dẫn để 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
, quy tắc này xác định <keyframe-name>
là một giá trị nhận dạng tuỳ chỉnh hoặc một chuỗi. Mục đích của khái niệm này là khai báo một nội dung nào đó trong một phần của tệp định kiểu và tham chiếu đến nội dung đó trong một 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 CSS khác sử dụng tên CSS là phông chữ, khai báo thuộc tính, truy vấn vùng chứa và gần đây nhất là chuyển đổi chế độ xem, định vị neo và ảnh động do cuộn điều khiển. Bảng không đầy đủ sau đây bao gồm các 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 Mọi nội dung khai báo thuộc tính tuỳ chỉnh chưa đăng ký |
var() |
Xem hiệu ứng chuyển đổi | view-transition-name
view-transition-class |
Phần tử mô phỏng ::view-transition-* |
Vị trí neo | anchor-name |
position-anchor |
Ảnh động do cuộn | view-timeline-name
scroll-timeline-name |
animation-timeline |
Kiểu danh sách | @counter-style |
list-style |
Bộ đếm | counter-reset
counter-set
counter-increment |
|
Truy vấn vùng chứa | container-name |
@container |
Trang | page |
@page |
Như bạn có thể thấy trong bảng, tên CSS thường có một tham chiếu CSS tương ứng. Ví dụ: animation-name
là tham chiếu đến tên @keyframes
. Tên CSS khác với tên được xác định trong DOM, chẳng hạn như tên thuộc tính và tên thẻ, vì các tên này được khai báo rồi tham chiếu trong ngữ cảnh của các tệp định kiểu.
Mối quan hệ giữa tên với DOM bóng
Mặc dù tên CSS được tạo để tạo mối quan hệ giữa các phần khác nhau của tài liệu hoặc bảng định kiểu, nhưng Shadow DOM lại được tạo để làm điều ngược lại. Lớp này đóng gói các mối quan hệ để các mối quan hệ đó không bị rò rỉ trên các thành phần web được cho là có không gian tên riêng.
Bằng cách kết hợp tên CSS và DOM bóng, trải nghiệm kết hợp các thành phần web sẽ đủ rõ ràng để linh hoạt nhưng cũng đủ hạn chế để ổn định.
Điều này rất tốt về mặt lý thuyết. Trong thực tế, các trình duyệt không nhất quán về cách tên CSS tương tác với DOM bóng, cả giữa các tính nă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 bóng hoạt động cùng nhau
Để hiểu vấn đề này, bạn nên tìm hiểu cách các phần này của CSS hoạt động cùng nhau theo lý thuyết.
Quy tắc chung
Quy tắc chung về cách tên CSS hoạt động trên các cây bóng được xác định trong thông số kỹ thuật 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à bạn có thể truy cập tên này từ cây bóng con cháu, nhưng không thể truy cập từ cây bóng đồng cấp hoặc cây bóng tổ tiên. Xin lưu ý rằng tên này không giống với tên trong nền tảng web như mã nhận dạng 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, các thuộc tính CSS không được đóng gói bằng shadow DOM.
Thay vào đó, chúng là phương tiện phổ biến để truyền các tham số trên nhiều cây bóng.
Điều này làm cho chỉ số mô tả @property
trở nên đặc biệt: chỉ số này được cho là hoạt động như một nội dung khai báo loại toàn cục của tài liệu, xác định cách một thuộc tính có tên cụ thể hoạt động. Vì các thuộc tính phải khớp nhau trên các cây bóng, nên việc khai báo thuộc tính không khớp sẽ tạo ra kết quả không mong muốn. Vì vậy, các nội dung khai báo @property
được chỉ định để làm phẳng và phân giải theo thứ tự tài liệu.
Cách hoạt động của quy tắc với ::part
Shadow parts (Phần bóng) hiển thị một phần tử bên trong cây bóng cho cây mẹ. Bằng cách đó, cây mẹ có thể truy cập vào phần tử đó và cũng tạo kiểu cho phần tử đó bằng phần tử ::part
.
Vì ::part
cho phép hai phạm vi cây tạo kiểu cho cùng một phần tử, nên thứ tự lũy tiến sau đây được chỉ định:
- Trước tiên, hãy kiểm tra kiểu bên trong ngữ cảnh bóng đổ. Đây là kiểu "mặc định" của phần.
- Sau đó, áp dụng kiểu bên ngoài như đã xác định trong
::part
. Đây là kiểu "tuỳ chỉnh" của phần. - Sau đó, hãy áp dụng bất kỳ kiểu nội bộ nào được xác định cùng với
!important
. Điều này cho phép phần tử tuỳ chỉnh khai báo rằng một thuộc tính nhất định của một phần nhất định không thể tuỳ chỉnh bằng::part
.
Điều này có nghĩa là bạn không thể tham chiếu các tên trong DOM bóng từ ::part
, vì ::part
là kiểu trong phạm vi máy chủ lưu trữ thay vì kiểu trong phạm vi bóng. 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 hoạt động với các kiểu nội tuyến
Không giống như ::part
, các kiểu nội tuyến có thuộc tính style
hoặc các kiểu được đặt kiểu theo phương thức lập trình bằng tập lệnh sẽ nằm trong phạm vi của phần tử. Đó là vì để áp dụng một kiểu cho một phần tử, bạn cần có quyền truy cập vào tên phần tử và do đó là chính gốc bóng.
Cách tên CSS và shadow DOM hoạt động cùng nhau trong thực tế
Mặc dù các quy tắc trước đó được xác định rõ ràng và nhất quán, nhưng cách triển khai hiện tại không phải lúc nào cũng phản ánh điều đó.
Trong thực tế, @property
hoạt động khác với thông số kỹ thuật một cách nhất quán trên các trình duyệt và hầu hết các tính năng khác đều có lỗi chưa được khắc phục (một số tính năng chưa được phát hành, vì vậy, bạn có thời gian để khắc phục các lỗi đó).
Để kiểm thử và minh hoạ cách các tính năng này hoạt động 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à kiểm thử 6 kịch bản:
- Tham chiếu bên ngoài đến một tên bên ngoài: không có DOM bóng, thao tác này sẽ hoạt động.
- Tham chiếu bên ngoài đến tên bên trong: cách này sẽ không hoạt động vì điều đó 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: cách này sẽ hoạt động vì các tên trong phạm vi cây được kế thừa bởi các gốc bóng.
- Tham chiếu nội bộ đến tên nội bộ: cách này sẽ hoạt động vì cả tên của tham chiếu đều nằm trong cùng một phạm vi.
::part
tham chiếu đến tên bên ngoài: cách này sẽ hoạt động vì cả::part
và tên đều được khai báo trong cùng một phạm vi.- Tham chiếu
::part
đến tên bên trong: thao tác này sẽ không hoạt động vì phạm vi bên ngoài không được biết về tên được khai báo bên trong DOM bóng.
@keyframes
Như đã xác định trong quy cách, bạn có thể tham chiếu tên khung hình chính từ trong một gốc bóng, miễn là quy tắc tại @keyframes
nằm trong phạm vi cấp trên. Trong thực tế, không có trình duyệt nào triển khai hành vi này và bạn chỉ có thể tham chiếu các định nghĩa khung hình chính trong phạm vi mà các khung hình chính đó được xác định. Xem vấn đề 10540.
@property
Như đã xác định trong quy cách, mọi nội dung khai báo @property
sẽ được làm phẳng thành phạm vi tài liệu. Tuy nhiên, hiện tại, trong tất cả các trình duyệt, bạn chỉ có thể khai báo @property
trong phạm vi tài liệu và các nội dung khai báo @property
trong thư mục gốc bóng sẽ bị bỏ qua.
Xem vấn đề 10541.
Lỗi dành riêng cho trình duyệt
Các tính năng khác không hiển thị 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 một gốc bóng scroll-timeline-name
vàview-timeline-name
không được đặt đúng phạm vi trên::part
(cũng trong Chromium).- Không có trình duyệt nào cho phép khai báo
@font-palette-values
trong thư mục gốc bóng. - Bạn có thể xác định
view-transition-class
bên trong một thư mục gốc bóng (chính quá trình chuyển đổi nằm bên ngoài thư mục gốc bóng). - Firefox cho phép
::part
truy cập vào 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 một gốc bóng.
Xin lưu ý rằng counter-reset
, counter-set
, counter-increment
có quy tắc khác nhau một chút vì đó là tên ngầm ẩn và việc khai báo thuộc tính CSS có một bộ quy tắc đã được thiết lập và kiểm thử kỹ lưỡng.
Kết luận
Tin xấu là khi kiểm tra ảnh chụp nhanh về trạng thái tương tác hiện tại liên quan đến tên CSS và shadow DOM, trải nghiệm này không nhất quán và có lỗi. Không có tính năng nào trong số những tính năng mà chúng tôi đã kiểm tra ở đây hoạt động nhất quán trên các trình duyệt và theo thông số kỹ thuật. Tin vui là delta để mang lại trải nghiệm nhất quán là một danh sách lỗi và vấn đề về thông số kỹ thuật có giới hạn. Hãy khắc phục vấn đề này. Trong thời gian chờ đợi, thông tin tổng quan này hy vọng có thể giúp bạn nếu bạn đang gặp khó khăn với các điểm không nhất quán được mô tả trong bài viết này.