Dodaj do swojej witryny wydajne, interaktywne efekty odkrywania za pomocą masek CSS i zarejestrowanych właściwości niestandardowych. Używając gradientu promieniowego jako maski i rejestrując jego wartości punktów, możemy płynnie przechodzić między wejściem i wyjściem, śledząc wskaźnik użytkownika przy minimalnym użyciu JavaScriptu.
Implementacja
1. Rejestrowanie właściwości niestandardowych
Aby umożliwić płynną interpolację wartości punktów gradientu, musisz zarejestrować zmienne za pomocą @property. Informuje to silnik przeglądarki o typie danych, umożliwiając mu przechodzenie między wartościami podczas aktualizacji.
/* Register the spotlight inner and outer sizes to enable interpolation */
@property --inner-size{
syntax: "<length-percentage>";
inherits: true;
initial-value: 0px;
}
@property --outer-size{
syntax: "<length-percentage>";
inherits: true;
initial-value: 0px;
}
Właściwości niestandardowe śledzące pozycję wskaźnika nie muszą być przenoszone, więc nie trzeba ich rejestrować.
2. Definiowanie warstwy maskowania
Zastosuj mask-image do elementu, który chcesz wyświetlić. Użyj radial-gradient, który odwołuje się do zarejestrowanych usług.
.reveal-layer {
/* Only transition the size properties, NOT the position variables */
transition: --inner-size 0.2s ease-in-out, --outer-size 0.2s ease-in-out;
/* The spotlight is defined by the transparent center of the mask */
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
black var(--inner-size, 0%),
transparent var(--outer-size, 0%)
);
/* Ensure the mask doesn't repeat if the element is large */
mask-repeat: no-repeat;
/* Make the mask layer non-interactive */
pointer-events: none;
}
/* Update the gradients stops on interaction */
.reveal-layer:hover {
--inner-size: 100px;
--outer-size: 120px;
}
3. Aktualizowanie współrzędnych za pomocą JavaScriptu
Śledź pozycję wskaźnika i aktualizuj zmienne CSS. Właściwości są zarejestrowane i mają zdefiniowaną wartość transition, więc podświetlenie będzie się płynnie przesuwać, nawet jeśli zdarzenia wskaźnika będą rzadkie.
const container = document.querySelector('.container');
// Store the container's bounding rect
let rect = container.getBoundingClientRect();
// Update the rect when the container is resized
const resizeObserver = new ResizeObserver(()=>{
rect = container.getBoundingClientRect();
})
resizeObserver.observe(container);
container.addEventListener('pointermove', (e) => {
// Calculate position as a percentage of the container.
const x = ((e.clientX - rect.left) / rect.width) * 100;
const y = ((e.clientY - rect.top) / rect.height) * 100;
// Update the registered properties
container.style.setProperty('--mouse-x', `${x}%`);
container.style.setProperty('--mouse-y', `${y}%`);
});
4. Ułatwienia dostępu i interakcja
OBOWIĄZKOWA gwarancja ułatwień dostępu: ten wzorzec opiera się na interakcjach ze wskaźnikiem, aby wyświetlić wizualne wyróżnienie. MUSISZ zagwarantować, że wszystkie treści pod spodem pozostaną w pełni widoczne, czytelne i niezależnie dostępne za pomocą klawiatury w domyślnym układzie, a warstwa wyróżnienia będzie używana wyłącznie jako nieistotne ulepszenie wizualne dla użytkowników korzystających ze wskaźnika. Nigdy nie używaj tego efektu do ukrywania lub blokowania istotnych treści przed użytkownikami korzystającymi tylko z klawiatury lub technologii wspomagających osoby z niepełnosprawnością.
- Zdarzenia wskaźnika: ustaw
pointer-events: nonena warstwie nakładki maski, aby umożliwić standardowe interakcje kliknięcia i dotknięcia w celu przejścia do elementów sterujących poniżej. - Zastąpienie ustawienia Mniej animacji: wyłącz płynną interpolację przejść w przypadku użytkowników, którzy proszą o ograniczenie animacji.
/* MANDATORY Copy-Paste Safety: Disable transition scaling for motion-sensitive users */
@media (prefers-reduced-motion: reduce) {
.reveal-layer {
transition: none !important;
}
}
Strategie zastępcze
Kreacja zastępcza dla niezarejestrowanej usługi
Przeglądarki, które obsługują mask-image, ale nie @property, nadal będą wyświetlać wyróżnienie, ale ruch będzie przeskakiwać między stanem włączenia i wyłączenia, ponieważ nie mogą interpolować wartości wewnątrz radial-gradient. Podaj wartości zastępcze, gdy używasz var().
.reveal-layer {
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
/* Use fallback values when using the `var()` function for browsers that don't get an initial value from the @property registration. */
black var(--inner-size, 0%),
transparent var(--outer-size, 0%)
);
}
Podstawowa obsługa masek
W przypadku przeglądarek, które w ogóle nie obsługują masek CSS:
- Właściwość z prefiksami: użyj właściwości z prefiksami
-webkit-mask-image, aby zapewnić obsługę w większej liczbie przeglądarek. - Progresywne ulepszanie: zaprojektuj podstawowy stan interfejsu tak, aby był w pełni funkcjonalny i czytelny bez efektu ujawniania. Jest to przydatne, gdy efekt tylko dodaje atrakcyjności wizualnej, ale nie jest wymagany do odczytania treści.