Досить зловживати div: інтро до семантичного HTML

16 хв. читання

div проявив себе

Усі ми любимо тег div. Він існує вже давно і за цей час став найпопулярнішим елементом для огортання будь-якого контенту в блок, щоб стилізувати чи структурувати його. Навіть зараз у продакшені часто можна натрапити на подібний код:

<div class="container" id="header">
    <div class="header header-main">Super duper best blog ever</div>
    <div class="site-navigation">
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </div>
</div>
<div class="container" id="main">
    <div class="article-header-level-1">
        Why you should buy more cheeses than you currently do
    </div>
    <div class="article-content">
        <div class="article-section">
            <div class="article-header-level-2">
                Part 1: Variety is spicy
            </div>
            <!-- інший контент -->
        </div>
        <div class="article-section">
            <div class="article-header-level-2">
                Part 2: Cows are great
            </div>
            <!-- інший контент -->
        </div>
    </div>
</div>
<div class="container" id="footer">
    Contact us!
    <div class="contact-info">
        <p class="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </p>
        <div class="street-address">
            <p>123 Main St., Suite 404</p>
            <p>Yourtown, AK, 12345</p>
            <p>United States of America</p>
        </div>
    </div>
</div>

Фух, як багато div! Але все ж працює... Майже все. Тут є така потрібна нам структура, тож після стилізації все буде таким, яким і планувалось. Однак є суттєві проблеми:

  • Доступність: більшість інструментів a11y досить розумні. Вони намагаються парсити структуру сторінки, щоб допомогти юзерам користуватися нею саме так, як задумав автор, і полегшити доступ до різних розділів сторінки. Але <div> насправді не передають ніякої корисної інформації про структуру документа. Навіть найрозумніший інструмент a11y — все ще не людина, тому не може аналізувати усі дивні назви, які розробники використовують для ідентифікаторів та класів тегу <div>. Людина може здогадатися, що class="article-header-level-2" — підзаголовок, а от робот навряд.
  • Читабельність: щоб прочитати такий код, треба уважно оглянути назви класів серед синтаксичного цукру <div class="..."></div>. Зі збільшенням вкладеності вашої розмітки, вам ставатиме все складніше відстежувати закриваючі теги </div>. Ви можете звернутися по допомогу до фіч IDE, на зразок позначення кольорами відступів або виділення відповідного тегу, щоб краще орієнтуватися у документі.
  • Послідовність і стандарти: досить неприємно звикати до стилю розмітки в кодовій базі нового проєкту. Якщо б ми мали стандарт розмітки, було б набагато легше переглянути HTML-файл в незнайомій кодовій базі і швидко розібратися, що він повинен представляти. Якби ж тільки існував такий стандарт...

HTML5: такий стандарт

HTML5, м'яко кажучи, не новий. Початкові напрацювання були випущені для публічного обговорення у січні 2008 (11 років тому!) і стали повноцінною W3C рекомендацією у жовтні 2014, тобто 4,5 роки тому.

Одним з основних досягнень HTML5 стало впровадження стандартизованого набору семантичних елементів. Термін «семантичний» вказує на значення слова або речі. Тому «семантичні елементи» — елементи, призначені для розмітки структури документа у більш осмислений спосіб: щоб було чітко зрозуміло, для чого саме вони у документі. І що важливо: оскільки теги стандартизовані, вони організовують розмітку документа так, що кожен може використовувати і розуміти їх, навіть роботи.

У специфікації HTML5 щодо елементу div згадується таке:

Розробникам рекомендується використовувати елемент div в останню чергу, коли всі інші елементи не підходять. Використовуйте доречніші елементи замість div, щоб покращити доступність для користувачів та підтримуваність коду для розробників.

У статті семантичні блокові елементи згруповано у дві категорії: елементи базової структури та індикатори вмісту. Не варто сприймати це як терміни: такий поділ необхідний для зручності.

Елементи базової структури

Є дуже поширений шаблон, який можна знайти на вебсайтах, у посібниках, та навіть у бібліотеках CSS — і не дарма. На найвищому рівні ми поділяємо нашу сторінку на три частини: header, main і footer, а потім вже ділимо ці секції, як нам потрібно.

