Kategoria:CSS

Preferencje użytkownika a CSS, na co warto zwracać uwagę?

  • Czas potrzebny na przeczytanie:5 minut
  • Opublikowane:8 listopada 2021

Słuchaj swoich użytkowników. Ta porada jest jedną z najważniejszych, jeśli chcemy usprawnić User Experience naszej aplikacji. Jak przez pryzmat preferencji użytkownika dostosowywać swoje produkty korzystając z nowoczesnych media queries?

Ograniczenia ruchu

Animacje, bo o nich mowa, najczęściej nie są niczym złym - często poprawiają wrażenia z korzystania z naszej strony. No ale jak to już bywa w programowaniu, nic nie jest czarno-białe. Niektórzy użytkownicy nie chcą bądź nie mogą patrzeć np. na szybko poruszające się elementy na stronie. Tacy użytkownicy często borykają się z niepełnosprawnościami poznawczymi...

Kuce z bronksu - ja lubie szypko, a ja lubie wolmo

Na szczęście jest na to sposób! Możemy skorzystać z preferencji ograniczenia ruchu i oszczędzić bólu głowy naszym użytkownikom. Jak to działa? Użytkownik włącza w systemie operacyjnym opcje redukowania ruchu, a my wykrywamy to z pomocą specjalnych media queries.

W @prefers-reduced-motion możemy rozróżnić dwa stany - no-preference i reduce. Załóżmy, że na naszej stronie chcemy mieć box, który będzie się obracał w konkretny sposób przez półtorej sekundy:

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.box {
  animation: spin 1.5s linear infinite both;
}

Aby usunąć animacje, gdy ograniczenia ruchu będą ustawione na reduce, wystarczy zrobić:

@media screen and (prefers-reduced-motion: reduce) {
  .box {
    animation: none;
  }
}

Warto pamiętać, że @prefers-reduced-motion nie ogranicza nas w żadnym stopniu. Nie musimy również kasować całej animacji, możemy ją tylko zredukować, o ile i w jaki sposób, to już zależy od konkretnego przypadku.

Kolejnym praktycznym zastosowaniem dla tego media query może być odtwarzanie filmu. Jak może wiesz, autoplay nie jest uznawany za dobrą praktykę, jeśli chodzi o video. Niestety czasem "nie mamy wyboru" i musimy umieścić film na stronie, który będzie autoodtwarzany, najczęściej w formie jakiegoś tła.

Porównanie wyglądu odtwarzacza wideo z i bez ograniczeń ruchu
<video src="..." type="video/mp4" controls />

Chcemy, aby nasz film odtwarzał się automatycznie, jeśli wartość @prefers-reduced-motion w systemie jest ustawiona na no-preference. Jeśli użytkownik będzie chciał mieć zredukowany ruch, zatrzymamy autoodtwarzanie. Jak to ogarnąć? Wystarczy nam kilka linijek w JS:

const video = document.querySelector('video');

// Sprawdzamy, czy ruch jest zredukowany
const isReducedMotionEnabled = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

if (isReduceMotionEnabled) {
  // Jeśli tak, wywalamy atrybut autoplay
  video.setAttribute('autoplay', false);
} else {
  // Jeśli nie, ustawiamy odtwarzanie na automatyczne
  video.setAttribute('autoplay', true);
}

Preferencje motywu

Na pewno znane Ci dark i light themes oraz odwieczna wojna użytkowników i programistów o to, który z nich jest lepszy w przeglądarce, na stronie internetowej, a który w IDE...

Którą stronę obrać? Jeśli mam wybierać między złem a złem... Najlepiej nie wybierać wcale i przygotować dwie wersje tak, aby każdy był zadowolony. Dzięki @prefers-color-scheme mamy możliwość wykrycia preferowanego motywu w systemie:

:root {
  --color-background: #ffffff;
  --color-text: #000000;
}

@media screen and (prefers-color-scheme: dark) {
  :root {
    --color-background: #000000;
    --color-text: #ffffff;
  }
}

Do wyboru mamy opcje dark i light. Przy obsłudze więcej niż jednego motywu (i nie tylko) Twoim najlepszym przyjacielem będą CSS Variables. Jeśli jeszcze o nich nie słyszałeś, to sprawdź koniecznie mój artykuł na ten temat.

Redukowanie danych

Chociaż ciężko w to uwierzyć, ale w 2021 roku, niektórzy użytkownicy internetu, mogą nie mieć szybkiego łącza internetowego lub mają ściśle określony transfer do wykorzystania. Takie osoby mogą chcieć zredukować ilość pobieranych danych ze względu na oszczędność ich zasobów. Z pomocą przychodzi @prefers-reduced-data.

