Xây dựng thành phần chú giải công cụ

Tổng quan cơ bản về cách tạo phần tử tuỳ chỉnh cho chú giải công cụ thích ứng màu sắc và dễ tiếp cận.

Trong bài đăng này, tôi muốn chia sẻ suy nghĩ về cách tạo một phần tử tuỳ chỉnh <tool-tip> thích ứng màu sắc và dễ tiếp cận. Hãy xem thử bản minh hoạxem nguồn!

Một phần chú thích xuất hiện khi dùng nhiều ví dụ và bảng phối màu

Nếu bạn thích video, đây là phiên bản YouTube của bài đăng này:

Tổng quan

Phần chú thích là một lớp phủ không theo phương thức, không chặn, không tương tác, có chứa thông tin bổ sung cho giao diện người dùng. Theo mặc định, thành phần này sẽ bị ẩn và không bị ẩn khi một phần tử liên kết được di chuột hoặc lấy làm tâm điểm. Bạn không thể chọn hoặc tương tác trực tiếp với chú giải công cụ. Chú giải công cụ không phải là phần thay thế cho nhãn hoặc thông tin có giá trị cao khác, người dùng phải có thể hoàn thành đầy đủ tác vụ mà không cần chú thích.

Nên: luôn gắn nhãn thông tin đầu vào của bạn.
Không nên: dựa vào chú giải công cụ thay vì nhãn

Bật/tắt chú thích so với Chú giải công cụ

Giống như nhiều thành phần, có nhiều mô tả khác nhau về chú giải công cụ, ví dụ: trong MDN, WAI ARIA, Sarah HigleyThành phần bao hàm. Tôi thích cách tách biệt giữa chú giải công cụ và nút bật/tắt. Phần chú thích nên chứa thông tin bổ sung không mang tính tương tác, còn phần chú thích có thể chứa thông tin tương tác và thông tin quan trọng. Lý do chính của việc phân chia là khả năng hỗ trợ tiếp cận, dự kiến người dùng sẽ chuyển đến cửa sổ bật lên như thế nào cũng như có quyền truy cập vào thông tin và các nút trong đó. Bật/tắt mẹo sẽ nhanh chóng trở nên phức tạp.

Dưới đây là video về mẹo bật/tắt trên trang web Designcember; một lớp phủ có tính năng tương tác mà người dùng có thể ghim và khám phá, sau đó đóng bằng phím tắt ( sáng) hoặc phím Escape:

Thử thách GUI này đi theo hướng dẫn về chú giải công cụ, nhằm tìm cách làm hầu hết mọi thứ bằng CSS và sau đây là cách tạo nó.

Markup (note: đây là tên ứng dụng)

Tôi đã chọn sử dụng phần tử tuỳ chỉnh <tool-tip>. Tác giả không cần đưa phần tử tuỳ chỉnh vào thành phần web nếu họ không muốn. Trình duyệt sẽ coi <foo-bar> giống như <div>. Bạn có thể nghĩ đến một phần tử tuỳ chỉnh như tên lớp ít cụ thể hơn. Không liên quan đến JavaScript.

<tool-tip>A tooltip</tool-tip>

Đây giống như một div với một số văn bản bên trong. Chúng ta có thể liên kết cây hỗ trợ tiếp cận của các trình đọc màn hình có hỗ trợ bằng cách thêm [role="tooltip"].

<tool-tip role="tooltip">A tooltip</tool-tip>

Còn đối với trình đọc màn hình, văn bản này được nhận dạng là chú giải công cụ. Hãy xem trong ví dụ sau đây về cách mà phần tử đường liên kết đầu tiên có một phần tử chú thích được nhận dạng trong cây còn phần tử thứ hai thì không? Mục thứ hai không có vai trò này. Trong phần kiểu, chúng ta sẽ cải thiện chế độ xem dạng cây này.

Ảnh chụp màn hình của Cây hỗ trợ tiếp cận của Công cụ của Chrome cho nhà phát triển trình bày HTML. Hiển thị một đường liên kết có văn bản &quot;trên cùng; Có chú giải công cụ: &quot;Xin chào, có một chú giải công cụ!&quot; có thể làm tâm điểm. Bên trong đó là văn bản tĩnh &quot;top&quot; (trên cùng) và một phần tử chú giải công cụ.

