Element <label> w HTML to prosty, ale niezwykle ważny znacznik, który służy do tworzenia etykiet dla kontrolek formularzy, takich jak pola tekstowe, checkboxy czy radia. Dzięki niemu użytkownicy mogą klikać nie tylko na samą kontrolkę, ale także na powiązaną etykietę, co znacznie poprawia dostępność i doświadczenie użytkownika (UX).
W dzisiejszych aplikacjach webowych formularze są wszędzie – od logowania po złożone ankiety. Ignorowanie <label> to błąd początkujących, który prowadzi do frustracji użytkowników i problemów ze zgodnością ze standardami WCAG (Web Content Accessibility Guidelines). W tym wpisie przejdziesz od podstaw po praktyczne triki – z gotowymi przykładami do kopiowania.
Czym dokładnie jest <label> i dlaczego jest obowiązkowy?
<label> powiązuje tekstową etykietę z elementem interaktywnym, takim jak <input>, <select>, <textarea> czy <button>. Działa w dwóch trybach: implicytnym (bez atrybutu for, gdy kontrolka jest zagnieżdżona wewnątrz etykiety) oraz eksplicytnym (z atrybutem for, który wskazuje identyfikator id kontrolki).
Oba sposoby aktywują kontrolkę po kliknięciu w etykietę, co jest kluczowe dla klawiaturzystów i użytkowników screen readerów.
Kontekst użycia w HTML5 (zgodnie ze standardami):
- modele treści: ogólna, syntagmatyczna, interaktywna, formularzowa,
- elementy nadrzędne: np.
<div>,<fieldset>,<form>, - znaczniki: otwierający i zamykający obowiązkowe,
- charakter: liniowy (inline).
Bez <label> formularz traci na dostępności – czytniki ekranu nie odczytają powiązania, a myszka musi trafić w mały checkbox.
Podstawowe przykłady użycia
Zacznijmy od prostego formularza rejestracyjnego. Oto tryb implicytny – najprostszy dla małych formularzy:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przykład etykiety – tryb implicytny</title>
</head>
<body>
<form action="skrypt.php" method="get">
<label>
Imię:
<input name="imie" type="text">
</label><br>
<label>
Nazwisko:
<input name="nazwisko" type="text">
</label><br>
<label>
<input type="checkbox" name="zgoda"> Akceptuję regulamin
</label><br>
<input type="submit" value="Wyślij">
</form>
</body>
</html>
Kliknięcie na „Imię:” lub „Akceptuję regulamin” aktywuje pole. Idealne dla kompaktowych form.
Teraz tryb eksplicytny z for i id – zalecany dla złożonych układów, bo daje pełną kontrolę:
<form>
<div>
<label for="email">Adres e-mail:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="haslo">Hasło:</label>
<input type="password" id="haslo" name="haslo" minlength="8">
</div>
<div>
<label for="zgoda">Wyrażam zgodę na przetwarzanie danych:</label>
<input type="checkbox" id="zgoda" name="zgoda">
</div>
</form>
Uwaga – wartość for musi dokładnie odpowiadać id kontrolki, łącznie z wielkością liter.
Atrybuty <label> – od podstawowych po zaawansowane
<label> obsługuje globalne atrybuty HTML (np. id, class, style, title) oraz zdarzenia (np. onclick, onfocus). Najważniejsze atrybuty specyficzne to:
| Atrybut | Opis | Przykład |
|---|---|---|
| for | Łączy z elementem o podanym id. Kluczowy dla dostępności. |
for="username" |
| accesskey | Klawisz szybkiego dostępu (np. Alt + S) do aktywacji fokusu etykiety lub kontrolki. | accesskey="e" |
| form | Powiązuje z formularzem o danym id (działa nawet, gdy etykieta jest poza <form>). |
form="mojFormularz" |
Przykład wykorzystujący accesskey i zdarzenia JavaScript:
<label for="szukaj" accesskey="s" title="Naciśnij Alt+S dla fokusu" onclick="this.nextElementSibling.focus();" >
Szukaj:
</label>
<input type="search" id="szukaj" name="q" onfocus="console.log('Fokus!');">
Zaawansowane zastosowania i najlepsze praktyki
1. Formularze z <fieldset> i <legend>
Grupuj powiązane pola dla lepszej semantyki i czytelności:
<fieldset>
<legend>Dane osobowe</legend>
<label for="imie">Imię: <input type="text" id="imie"></label>
<label for="nazwisko">Nazwisko: <input type="text" id="nazwisko"></label>
</fieldset>
<label> może być wewnątrz <fieldset>, ale nie w <legend>.
2. Radia i checkboxy w grupach
Pola są grupowane przez atrybut name, ale etykiety znacząco poprawiają UX i trafialność:
<fieldset>
<legend>Płeć:</legend>
<label><input type="radio" name="plec" value="k"> Kobieta</label>
<label><input type="radio" name="plec" value="m"> Mężczyzna</label>
</fieldset>
3. Stylizacja CSS dla <label>
Dodaj wizualny sygnał klikalności i zadbaj o odstępy:
label {
cursor: pointer;
display: block; /* Dla pionowego układu */
margin-bottom: 10px;
font-weight: bold;
}
label input {
margin-left: 5px;
}
Pełny przykład z CSS i JS (walidacja po kliknięciu etykiety):
<!DOCTYPE html>
<html lang="pl">
<head>
<style>
label { cursor: pointer; display: block; margin: 10px 0; }
input:invalid { border-color: red; }
</style>
</head>
<body>
<form id="rejestracja">
<label for="email">
E-mail:
<input type="email" id="email" required>
</label>
<button type="submit">Rejestruj</button>
</form>
<script>
document.querySelectorAll('label').forEach(label => {
label.addEventListener('click', () => {
const input = document.getElementById(label.getAttribute('for'));
if (input) {
input.focus();
if (input.validity.valid) input.style.borderColor = 'green';
}
});
});
</script>
</body>
</html>
4. Dostępność (a11y) i WCAG
Podstawowe zasady, które zapewniają zgodność i wygodę użytkowania:
- zawsze stosuj
<label>dla każdego<input>(z wyjątkiem typówhiddeniimage), - unikaj pustych etykiet:
<label for="x"> </label>– czytniki ekranu nie będą miały co odczytać, - dla przycisków wysyłających używaj po prostu
<button type="submit">lub etykiety tylko wtedy, gdy rzeczywiście oznaczasz pole, - regularnie testuj z NVDA/VoiceOver oraz na klawiaturze (Tab/Shift+Tab).
Błędy do uniknięcia:
- brak atrybutu
forprzy braku zagnieżdżenia kontrolki w etykiecie, - powielone wartości
idw obrębie jednego dokumentu, - jedna etykieta obejmująca wiele kontrolek – etykieta powinna wskazywać dokładnie jedną kontrolkę.
Powiązane elementy formularzowe
<label> najczęściej współpracuje z następującymi elementami:
<input>(m.in. typy: text, checkbox, radio, date, email itp.),<textarea>i<select>,<fieldset>,<legend>oraz<datalist>.
Poniżej krótkie przykłady połączeń:
| Element | Przykład z <label> |
|---|---|
| Checkbox | <label><input type="checkbox"> Zgoda</label> |
| Radio | <label for="opcja1"><input type="radio" id="opcja1"> Opcja 1</label> |
| Select | <label for="kraj">Kraj: <select id="kraj"></select></label> |
| Textarea | <label for="opis">Opis: <textarea id="opis"></textarea></label> |