<div class="container" id="header">...</div>
<div class="container" id="main">
    ...
    <div class="article-section">...</div>
    ...
</div>
<div class="container" id="footer">...</div>

Такий шаблон використовується вже досить давно: подібна структура документа легко сприймається та стилізується за допомогою CSS. Елементи header та footer також спрощують роботу з частковими шаблонами на таких мовах, як PHP або Rails/ERB, тому що ви можете визначити однакові header та footer по всьому сайту так:

<?php include 'header.php'; ?>

<div id="main">...</div>

<?php include 'footer.php'; ?>

Більшість погодиться, що це хороший шаблон для користування. Такої ж думки дотримуються і WHATWG та W3C, які стандартизували описаний шаблон, додавши нові елементи до HTML5 із дуже зрозумілими назвами: <header>, <main>, <footer> та <section>.

<header> та <footer>

Елементи <header> і <footer> дуже схожі за своїм визначенням у специфікації та правилами використання, з єдиною різницею в їхньому семантичному призначенні: заголовки йдуть на початку, а футер — наприкінці сторінки. <header> і <footer> не обов'язково розмежовують <body> вашої сторінки: їх можна використовувати усюди, де є частина контенту з чітким початком та кінцем. До такого контенту належать форми, статті, секції статей, пости у соціальних мережах, картки тощо.

Заголовок і футер семантично приєднані до найближчих елементів sectioning root або sectioning content. До них зараховуються <body>, <blockquote>, <section>, <td>, <aside> та багато інших. Допоміжні інструменти можуть використовувати ці та інші елементи для створення структури документа, щоб допомогти користувачам легко орієнтуватися в ньому. У вас не повинно бути більше одного <header> або <footer> на секцію.

І наостанок, <header> часто вміщує заголовки (<h1><h6>). Це не обов'язково, але так можна згрупувати інші елементи, пов'язані із заголовком: посилання, зображення або підзаголовки. Ми отримаємо узгоджену структуру, навіть якщо заголовок — єдиний елемент в <header>.

<main>

Третій особливий елемент базової структури — <main>. У специфікації зазначено дві дуже важливі особливості <main>.

Основна частина документа вміщує контент, унікальний для нього, та не має вмісту, що повторюється на інших сторінках: посилання для навігації сайтом, інформація про авторські права, логотипи, банери та пошукові форми (лише якщо це не пошукова сторінка).

Тобто у <main> ви розміщуєте важливі частини сторінки, за якими і прийшов користувач. Іншими словами: основний контент.

Усі інші перелічені елементи —на зразок логотипів, пошукових форм тощо — можуть розташовуватись у <header> чи <footer>, у <body>, але поза <main>.

У документі не повинно бути більше за один видимий main-елемент. Усі зайві main необхідно приховати за допомогою атрибуту hidden.

На відміну від <header> та <footer> (та більшості інших блокових елементів), <main> не можна використовувати у довільних секціях сторінки: лише один раз. Або ж усі інші main треба приховати атрибутом hidden, що поводиться як display: none; у CSS. Це досить корисний підхід для попереднього завантаження представлень у застосунку. Створіть новий <main hidden>, отримайте певний вміст, який ймовірніше показуватиметься наступним (наприклад, наступна стаття у серії, наступний слайд у слайдшоу). Коли користувач клікне на посилання/кнопку, замініть поточний <main> на попередньо завантажений — через перемикання атрибуту hidden на обох.

Перш ніж продовжити, відредагуємо наш приклад. Ось, яким усе було б, якби ми використовували <header>, <main> і <footer> для основної структури статті:

<header>
    <h1>Super duper best blog ever</h1>
    ...
</header>
<main>
    <h2>Why you should buy more cheeses than you currently do</h2>
    ...
</main>
<footer>
    Contact us!
    <div class="contact-info">this.is.us@example.com</div>
</footer>

Так набагато краще, але досі маємо багато роботи.

<section>