Tiếp theo, chúng ta cần đặt phần chú thích để không thể làm tâm điểm. Nếu trình đọc màn hình không hiểu vai trò của chú giải công cụ, thì điều này sẽ cho phép người dùng tập trung vào <tool-tip> để đọc nội dung và trải nghiệm người dùng không cần đến điều này. Trình đọc màn hình sẽ thêm nội dung vào phần tử mẹ và do đó, bạn không cần lấy tiêu điểm để truy cập được. Tại đây, chúng ta có thể sử dụng inert để đảm bảo không người dùng nào vô tình tìm thấy nội dung chú giải công cụ này trong luồng thẻ của họ:

<tool-tip inert role="tooltip">A tooltip</tool-tip>

Một ảnh chụp màn hình khác về Cây hỗ trợ tiếp cận của Công cụ của Chrome cho nhà phát triển, lần này bị thiếu phần tử chú thích.

Sau đó, tôi chọn sử dụng các thuộc tính làm giao diện để chỉ định vị trí của chú giải công cụ. Theo mặc định, tất cả <tool-tip> sẽ giả định vị trí "trên cùng", nhưng bạn có thể tuỳ chỉnh vị trí này trên một phần tử bằng cách thêm tip-position:

<tool-tip role="tooltip" tip-position="right ">A tooltip</tool-tip>

Ảnh chụp màn hình của một đường liên kết có chú thích ở bên phải với nội dung &quot;A tooltip&quot; (Chú giải công cụ).

Tôi thường sử dụng các thuộc tính thay vì lớp cho những mục như thế này để <tool-tip> không thể được gán nhiều vị trí cùng một lúc. Có thể chỉ có một hoặc không có.

Cuối cùng, hãy đặt các phần tử <tool-tip> vào bên trong phần tử bạn muốn cung cấp chú giải công cụ. Ở đây, tôi chia sẻ văn bản alt với người dùng mắt bằng cách đặt hình ảnh và <tool-tip> bên trong phần tử <picture>:

<picture>
  <img alt="The GUI Challenges skull logo" width="100" src="...">
  <tool-tip role="tooltip" tip-position="bottom">
    The <b>GUI Challenges</b> skull logo
  </tool-tip>
</picture>

Ảnh chụp màn hình của một hình ảnh có chú giải công cụ có nội dung &quot;Biểu trưng hình hộp sọ trong Thử thách GUI&quot;.

Ở đây, tôi đặt <tool-tip> bên trong phần tử <abbr>:

<p>
  The <abbr>HTML <tool-tip role="tooltip" tip-position="top">Hyper Text Markup Language</tool-tip></abbr> abbr element.
</p>

Ảnh chụp màn hình của một đoạn văn có gạch chân từ viết tắt HTML và chú giải công cụ phía trên nội dung &quot;Ngôn ngữ đánh dấu siêu văn bản&quot;.

Hỗ trợ tiếp cận

Vì tôi đã chọn xây dựng chú giải công cụ chứ không phải bật/tắt nên phần này sẽ đơn giản hơn nhiều. Trước tiên, hãy để tôi phác thảo trải nghiệm người dùng mong muốn:

  1. Trong không gian hạn chế hoặc giao diện lộn xộn, hãy ẩn các thông báo bổ sung.
  2. Khi người dùng di chuột, lấy tiêu điểm hoặc sử dụng thao tác chạm để tương tác với một phần tử, thông báo sẽ hiển thị.
  3. Khi thao tác di chuột, tiêu điểm hoặc thao tác chạm kết thúc, hãy ẩn tin nhắn trở lại.
  4. Cuối cùng, hãy đảm bảo mọi chuyển động sẽ giảm đi nếu người dùng đã chỉ định một lựa chọn ưu tiên là giảm chuyển động.

Mục tiêu của chúng tôi là thông báo bổ sung theo yêu cầu. Người dùng chuột hoặc bàn phím khi nhìn thấy có thể di chuột để hiển thị tin nhắn và đọc tin nhắn bằng mắt. Người dùng trình đọc màn hình không khiếm thị có thể tập trung để hiển thị tin nhắn, nhận được tin nhắn rõ ràng thông qua công cụ của họ.

Ảnh chụp màn hình MacOS VoiceOver đọc một đường liên kết có phần chú thích

