W Polsce żyje około 3 miliony osób z różnymi dysfunkcjami wzroku. Nie wszystkie z nich korzystają z czytników ekranowych - wiele osób po prostu potrzebuje większego tekstu. Kryterium WCAG 1.4.4 “Resize Text” określa minimalne wymagania, które Twoja strona musi spełnić, aby była dostępna dla tej grupy użytkowników.

Czym jest kryterium WCAG 1.4.4?

WCAG 1.4.4 “Resize Text” to jedno z kryteriów sukcesu na poziomie AA, który jest wymagany przez większość przepisów dotyczących dostępności cyfrowej, w tym europejską dyrektywę o dostępności stron internetowych.

Wymaganie brzmi: Tekst (z wyjątkiem napisów i obrazów tekstu) może być powiększony do 200% bez użycia technologii wspomagających i bez utraty treści lub funkcjonalności.

To oznacza, że użytkownik musi móc:

  • Powiększyć tekst za pomocą wbudowanych funkcji przeglądarki
  • Nie stracić dostępu do żadnej treści
  • Zachować pełną funkcjonalność strony
Poziom WCAGPowiększenieKryterium
A100%Brak wymagań
AA200%WCAG 1.4.4 Resize Text
AAA400%+WCAG 1.4.10 Reflow

Wyjątki od reguły

Kryterium nie dotyczy:

  • Napisów (captions) - teksty w filmach
  • Obrazów tekstu - tekst osadzony w grafikach (choć należy ich unikać)

Dlaczego powiększanie tekstu jest ważne?

Różnorodność użytkowników

Osoby potrzebujące większego tekstu to nie tylko osoby niewidome korzystające z czytników ekranowych. To także:

  • Osoby słabowidzące - widzą, ale potrzebują powiększenia
  • Seniorzy - starzenie się wpływa na wzrok
  • Osoby z czasowymi problemami - zmęczenie oczu, migrena, praca przy słabym oświetleniu
  • Użytkownicy mobilni - małe ekrany w słonecznym świetle

Wymagania prawne

Od 2021 roku strony podmiotów publicznych w Polsce muszą spełniać WCAG 2.1 na poziomie AA zgodnie z ustawą o dostępności cyfrowej. Dyrektywa European Accessibility Act rozszerza te wymagania na sektor prywatny od 2025 roku.

Wpływ na SEO

Google coraz bardziej premiuje dostępne strony. Dobre praktyki dostępności często pokrywają się z dobrymi praktykami optymalizacji stron - responsywność, semantyczny HTML, czytelna typografia.

Jednostki CSS: klucz do skalowania tekstu

Wybór jednostek CSS dla rozmiaru tekstu to fundament dostępności. Jednostki dzielą się na absolutne i względne.

Jednostki absolutne - unikaj dla font-size

/* Źle - nie skaluje się z preferencjami użytkownika */
body {
  font-size: 16px;
}

h1 {
  font-size: 32px;
}

Piksele (px) i punkty (pt) są jednostkami absolutnymi. Oznacza to, że tekst o rozmiarze 16px zawsze będzie miał dokładnie 16 pikseli, niezależnie od ustawień użytkownika w przeglądarce.

Problem: Gdy użytkownik zmieni domyślny rozmiar tekstu w ustawieniach przeglądarki (np. z 16px na 20px), tekst w pikselach nie zostanie powiększony.

Jednostki względne - preferowane

/* Dobrze - skaluje się z preferencjami użytkownika */
:root {
  font-size: 100%; /* Respektuje ustawienia przeglądarki */
}

body {
  font-size: 1rem;
}

h1 {
  font-size: 2.5rem;
}
JednostkaTypWzględem czegoSkalowanieRekomendacja
pxAbsolutna-NieUnikać dla font-size
ptAbsolutna-NieTylko druk
remWzględnaRoot elementTakPreferowana
emWzględnaElement rodzicaTakDla komponentów
%WzględnaElement rodzicaTakAlternatywa
vw/vhViewportSzerokość/wysokość oknaCzęściowoOstrożnie, z clamp()

Praktyczny system typografii

/* Bazowy rozmiar - respektuje preferencje użytkownika */
:root {
  font-size: 100%; /* Domyślnie 16px, ale skaluje się */
}

body {
  font-size: 1rem;
  line-height: 1.6;
}

/* Nagłówki w rem - proporcjonalne skalowanie */
h1 { font-size: 2.5rem; }  /* 40px przy domyślnych */
h2 { font-size: 2rem; }    /* 32px */
h3 { font-size: 1.5rem; }  /* 24px */
h4 { font-size: 1.25rem; } /* 20px */

/* Tekst pomocniczy */
small, .text-sm { font-size: 0.875rem; } /* 14px */

Fluid typography z clamp()

Funkcja clamp() pozwala na płynne skalowanie tekstu między minimalną a maksymalną wartością:

/* Fluid typography - płynnie skaluje się z viewportem */
h1 {
  /* min: 1.5rem, preferowane: 4vw + 1rem, max: 3rem */
  font-size: clamp(1.5rem, 4vw + 1rem, 3rem);
}

p {
  font-size: clamp(1rem, 2vw + 0.5rem, 1.25rem);
}

Uwaga: Używając jednostek viewport (vw, vh), zawsze stosuj clamp() z wartościami w rem, aby zapewnić minimalne i maksymalne rozmiary, które skalują się z preferencjami użytkownika.

Viewport meta: czego unikać

Tag <meta name="viewport"> kontroluje, jak strona jest wyświetlana na urządzeniach mobilnych. Niewłaściwa konfiguracja może całkowicie zablokować możliwość powiększania.

Poprawna konfiguracja

<meta name="viewport" content="width=device-width, initial-scale=1">

To wszystko, czego potrzebujesz. Ta konfiguracja:

  • Ustawia szerokość na szerokość urządzenia
  • Startuje ze skalą 1:1
  • Nie blokuje możliwości powiększania

Błędy naruszające WCAG 1.4.4

<!-- BŁĄD: Całkowicie blokuje pinch-to-zoom -->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

<!-- BŁĄD: Ogranicza maksymalne powiększenie do 100% -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

<!-- BŁĄD: Kombinacja obu problemów -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

Dlaczego to problem?

  • user-scalable=no - całkowicie wyłącza gest pinch-to-zoom na iOS
  • maximum-scale=1 - ogranicza maksymalne powiększenie do 100%
  • Na iOS Safari te ograniczenia są respektowane
  • Android Chrome od wersji 32 ignoruje user-scalable=no, ale nie polegaj na tym

Częsty argument (i dlaczego jest błędny)

“Muszę zablokować zoom, bo formularz się psuje przy powiększeniu”

To nie jest rozwiązanie - to ukrywanie problemu. Jeśli formularz nie działa przy 200% zoom, to formularz wymaga naprawy, a nie blokowania dostępności.

Kontenery z tekstem: overflow i wysokość

Kolejnym częstym problemem są kontenery z ograniczoną wysokością, które obcinają tekst przy powiększeniu.

Problem: sztywna wysokość

/* Źle - tekst zostanie ucięty przy powiększeniu */
.card {
  height: 200px;
  overflow: hidden;
}

.card-description {
  max-height: 80px;
  overflow: hidden;
}

Przy powiększeniu do 200% tekst w kontenerze o stałej wysokości zostanie obcięty, a użytkownik straci dostęp do części treści.

Rozwiązanie: elastyczne kontenery

/* Dobrze - kontener rośnie z tekstem */
.card {
  min-height: 200px; /* Minimum, ale może rosnąć */
  /* Brak overflow: hidden */
}

.card-description {
  /* Brak ograniczeń wysokości */
}

Wyjątek: świadome obcinanie z dostępem do pełnej treści

Czasami potrzebujesz pokazać tylko fragment tekstu (np. preview artykułu). To jest akceptowalne, jeśli pełna treść jest dostępna gdzie indziej:

