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 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 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-* |
Định vị neo | anchor-name |
position-anchor |
Ảnh động dạng 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 tệp định kiểu, nhưng Shadow DOM được xây dựng để làm ngược lại. Lớp này đóng gói 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 cho là 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, trải nghiệm soạn thảo các thành phần web sẽ tạo cảm giác đủ sinh động để linh hoạt như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 rõ vấn đề, về lý thuyết, bạn cần hiểu cách các phần này của CSS phối hợp với nhau.
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, 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ố 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: nó phải hoạt động giống như một nội dung khai báo kiểu chung cho tài liệu, giúp xác định cách hoạt động của một thuộc tính có tên cụ thể. Vì thuộc tính phải khớp trên các cây bóng đổ, nên việc khai báo thuộc tính không khớp sẽ dẫn đến kết quả không mong muốn, vì vậy, nội dung khai báo @property
được chỉ định để được làm phẳng và giải quyết theo thứ tự trong 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 này.
- 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 này. - 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 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
.
Tức là không thể tham chiếu tên từ trong DOM bóng đổ từ ::part
, vì ::part
là kiểu ở phạm vi máy chủ lưu trữ chứ không phải là 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 sẽ hoạt động với các kiểu cùng dòng
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à DOM tối 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 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à kiểm thử 6 kịch bản:
- Tham chiếu bên ngoài đến tên ngoài: không liên quan đến DOM tối, cách này sẽ hiệu quả.
- 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: thuộc tính này sẽ có tác dụng, vì tên trong phạm vi cây được các gốc bóng đổ kế thừa.
- Tham chiếu nội tại đến tên nội tại: 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à các định nghĩa khung hình chính chỉ có thể được tham chiếu trong phạm vi mà chúng được xác định. Hãy 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 nằm trong phạm vi chính xác 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 gốc đổ bóng (bản thân hiệu ứng chuyển đổi nằm bên ngoài gốc của 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 hơi khác nhau 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 trạng thái tương tác hiện tại liên quan đến tên CSS và DOM bóng, trải nghiệm không nhất quán và có lỗi. Không có tính năng nào 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 để đảm bảo trải nghiệm nhất quán là một danh sách hữu hạn các lỗi và 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, 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.