Trong phần trước, chúng ta đã đề cập đến cây hỗ trợ tiếp cận, vai trò và giá trị không hoạt động của chú giải công cụ. Việc còn lại là kiểm thử và xác minh trải nghiệm người dùng hiển thị thông báo trong chú giải công cụ cho người dùng một cách phù hợp. Trong quá trình thử nghiệm, chúng tôi chưa rõ phần nào của thông báo âm thanh là phần chú thích. Bạn cũng có thể thấy văn bản này trong khi gỡ lỗi trong cây hỗ trợ tiếp cận. Văn bản liên kết "top" (trên cùng) sẽ được chạy cùng nhau mà không do dự, với "Look, tooltips!". Trình đọc màn hình không làm hỏng hoặc xác định văn bản là nội dung trong chú giải công cụ.

Ảnh chụp màn hình Cây hỗ trợ tiếp cận của Công cụ của Chrome cho nhà phát triển, trong đó văn bản đường liên kết có nội dung &quot;trên Ok, phần chú thích!&quot;.

Thêm một phần tử giả chỉ dành cho trình đọc màn hình vào <tool-tip> và chúng ta có thể thêm văn bản lời nhắc riêng cho người dùng không nhìn thấy.

&::before {
  content: "; Has tooltip: ";
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

Dưới đây là cây hỗ trợ tiếp cận đã cập nhật, hiện có dấu chấm phẩy sau văn bản đường liên kết và lời nhắc cho chú giải công cụ "Có chú giải công cụ: ".

Ảnh chụp màn hình cập nhật của Cây hỗ trợ tiếp cận trong Công cụ của Chrome cho nhà phát triển, trong đó văn bản đường liên kết đã cải thiện cụm từ &quot;trên cùng; Có chú giải công cụ: &quot;Xin chào, có chú giải công cụ!&quot;.

Giờ đây, khi người dùng trình đọc màn hình lấy tiêu điểm đường liên kết, thông báo sẽ hiển thị "top" (trên cùng) và tạm dừng một chút, sau đó thông báo "has tooltip: Look, tooltips" (có chú giải công cụ: xem, chú giải công cụ). Điều này sẽ cung cấp cho người dùng trình đọc màn hình một vài gợi ý thú vị về trải nghiệm người dùng. Sự do dự giúp phân tách tốt giữa văn bản liên kết và chú thích. Ngoài ra, khi "có chú giải công cụ" được thông báo, người dùng trình đọc màn hình có thể dễ dàng huỷ chú thích nếu họ đã từng nghe trước đó. Thao tác này rất gợi nhớ việc di chuột và di chuột nhanh chóng, vì bạn đã xem thông báo bổ sung. Cảm giác như trải nghiệm người dùng tương đương.

Kiểu

Phần tử <tool-tip> sẽ là phần tử con của phần tử đại diện cho thông điệp bổ sung, vì vậy, trước tiên, hãy bắt đầu với các yếu tố cần thiết cho hiệu ứng lớp phủ. Lấy trường hợp này ra khỏi quy trình tài liệu bằng position absolute:

tool-tip {
  position: absolute;
  z-index: 1;
}

Nếu thành phần mẹ không phải là ngữ cảnh xếp chồng, thì chú giải công cụ sẽ tự định vị ở vị trí gần nhất, không phải là điều chúng ta muốn. Có một bộ chọn mới trên khối có thể hữu ích, đó là :has():

Hỗ trợ trình duyệt

  • 105
  • 105
  • 121
  • 15,4

Nguồn

:has(> tool-tip) {
  position: relative;
}

Đừng lo lắng quá nhiều về khả năng hỗ trợ của trình duyệt. Trước tiên, hãy nhớ rằng các chú giải công cụ này là thông tin bổ sung. Nếu chúng không hoạt động thì cũng không sao. Thứ hai, trong phần JavaScript, chúng ta sẽ triển khai một tập lệnh để polyfill chức năng chúng ta cần cho các trình duyệt không hỗ trợ :has().

Tiếp theo, hãy làm cho chú giải công cụ không mang tính tương tác để chúng không đánh cắp các sự kiện con trỏ từ phần tử mẹ:

tool-tip {
  …
  pointer-events: none;
  user-select: none;
}

Sau đó, hãy ẩn chú giải công cụ bằng độ mờ để chúng ta có thể chuyển đổi chú giải công cụ bằng tính năng làm mờ:

tool-tip {
  opacity: 0;
}

:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
}