/* OK - preview z linkiem do pełnej treści */
.article-preview {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
<article class="article-preview">
  <p>Początek artykułu, który może być długi...</p>
</article>
<a href="/pelny-artykul/">Czytaj więcej</a>

Problematyczne wzorce

Unikaj tych wzorców bez alternatywnego dostępu do treści:

/* Źle - obcina tekst bez ostrzeżenia */
.bio {
  height: 100px;
  overflow: hidden;
}

/* Źle - tooltip znika przy powiększeniu */
.tooltip {
  position: absolute;
  max-height: 50px;
  overflow: hidden;
}

Responsive Design a dostępność

Responsive Web Design i dostępność idą w parze, ale same breakpointy nie wystarczą.

Media queries nie zastąpią jednostek względnych

/* To NIE jest rozwiązanie dla WCAG 1.4.4 */
@media (max-width: 768px) {
  body { font-size: 14px; } /* Nadal px! */
}

@media (max-width: 480px) {
  body { font-size: 12px; }
}

Powyższy kod zmienia rozmiar tekstu na różnych urządzeniach, ale nadal używa pikseli - użytkownik nie może zwiększyć tekstu ponad określone wartości.

Prawidłowe podejście

/* Bazowy rozmiar w jednostkach względnych */
body {
  font-size: 1rem;
}

/* Zwiększenie dla większych ekranów - nadal w rem */
@media (min-width: 1200px) {
  body {
    font-size: 1.125rem;
  }
}

Testowanie przy różnych powiększeniach

Pamiętaj, że powiększenie 200% to nie to samo co mniejszy ekran:

  • Breakpoint 768px - przeglądarka na tablecie
  • Zoom 200% - użytkownik z powiększeniem na desktopie

Przy zoom 200% na ekranie 1920px szerokości, efektywna szerokość to 960px. Ale to nie jest to samo co tablet - użytkownik ma myszkę, większy ekran fizyczny i inne oczekiwania.

Implementacja kontrolek rozmiaru tekstu

Choć przeglądarka oferuje wbudowane funkcje powiększania, niektóre strony implementują własne kontrolki A+/A-. To może być pomocne dla użytkowników, którzy nie znają skrótów klawiszowych.

Wzorzec HTML z dostępnością

<div class="font-controls" role="group" aria-label="Rozmiar tekstu">
  <button
    type="button"
    id="font-decrease"
    aria-label="Zmniejsz rozmiar tekstu"
  >
    A-
  </button>
  <button
    type="button"
    id="font-reset"
    aria-label="Przywróć domyślny rozmiar tekstu"
  >
    A
  </button>
  <button
    type="button"
    id="font-increase"
    aria-label="Zwiększ rozmiar tekstu"
  >
    A+
  </button>
</div>

JavaScript z persystencją

const FONT_SIZES = ['87.5%', '100%', '112.5%', '125%', '150%'];
const DEFAULT_INDEX = 1; // 100%
const STORAGE_KEY = 'userFontSize';

let currentIndex = DEFAULT_INDEX;

function setFontSize(index) {
  currentIndex = Math.max(0, Math.min(index, FONT_SIZES.length - 1));
  document.documentElement.style.fontSize = FONT_SIZES[currentIndex];
  localStorage.setItem(STORAGE_KEY, currentIndex.toString());

  // Aktualizuj stan przycisków
  updateButtonStates();
}

function updateButtonStates() {
  document.getElementById('font-decrease').disabled = currentIndex === 0;
  document.getElementById('font-increase').disabled = currentIndex === FONT_SIZES.length - 1;
}

function loadSavedFontSize() {
  const saved = localStorage.getItem(STORAGE_KEY);
  if (saved !== null) {
    setFontSize(parseInt(saved, 10));
  }
}

// Event listeners
document.getElementById('font-decrease').addEventListener('click', () => {
  setFontSize(currentIndex - 1);
});

document.getElementById('font-reset').addEventListener('click', () => {
  setFontSize(DEFAULT_INDEX);
});

document.getElementById('font-increase').addEventListener('click', () => {
  setFontSize(currentIndex + 1);
});

// Załaduj zapisany rozmiar przy starcie
loadSavedFontSize();

Alternatywa: CSS Custom Properties

:root {
  --font-scale: 1;
}

body {
  font-size: calc(1rem * var(--font-scale));
}

h1 {
  font-size: calc(2.5rem * var(--font-scale));
}
function setFontScale(scale) {
  document.documentElement.style.setProperty('--font-scale', scale);
  localStorage.setItem('fontScale', scale);
}

Jak testować WCAG 1.4.4?

Metoda 1: Zoom przeglądarki

Najprostsza i najważniejsza metoda testowania:

  1. Otwórz stronę w przeglądarce
  2. Naciśnij Ctrl + Plus (Windows/Linux) lub Cmd + Plus (Mac)
  3. Powiększ do 200% (zazwyczaj 4-5 kliknięć)
  4. Sprawdź każdą stronę i funkcjonalność

Co sprawdzić:

  • Czy cały tekst jest widoczny?
  • Czy nie pojawia się poziomy scroll?
  • Czy można korzystać z nawigacji?
  • Czy formularze działają poprawnie?
  • Czy przyciski są klikalne?

Metoda 2: Ustawienia systemowe

Testuj też z powiększonym domyślnym rozmiarem tekstu:

Windows:

  1. Ustawienia → Ułatwienia dostępu → Rozmiar tekstu
  2. Przesuń suwak na większy rozmiar

macOS:

  1. Preferencje systemowe → Dostępność → Ekran
  2. Włącz “Używaj skrótów klawiszowych do powiększania”

Przeglądarka (Chrome):

  1. Ustawienia → Wygląd → Rozmiar czcionki
  2. Zmień z “Średni” na “Bardzo duży”

Narzędzia automatyczne

NarzędzieTypOpis
WAVERozszerzenie/onlineWykrywa problemy z dostępnością
axe DevToolsRozszerzenie ChromeSzczegółowy audyt WCAG
LighthouseWbudowane w ChromeAudyt dostępności w DevTools
Pa11yCLIAutomatyczne testy w CI/CD

Checklist WCAG 1.4.4

Użyj tej listy do weryfikacji:

  • Tekst można powiększyć do 200% bez utraty treści
  • Brak user-scalable=no w viewport meta
  • Brak maximum-scale=1 w viewport meta
  • Rozmiary tekstu w jednostkach względnych (rem, em, %)
  • Kontenery tekstowe nie mają stałej wysokości z overflow: hidden
  • Nawigacja działa przy powiększeniu 200%
  • Formularze są funkcjonalne przy powiększeniu 200%
  • Brak poziomego scrollowania przy powiększeniu 200%

Podsumowanie

Kryterium WCAG 1.4.4 wymaga, aby tekst można było powiększyć do 200% bez utraty treści lub funkcjonalności. Kluczowe zasady:

  1. Używaj jednostek względnych - rem i em zamiast px dla rozmiaru tekstu
  2. Nie blokuj zoomu - unikaj user-scalable=no i maximum-scale=1 w viewport meta
  3. Elastyczne kontenery - nie ograniczaj wysokości kontenerów z tekstem
  4. Testuj regularnie - sprawdzaj stronę przy powiększeniu 200%
  5. Pamiętaj o prawnych wymaganiach - poziom AA jest obowiązkowy dla wielu organizacji

Dostępność to nie tylko wymóg prawny - to szacunek dla wszystkich użytkowników Twojej strony.

Źródła

  1. W3C - Understanding Success Criterion 1.4.4: Resize text https://www.w3.org/WAI/WCAG21/Understanding/resize-text.html

  2. Gov.pl - Powiększanie tekstu na stronach internetowych https://www.gov.pl/web/dostepnosc-cyfrowa/powiekszanie-tekstu-na-stronach-internetowych

  3. MDN - CSS values and units https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units

  4. Yale Usability - Zoom and Resizing Text https://usability.yale.edu/web-accessibility/articles/zoom-resizing-text

  5. WebAIM - Fonts https://webaim.org/techniques/fonts/

  6. MDN - clamp() function https://developer.mozilla.org/en-US/docs/Web/CSS/clamp