Interaktywne odkrywanie treści

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: none na 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:

  1. 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.
  2. 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.