:is():has() sẽ thực hiện phần công việc khó khăn ở đây, giúp tool-tip chứa các phần tử mẹ nhận biết được khả năng tương tác của người dùng khi chuyển đổi chế độ hiển thị của chú giải công cụ con. Người dùng chuột có thể di chuột, người dùng bàn phím và trình đọc màn hình có thể lấy tiêu điểm, còn người dùng chạm vào có thể nhấn.

Khi lớp phủ hiện và ẩn hoạt động với người dùng bình thường, đã đến lúc thêm một số kiểu để tuỳ chỉnh giao diện, định vị và thêm hình tam giác vào bong bóng trò chuyện. Các kiểu sau bắt đầu sử dụng các thuộc tính tuỳ chỉnh, xây dựng dựa trên vị trí hiện tại của chúng ta, đồng thời thêm bóng, kiểu chữ và màu sắc để trông giống như một chú giải công cụ nổi:

Ảnh chụp màn hình của phần chú thích ở chế độ tối, nổi trên đường liên kết &quot;block-start&quot;.

tool-tip {
  --_p-inline: 1.5ch;
  --_p-block: .75ch;
  --_triangle-size: 7px;
  --_bg: hsl(0 0% 20%);
  --_shadow-alpha: 50%;

  --_bottom-tip: conic-gradient(from -30deg at bottom, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) bottom / 100% 50% no-repeat;
  --_top-tip: conic-gradient(from 150deg at top, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) top / 100% 50% no-repeat;
  --_right-tip: conic-gradient(from -120deg at right, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) right / 50% 100% no-repeat;
  --_left-tip: conic-gradient(from 60deg at left, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) left / 50% 100% no-repeat;

  pointer-events: none;
  user-select: none;

  opacity: 0;
  transform: translateX(var(--_x, 0)) translateY(var(--_y, 0));
  transition: opacity .2s ease, transform .2s ease;

  position: absolute;
  z-index: 1;
  inline-size: max-content;
  max-inline-size: 25ch;
  text-align: start;
  font-size: 1rem;
  font-weight: normal;
  line-height: normal;
  line-height: initial;
  padding: var(--_p-block) var(--_p-inline);
  margin: 0;
  border-radius: 5px;
  background: var(--_bg);
  color: CanvasText;
  will-change: filter;
  filter:
    drop-shadow(0 3px 3px hsl(0 0% 0% / var(--_shadow-alpha)))
    drop-shadow(0 12px 12px hsl(0 0% 0% / var(--_shadow-alpha)));
}

/* create a stacking context for elements with > tool-tips */
:has(> tool-tip) {
  position: relative;
}

/* when those parent elements have focus, hover, etc */
:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
  transition-delay: 200ms;
}

/* prepend some prose for screen readers only */
tool-tip::before {
  content: "; Has tooltip: ";
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

/* tooltip shape is a pseudo element so we can cast a shadow */
tool-tip::after {
  content: "";
  background: var(--_bg);
  position: absolute;
  z-index: -1;
  inset: 0;
  mask: var(--_tip);
}

/* top tooltip styles */
tool-tip:is(
  [tip-position="top"],
  [tip-position="block-start"],
  :not([tip-position]),
  [tip-position="bottom"],
  [tip-position="block-end"]
) {
  text-align: center;
}

Điều chỉnh giao diện

Chú giải công cụ chỉ có một vài màu sắc để quản lý vì màu văn bản được kế thừa từ trang thông qua từ khoá hệ thống CanvasText. Ngoài ra, vì đã tạo các thuộc tính tuỳ chỉnh để lưu trữ giá trị, nên chúng ta chỉ có thể cập nhật các thuộc tính tuỳ chỉnh đó và cho phép giao diện xử lý phần còn lại:

@media (prefers-color-scheme: light) {
  tool-tip {
    --_bg: white;
    --_shadow-alpha: 15%;
  }
}

Ảnh chụp màn hình cạnh nhau về phiên bản sáng và tối của chú giải công cụ.

Đối với giao diện sáng, chúng tôi điều chỉnh nền thành màu trắng và làm cho bóng trở nên bớt mạnh bằng cách điều chỉnh độ mờ của nền.

Phải sang trái

Để hỗ trợ chế độ đọc từ phải sang trái, thuộc tính tuỳ chỉnh sẽ lưu trữ giá trị của hướng tài liệu thành giá trị -1 hoặc 1 tương ứng.

tool-tip {
  --isRTL: -1;
}

tool-tip:dir(rtl) {
  --isRTL: 1;
}

Công cụ này có thể được dùng để hỗ trợ việc đặt chú thích:

tool-tip[tip-position="top"]) {
  --_x: calc(50% * var(--isRTL));
}