У нас вже є основна розмітка сторінки: заголовок, футер та основна частина. Тепер ми можемо заповнити її контентом.

Зазвичай хочеться розбити вміст на розділи, особливо якщо текст об'ємний, ніхто ж не любить читати «простирадла».

Досить зловживати div: інтро до семантичного HTML

Тут на допомогу приходить <section>. Він має елементарне визначення: це просто <div>, який позначає новий розділ, тому може мати власний заголовок і футер.

Яка ж різниця між <section> та звичайним div? І коли використовувати кожен з них?

section не є універсальним контейнерним елементом. Коли елемент потрібен лише для застосування стилів або для зручності написання скриптів, рекомендується використовувати div. Загальне правило: section підходить тільки в тому випадку, якщо на вміст елемента явно посилаються у документі.

Якщо коротко: зазначаєте частину документа у змісті — використовуйте <section>, в інших випадках — послуговуєтесь <div> або чимось іншим.

Індикатори вмісту

У нас вже є надійна структура сторінки. Замість суцільних <div> ми явно визначили основний вміст сторінки, заголовок, футер та розділи. Але цим семантичні елементи не обмежуються.

Далі ми розглянемо декілька елементів HTML5, які стосуються семантики вмісту, а не структури.

<article>

Елемент <article> використовується для визначення самостійної частини контенту: якщо її розмістити в іншому місці, вона все одно матиме сенс. Це може бути стаття або запис, на зразок «твіту» чи посту у Facebook.

Специфікація HTML5 рекомендує завжди зазначати в <article> заголовок, що описує вміст. Для цього ідеально підійдуть теги <h1><h6>. В <article> можна також вставляти елементи <header>, <footer> та <section>. З таким підходом <article> стає повноцінним фрагментом, який можна розмістити на іншій сторінці.

Відредагуємо наш приклад: перепишемо елементи з class="article-*" на <article> з усіма вказаними особливостями використання:

<article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- інший  контент  -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- інший контент -->
    </section>
</article>

Таку розмітку набагато легше сприймати, до того ж пошукові роботи можуть з'ясувати, що ви мали на увазі.

<nav>

Цей елемент може здатися вам більш знайомим. <nav> призначений для явного визначення основних блоків навігації на сторінці, групи посилань, що допомагають користувачеві зорієнтуватися на сайті (тобто карта сайту або перелік посилань у заголовку) чи на поточній сторінці (тобто зміст).

Застосуємо <nav> для групи посилань у заголовку нашого прикладу:

<nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/archive">Archive</a>
</nav>

Структура зовсім не змінилась, але тепер ви з першого погляду можете визначити, для чого потрібна ця розмітка. А найважливіше — пошукові роботи також це зможуть.

<address>

Наостанок розглянемо <address>. Цей елемент потрібен для визначення контактної інформації, зазвичай його використовують у футері, де зазначається пошта, телефон тощо.

Цікаво, що для <address> немає особливих правил розмітки. У специфікації зазначено, що така деталізація виходить за межі HTML.

Загальні рішення зазначені в RDFa та W3C специфікаціях, які пропонують використовувати для тегів атрибути, щоб визначати різні дані. Футер з нашого прикладу можна покращити, використавши <address> та специфікацію RDFa:

<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>

Такий підхід не дуже лаконічний, але досить зручний для розмітки різних даних.

Більше про RDF за посиланнями:

Висновок

Ми з'ясували, як використовувати семантичні елементи HTML5 на реальному прикладі. Зрештою все матиме ось такий вигляд:

<header>
    <h1>Super duper best blog ever</h1>
    <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </nav>
</header>
<main>
    <article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- інший контент -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- інший контент -->
    </section>
</article>
</main>
<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>

Така розмітка не лише більш читабельна, а й більш ефективна для SEO та доступності.

Звичайно, цим семантичні елементи HTML не обмежуються. Існує безліч додаткових елементів, які допомагають позначати та структурувати текстовий вміст, вбудовані медіа тощо. Ви можете ознайомитися з деякими з них за посиланнями:

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.1K
Приєднався: 9 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація