🔥 Zapisy zamknięte, ale możesz pobrać Roadmapę .NET i dołączyć do listy oczekujących — Pobierz i dołącz do Listy VIP →

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 (h2h6). 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">&copy; 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 (h2h4 bez h3 to błąd)
  • Nagłówki definiują strukturę dla czytników ekranu i SEO — nie używaj h2 bo “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>&copy; 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.

👨‍💻
Mariusz Jurczenko
Senior .NET Developer · 10+ lat doświadczenia komercyjnego

Programista .NET z doświadczeniem komercyjnym w firmach takich jak NFZ, Kamsoft, Diagnostyka, Hermes Reply Polska czy Etisoft Smart Solutions. Twórca kursów, z których skorzystało już ponad 11 000 osób w Strefie Kursów i ponad 1 000 kursantów na dev-hobby.pl.

Specjalizacja: Clean Code, Clean Architecture i uczenie programowania tak, żeby dało się je naprawdę zrozumieć — nie wykuć.

🚀 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.

czytanie to początek

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ę →