Cũng như hỗ trợ vị trí của tam giác:

tool-tip[tip-position="right"]::after {
  --_tip: var(--_left-tip);
}

tool-tip[tip-position="right"]:dir(rtl)::after {
  --_tip: var(--_right-tip);
}

Cuối cùng, bạn cũng có thể dùng phép biến đổi logic trên translateX():

--_x: calc(var(--isRTL) * -3px * -1);

Vị trí phần chú thích

Đặt chú giải công cụ một cách hợp lý với các thuộc tính inset-block hoặc inset-inline để xử lý cả vị trí của chú giải công cụ thực tế và vị trí logic. Đoạn mã sau đây cho biết cách mỗi vị trí trong số 4 vị trí đó được tạo kiểu cho cả hướng từ trái sang phải và hướng từ phải sang trái.

Căn chỉnh phần trên cùng và bắt đầu theo khối

Ảnh chụp màn hình cho thấy sự khác biệt về vị trí giữa vị trí trên cùng từ trái sang phải và vị trí trên cùng từ phải sang trái.

tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position])) {
  inset-inline-start: 50%;
  inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-size));
  --_x: calc(50% * var(--isRTL));
}

tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position]))::after {
  --_tip: var(--_bottom-tip);
  inset-block-end: calc(var(--_triangle-size) * -1);
  border-block-end: var(--_triangle-size) solid transparent;
}

Căn phải và cùng dòng

Ảnh chụp màn hình cho thấy sự khác biệt về vị trí giữa vị trí cùng dòng từ trái sang phải và vị trí kết thúc cùng dòng từ phải sang trái.

tool-tip:is([tip-position="right"], [tip-position="inline-end"]) {
  inset-inline-start: calc(100% + var(--_p-inline) + var(--_triangle-size));
  inset-block-end: 50%;
  --_y: 50%;
}

tool-tip:is([tip-position="right"], [tip-position="inline-end"])::after {
  --_tip: var(--_left-tip);
  inset-inline-start: calc(var(--_triangle-size) * -1);
  border-inline-start: var(--_triangle-size) solid transparent;
}

tool-tip:is([tip-position="right"], [tip-position="inline-end"]):dir(rtl)::after {
  --_tip: var(--_right-tip);
}

Căn chỉnh dưới cùng và cuối khối

Ảnh chụp màn hình cho thấy sự khác biệt về vị trí giữa vị trí dưới cùng từ trái sang phải và vị trí kết thúc khối từ phải sang trái.

tool-tip:is([tip-position="bottom"], [tip-position="block-end"]) {
  inset-inline-start: 50%;
  inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-size));
  --_x: calc(50% * var(--isRTL));
}

tool-tip:is([tip-position="bottom"], [tip-position="block-end"])::after {
  --_tip: var(--_top-tip);
  inset-block-start: calc(var(--_triangle-size) * -1);
  border-block-start: var(--_triangle-size) solid transparent;
}

Căn chỉnh trái và cùng dòng

Ảnh chụp màn hình cho thấy sự khác biệt về vị trí giữa vị trí bên trái từ trái sang phải và vị trí bắt đầu cùng dòng từ phải sang trái.

tool-tip:is([tip-position="left"], [tip-position="inline-start"]) {
  inset-inline-end: calc(100% + var(--_p-inline) + var(--_triangle-size));
  inset-block-end: 50%;
  --_y: 50%;
}

tool-tip:is([tip-position="left"], [tip-position="inline-start"])::after {
  --_tip: var(--_right-tip);
  inset-inline-end: calc(var(--_triangle-size) * -1);
  border-inline-end: var(--_triangle-size) solid transparent;
}

tool-tip:is([tip-position="left"], [tip-position="inline-start"]):dir(rtl)::after {
  --_tip: var(--_left-tip);
}

Hoạt ảnh