Weźmy za przykład twitterowy post, normalnie, poza samą treścią, wyświetlane jest jeszcze zdjęcie profilowe użytkownika oraz u niektórych etykieta zweryfikowanego usera.

W naszym przypadku, gdy użytkownik ustawi wartość media query na reduce, chcielibyśmy wyświetlać tylko najważniejsze informacje, czyli autora i treść posta, bez zbędnych zdjęć, tak aby ograniczyć transfer do minimum.

.avatar {
}
.approved-icon {
}
.code-snippet {
}

@media screen and (prefers-reduced-data: reduce) {
  .avatar,
  .approved-icon,
  .code-snippet {
    display: none;
  }
}

Oczywiście takie rozwiązanie nie jest idealne... Często obrazki w tweetach są niezbędne do zrozumienia przekazu całego posta, więc fajnie by było wrzucić tutaj chociażby tekst alternatywny.

Innym, bardziej uniwersalnym przypadkiem, może być ładowanie fontów. Często na swoje strony ładujemy wiele różnych, customowych fontów. Dla użytkowników, którzy chcą zużywać jak najmniej danych, dobrą opcją będzie zastąpienie niestandardowych, tymi systemowymi:

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
    'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}

@media (prefers-reduced-data: no-preference) {
  @font-face {
    font-family: LeagueMono;
    src: url('/fonts/LeagueMono-Regular.woff2') format('woff2');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
  }

  body {
    font-family: 'LeagueMono';
  }
}

@prefers-reduced-data jest obecnie w bardzo wczesnej fazie rozwoju, wsparcie dla tej media query możesz śledzić na Can I Use.

Ustawienia kontrastu

Minimalny kontrast pomiędzy tekstem a tłem określa standard WCAG 2.0, jest on podzielony na dwa poziomy:

  • AA - dla normalnego tekstu kontrast powinien wynosić przynajmniej 4.5:1
  • AAA - dla normalnego tekstu kontrast powinien wynosić przynajmniej 7:1

Jak to się ma do naszych preferencji kontrastu? Dzięki @prefers-contrast możemy wykryć, że użytkownik potrzebuje więcej kontrastu i na bazie tego podbić kontrast z poziomu AA do AAA:

/* Kontrast 4.59:1, poziom AA */
.box {
  background-color: #ffffff;
}

.text {
  color: #387e94;
}

/* Kontrast 21:1, poziom AAA */
@media (prefers-contrast: more) {
  .box {
    background-color: #000000;
  }

  .text {
    color: #ffffff;
  }
}

Preferencje kontrastu to nie tylko kolory! Zamiast zmieniać ich poziom, możemy dostosować inne elemnty UI, taki jak np. border, aby były bardziej wyraziste:

.box {
  outline: 2px dashed black;
}

@media (prefers-contrast: more) {
  .box {
    outline: 2px solid black;
  }
}

@prefers-contrast jest obecnie w bardzo wczesnej fazie rozwoju, wsparcie dla tej media query możesz śledzić na Can I Use.

Zredukowana transparentość

Last but not least - czyli preferencje dotyczące transparentności. Dzięki @prefers-reduced-transparency możemy wskazać, w jakim stopniu dany element UI będzie transparenty:

.box {
  background: #000000;
  opacity: 0.5;
}

@media (prefers-reduced-transparency: reduce) {
  .box {
    opacity: 1;
  }
}

@prefers-reduced-transparency jest obecnie w bardzo wczesnej fazie rozwoju, wsparcie dla tej media query możesz śledzić na Can I Use.

Podsumowanie

To by było na tyle, jeśli chodzi o preferencje użytkownika w CSS 😎 Według mnie najważniejszą z nich jest ta pierwsza, ograniczenia ruchu to coś, co powinieneś mieć na swojej stronie, jeśli korzystasz z animacji!

Celowo pominąłem jedną preferencje - forced-colors. Jest ona według mnie tak abstrakcyjna, że nie znalazłem żadnego sensownego wytłumaczenia na jej użycie 🙄 Jeśli przychodzi Ci jakieś do głowy, to koniecznie daj znać.

Do usłyszenia!

Źródła

O autorze

Olaf Sulich

Olaf jest Frontend Developerem, blogerem i nosi rybacki kapelusz 🎩 Pisze o wszystkim co związane z frontendem, ale nie boi się backendu i designów 🦾 Ma głowę pełną pomysłów i nadzieję, że znajdziesz tutaj coś dla siebie!