Semantyczne Tagi HTML5 — Struktura Strony, SEO i Dostępność

Kąt widzenia: kiedy używać tagów semantycznych zamiast
<div>, dlaczego to ma znaczenie dla wyszukiwarek i czytników ekranu, i jak to wygląda w Razor Pages
Przykład przewodni: strona katalogu produktów w sklepie — od samych<div>do pełnej semantyki HTML5
Problem z samymi divami
Możesz zbudować każdą stronę używając tylko <div> i <span>. Przeglądarka wyrenderuje ją poprawnie. Ale:
<!-- ❌ Strona bez semantyki — poprawna wizualnie, ale bez znaczenia -->
<div class="header">
<div class="logo">Sklep</div>
<div class="navigation">
<div class="nav-item"><a href="/">Strona główna</a></div>
<div class="nav-item"><a href="/products">Produkty</a></div>
</div>
</div>
<div class="main-content">
<div class="product-list">
<div class="product">
<div class="title">Klawiatura mechaniczna</div>
<div class="description">Cherry MX Red...</div>
</div>
</div>
</div>
<div class="footer">
<div class="copyright">© 2026 Sklep</div>
</div>
Dla przeglądarki — OK. Ale dla:
- Robota Google — nie wie, że
class="header"to nagłówek. Klasy CSS to nie semantyka HTML. - Czytnika ekranu (niewidomy użytkownik) — nie może przeskakować między sekcjami strony. Słyszy jeden ciąg divów.
- Kolejnego developera — musi czytać klasy, żeby zrozumieć strukturę.
HTML5 rozwiązuje to przez tagi semantyczne — elementy, których sama nazwa mówi, czym są.
Mapa semantycznych tagów HTML5
<body>
<header> <!-- nagłówek strony lub sekcji -->
<nav> <!-- nawigacja -->...</nav>
</header>
<main> <!-- główna treść strony (tylko jeden na stronę) -->
<article> <!-- samodzielna treść (post, produkt, artykuł) -->
<section> <!-- sekcja wewnątrz article lub main -->
...
</section>
</article>
<aside> <!-- treść poboczna (sidebar, reklamy, powiązane) -->
...
</aside>
</main>
<footer> <!-- stopka strony lub sekcji -->
...
</footer>
</body>
<header> — nagłówek strony lub sekcji
<!-- Nagłówek całej strony -->
<header>
<a href="/" class="logo">
<img src="/img/logo.svg" alt="Sklep — strona główna">
</a>
<nav>...</nav>
</header>
<!-- Nagłówek sekcji / artykułu — header można używać wielokrotnie -->
<article>
<header>
<h2>Klawiatura mechaniczna TKL</h2>
<p>Dodano: <time datetime="2026-03-15">15 marca 2026</time></p>
</header>
<p>Opis produktu...</p>
</article>
<header> może się pojawiać wielokrotnie — jako nagłówek całej strony i jako nagłówek każdego <article>.
<nav> — blok nawigacyjny
<nav aria-label="Nawigacja główna">
<ul>
<li><a href="/">Strona główna</a></li>
<li><a href="/products">Produkty</a></li>
<li><a href="/about">O nas</a></li>
<li><a href="/contact">Kontakt</a></li>
</ul>
</nav>
<nav> sygnalizuje, że to blok linków nawigacyjnych. Na stronie może być kilka <nav> — główna nawigacja, breadcrumbs, nawigacja stopki. Atrybut aria-label odróżnia je od siebie dla czytników ekranu.
<main> — główna treść strony
<main>
<!-- Tu jest to, po co użytkownik przyszedł na tę stronę -->
<h1>Katalog produktów</h1>
<div class="product-grid">...</div>
</main>
Tylko jeden <main> na stronie. To główna treść — nie nawigacja, nie sidebar, nie footer. Czytniki ekranu pozwalają przeskakować bezpośrednio do <main> (skrót klawiszowy).
<article> — samodzielna, kompletna treść
<article class="product-card">
<header>
<h2><a href="/products/42">Klawiatura mechaniczna TKL</a></h2>
</header>
<figure>
<img src="/img/kb-tkl.jpg" alt="Klawiatura mechaniczna TKL - widok z góry">
</figure>
<p>Kompaktowa klawiatura bez bloku numerycznego. Przełączniki Cherry MX Red.</p>
<footer>
<span class="price">299,00 zł</span>
<a href="/products/42" class="btn">Szczegóły</a>
</footer>
</article>
<article> to treść, która ma sens w izolacji — mogłaby być wyjęta ze strony i nadal być zrozumiała. Post na blogu, karta produktu, komentarz, artykuł newsowy.
<section> — sekcja tematyczna
<main>
<section aria-labelledby="featured-heading">
<h2 id="featured-heading">Polecane produkty</h2>
<div class="product-grid">
<article>...</article>
<article>...</article>
</div>
</section>
<section aria-labelledby="sale-heading">
<h2 id="sale-heading">Promocje</h2>
<div class="product-grid">...</div>
</section>
</main>
<section> to tematyczna część strony. Powinna mieć nagłówek (h2–h6). Jeśli możesz użyć <article> — użyj <article>. <section> to “ogólna sekcja z nagłówkiem”, <article> to “samodzielna treść”.
<aside> — treść poboczna
<main>
<div class="catalog-layout">
<section class="product-list">
<!-- główna treść -->
</section>
<aside aria-label="Filtry">
<h2>Filtruj produkty</h2>
<form>
<fieldset>
<legend>Kategoria</legend>
<label><input type="checkbox" name="cat" value="keyboards"> Klawiatury</label>
<label><input type="checkbox" name="cat" value="mice"> Myszy</label>
</fieldset>
<fieldset>
<legend>Cena</legend>
<input type="range" name="max-price" min="0" max="2000" value="2000">
</fieldset>
</form>
</aside>
</div>
</main>
<aside> to treść powiązana, ale nie kluczowa dla głównego przekazu — sidebar z filtrami, powiązane produkty, reklama, cytat.
<footer> — stopka strony lub sekcji
<footer>
<div class="footer-columns">
<nav aria-label="Linki stopki">
<h3>Informacje</h3>
<ul>
<li><a href="/about">O firmie</a></li>
<li><a href="/privacy">Polityka prywatności</a></li>
<li><a href="/terms">Regulamin</a></li>
</ul>
</nav>
<address>
<strong>Sklep Sp. z o.o.</strong><br>
ul. Przykładowa 42, 00-001 Warszawa<br>
<a href="mailto:kontakt@sklep.pl">kontakt@sklep.pl</a>
</address>
</div>
<p class="copyright">© 2026 Sklep Sp. z o.o. Wszelkie prawa zastrzeżone.</p>
</footer>
<address> wewnątrz <footer> — dane kontaktowe (adres, email, telefon).
Nagłówki — hierarchia H1–H6
Nagłówki tworzą spis treści strony. Muszą być zagnieżdżone hierarchicznie:
<h1>Katalog produktów</h1> <!-- jeden h1 na stronę -->
<h2>Klawiatury</h2>
<h3>Mechaniczne</h3>
<h3>Membranowe</h3>
<h2>Myszy</h2>
<h3>Gamingowe</h3>
<h4>Bezprzewodowe</h4>
<h3>Biurowe</h3>
Zasady:
- Jeden
<h1>na stronę — główny tytuł, najważniejszy przekaz - Nie pomijaj poziomów (
h2→h4bezh3to błąd) - Nagłówki definiują strukturę dla czytników ekranu i SEO — nie używaj
h2bo “wygląda ładniej” niżh3
Jeśli chcesz zmienić rozmiar tekstu — użyj CSS, nie zmieniaj poziomu nagłówka.
Listy — ul, ol, dl
<!-- Nieuporządkowana (punkty) — elementy bez istotnej kolejności -->
<ul>
<li>Podświetlenie RGB</li>
<li>Przełączniki Cherry MX Red</li>
<li>Anti-ghosting</li>
</ul>
<!-- Uporządkowana (numerowana) — kolejność ma znaczenie -->
<ol>
<li>Dodaj produkt do koszyka</li>
<li>Wybierz adres dostawy</li>
<li>Wybierz metodę płatności</li>
<li>Potwierdź zamówienie</li>
</ol>
<!-- Definicyjna — para termin: definicja -->
<dl>
<dt>SKU</dt>
<dd>KB-MX-RED-TKL-42</dd>
<dt>Waga</dt>
<dd>850 g</dd>
<dt>Wymiary</dt>
<dd>360 × 130 × 40 mm</dd>
</dl>
<dl> (definition list) jest idealny do specyfikacji produktów, słowników, metadanych — par klucz–wartość.
Nawigacja jako lista — to jest semantycznie poprawny wzorzec:
<nav>
<ul> <!-- lista linków nawigacyjnych -->
<li><a href="/">Strona główna</a></li>
<li><a href="/products">Produkty</a></li>
<li><a href="/cart">Koszyk (3)</a></li>
</ul>
</nav>
CSS usuwa domyślne punkty (list-style: none) i zmienia układ na poziomy.
<figure> i <figcaption> — ilustracja z podpisem
<figure>
<img src="/img/keyboard-tkl.jpg"
alt="Klawiatura mechaniczna TKL — widok z przodu i z boku">
<figcaption>
Klawiatura TKL z podświetleniem RGB.
Zdjęcie: <a href="/photos/kb-tkl">galeria produktu</a>
</figcaption>
</figure>
<figure> to samodzielna treść wizualna — obraz, diagram, fragment kodu, tabela z podpisem. <figcaption> to jej opis.
<time> — data i czas
<!-- datetime to czytelna maszynowo reprezentacja, treść tagu — czytelna dla człowieka -->
<time datetime="2026-03-15">15 marca 2026</time>
<time datetime="2026-03-15T14:30:00+01:00">15 marca 2026, godz. 14:30</time>
<time datetime="P3D">3 dni</time> <!-- czas trwania -->
Wyszukiwarki i aplikacje rozumieją atrybut datetime. W Razor:
<time datetime="@product.AddedAt.ToString("yyyy-MM-dd")">
@product.AddedAt.ToString("d MMMM yyyy", new CultureInfo("pl-PL"))
</time>
Kompletna struktura strony katalogu
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Klawiatury mechaniczne — Sklep</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header class="site-header">
<a href="/" class="brand">
<img src="/img/logo.svg" alt="Sklep — wróć na stronę główną">
</a>
<nav aria-label="Nawigacja główna">
<ul>
<li><a href="/products">Produkty</a></li>
<li><a href="/brands">Marki</a></li>
<li><a href="/cart" aria-label="Koszyk, 3 produkty">Koszyk (3)</a></li>
</ul>
</nav>
</header>
<main>
<nav aria-label="Breadcrumbs">
<ol>
<li><a href="/">Strona główna</a></li>
<li><a href="/products">Produkty</a></li>
<li aria-current="page">Klawiatury mechaniczne</li>
</ol>
</nav>
<h1>Klawiatury mechaniczne</h1>
<div class="catalog-layout">
<aside aria-label="Filtry">
<h2>Zawęź wyniki</h2>
<form method="get" action="/products/keyboards">
<!-- filtry -->
</form>
</aside>
<section aria-labelledby="products-heading">
<h2 id="products-heading" class="sr-only">Lista produktów</h2>
<div class="product-grid">
<article class="product-card">
<a href="/products/42">
<figure>
<img src="/img/kb-tkl.jpg"
alt="Klawiatura TKL Cherry MX Red">
</figure>
<h3>Klawiatura TKL MX Red</h3>
</a>
<p>Kompaktowa, bez bloku numerycznego.</p>
<dl class="product-specs">
<dt>Przełączniki</dt><dd>Cherry MX Red</dd>
<dt>Układ</dt><dd>TKL (87 klawiszy)</dd>
</dl>
<footer class="product-card-footer">
<strong class="price">299,00 zł</strong>
<button data-product-id="42">Do koszyka</button>
</footer>
</article>
<!-- kolejne article.product-card -->
</div>
</section>
</div>
</main>
<footer class="site-footer">
<nav aria-label="Linki stopki">
<ul>
<li><a href="/about">O firmie</a></li>
<li><a href="/privacy">Polityka prywatności</a></li>
<li><a href="/contact">Kontakt</a></li>
</ul>
</nav>
<p><small>© 2026 Sklep Sp. z o.o.</small></p>
</footer>
</body>
</html>
Dlaczego semantyka ma znaczenie w projekcie .NET
SEO: Google odczytuje strukturę HTML. <h1> na stronie produktu z nazwą produktu = wyższa pozycja dla tej frazy. <nav> mówi robotowi, gdzie są linki nawigacyjne (mniej ważne dla indeksowania treści).
Dostępność: ~15% populacji korzysta z technologii wspomagających. Czytniki ekranu (NVDA, JAWS, VoiceOver) nawigują po nagłówkach, <main>, <nav>, <article>. Bez semantyki — strona jest dla nich jednym ciągiem tekstu.
Utrzymywalność: <article class="product-card"> mówi więcej niż <div class="product-card">. Nowy developer widzi strukturę bez czytania CSS.
Razor Pages i Tag Helpers: ASP.NET Core Tag Helpers generują poprawne tagi HTML. <form asp-action="AddToCart"> generuje <form method="post" action="/cart/add">. Rozumienie semantyki HTML pomaga zrozumieć, co Tag Helpers produkują.
Podsumowanie: kiedy co
| Chcesz opisać… | Użyj |
|---|---|
| Nagłówek strony z logo i nawigacją | <header> |
| Menu z linkami | <nav> + <ul> + <li> + <a> |
| Główną treść strony | <main> (jeden) |
| Samodzielną treść (produkt, post) | <article> |
| Tematyczną sekcję z nagłówkiem | <section> |
| Sidebar, powiązane produkty | <aside> |
| Stopkę strony | <footer> |
| Listę bez kolejności | <ul> + <li> |
| Listę kroków/rankingów | <ol> + <li> |
| Pary klucz–wartość (specyfikacja) | <dl> + <dt> + <dd> |
| Obraz z podpisem | <figure> + <img> + <figcaption> |
| Datę/czas | <time datetime="..."> |
| Kontener bez semantyki | <div> (ostateczność) |
Następny post: Struktura dokumentu HTML5 i kluczowe znaczniki treści — kompletny szablon Razor Page — DOCTYPE, head z meta tagami, wszystkie tagi treści i gotowy szkielet pliku .cshtml.
🚀 Co dalej?
Zobacz to w praktyce na wideo i pobierz darmową roadmapę, żeby ułożyć naukę w spójną ścieżkę do pierwszej pracy.
- 🗺️ Pobierz darmową roadmapę Junior .NET Developer — 12 kroków od podstaw C# do pierwszej pracy: dev-hobby.pl
- 🎬 Subskrybuj kanał YouTube — nowe filmy co tydzień.
Zamień wiedzę w umiejętności
Pobierz darmową Roadmapę .NET i ułóż takie tematy jak ten w spójną ścieżkę do pierwszej pracy.
Pobieram roadmapę →
1 comment