Hiện tại, chúng tôi chỉ mới bật chế độ hiển thị của phần chú thích. Trong phần này, trước tiên, chúng tôi sẽ tạo ảnh động về độ mờ cho tất cả người dùng, vì đây là quá trình chuyển đổi chuyển động giảm an toàn thường. Sau đó, chúng ta sẽ tạo ảnh động cho vị trí biến đổi để chú giải công cụ xuất hiện trượt ra từ phần tử mẹ.

Chuyển đổi mặc định an toàn và có ý nghĩa

Tạo kiểu cho phần tử chú giải công cụ thành độ mờ và biến đổi chuyển đổi, như sau:

tool-tip {
  opacity: 0;
  transform: translateX(var(--_x, 0)) translateY(var(--_y, 0));
  transition: opacity .2s ease, transform .2s ease;
}

:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
  transition-delay: 200ms;
}

Thêm chuyển động vào hiệu ứng chuyển cảnh

Đối với mỗi bên, một chú giải công cụ có thể xuất hiện. Nếu người dùng ổn định với chuyển động, hãy định vị nhẹ thuộc tính translationX bằng cách cho nó một khoảng cách nhỏ để di chuyển từ:

@media (prefers-reduced-motion: no-preference) {
  :has(> tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position]))):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_y: 3px;
  }

  :has(> tool-tip:is([tip-position="right"], [tip-position="inline-end"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_x: -3px;
  }

  :has(> tool-tip:is([tip-position="bottom"], [tip-position="block-end"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_y: -3px;
  }

  :has(> tool-tip:is([tip-position="left"], [tip-position="inline-start"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_x: 3px;
  }
}

Lưu ý rằng thao tác này đang đặt trạng thái "out" do trạng thái "in" nằm ở translateX(0).

JavaScript

Theo tôi, JavaScript là không bắt buộc. Lý do là không có phần chú thích nào trong số này cần phải đọc để hoàn thành một thao tác trong giao diện người dùng. Nếu chú giải công cụ có lỗi hoàn toàn, thì cũng không sao. Điều này cũng có nghĩa là chúng tôi có thể xem chú thích được cải tiến dần dần. Cuối cùng, mọi trình duyệt sẽ hỗ trợ :has() và tập lệnh này có thể hoàn toàn biến mất.

Tập lệnh polyfill thực hiện hai việc và chỉ hoạt động nếu trình duyệt không hỗ trợ :has(). Trước tiên, hãy kiểm tra xem :has() có hỗ trợ không:

if (!CSS.supports('selector(:has(*))')) {
  // do work
}

Tiếp theo, hãy tìm các phần tử mẹ của <tool-tip> và đặt tên lớp cho các phần tử đó để sử dụng:

if (!CSS.supports('selector(:has(*))')) {
  document.querySelectorAll('tool-tip').forEach(tooltip =>
    tooltip.parentNode.classList.add('has_tool-tip'))
}

Tiếp theo, hãy chèn một tập hợp các kiểu sử dụng tên lớp đó, mô phỏng bộ chọn :has() cho cùng một hành vi:

if (!CSS.supports('selector(:has(*))')) {
  document.querySelectorAll('tool-tip').forEach(tooltip =>
    tooltip.parentNode.classList.add('has_tool-tip'))

  let styles = document.createElement('style')
  styles.textContent = `
    .has_tool-tip {
      position: relative;
    }
    .has_tool-tip:is(:hover, :focus-visible, :active) > tool-tip {
      opacity: 1;
      transition-delay: 200ms;
    }
  `
  document.head.appendChild(styles)
}

Vậy là xong, giờ đây tất cả trình duyệt sẽ sẵn sàng hiển thị phần chú thích nếu :has() không được hỗ trợ.

Kết luận

Giờ bạn đã biết cách thực hiện điều đó, bạn sẽ làm như thế nào 🙂 Tôi thực sự đang mong chờ API popup để giúp nút bật/tắt dễ dàng hơn, lớp trên cùng để không có cuộc chiến chỉ mục z và API anchor để định vị mọi thứ trong cửa sổ tốt hơn. Cho đến lúc đó, tôi sẽ tạo phần chú thích.

Hãy đa dạng hoá phương pháp tiếp cận của chúng ta và tìm hiểu tất cả các cách xây dựng trên web.

Hãy tạo một bản minh hoạ, đường liên kết tweet me và tôi sẽ thêm bản phối lại đó vào phần bản phối lại của cộng đồng bên dưới!

Bản phối lại của cộng đồng

Chưa có nội dung nào để xem ở đây.

Tài nguyên