Структура і семантика HTML-документа
Для того, щоб браузер краще розумів, що, як і де потрібно відобразити на веб-сторінці, у HTML-документа має бути відповідна, стандартизована, структура, а всі теги повинні бути використані за призначенням.
Зміст
Структура HTML-документа
Кістяк структури будь-якого сучасного HTML-документа виглядає так:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
Що тут є:
-
<!DOCTYPE>
особливий тег, він є радше допоміжною інформацією і однозначно говорить браузеру, який стандарт документа він має очікувати для обробки і подальшого відображення. Кожен HTML-документ мусить починатися з тегу<!DOCTYPE>
. Для останньої версії HTML цей тег має такий атрибут:<!DOCTYPE html>
. -
<html>
— це тег, що розмічає початок і кінець HTML-документа. Його також називають кореневим елементом документа, і всі інші елементи мають знаходитися всередині нього. -
<head>
є також одним із особливих елементів, бо містить в собі метадані. Простіше кажучи, це дані про дані документа. До метаданих документа відноситься, наприклад, назва документа, що вказується у тегу<title>
.Особливість елемента
<head>
в тому, що його контент не відображається браузером, а також він може містити в собі тільки обмежений перелік тегів, які, власне, і не потребують відображення. Здебільшого, цей елемент описує назву документа, яку таблицю символів використовує документ, стилі і скрипти. -
<body>
— тіло документа, яке має містити в собі весь контент HTML-сторінки. Або ж все те, що ви бачите, коли дивитесь сторінку в браузері: заголовки, абзаци, світлини, посилання, списки і таке інше.
Реальна структура HTML-документа
Робоча заготовка документа, готова для реального використання, виглядає так:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Назва сторінки</title>
<meta name="description" content="Короткий опис, про що ця сторінка.">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
</body>
</html>
Зверніть увагу, що елементи мають горизонтальний відступ. Зазвичай, це 4
пробіла (або один tab
) для кожного нового рівня вкладеності.
Як бачите, тут всього трохи більше, але сама структура ніяк не помінялась. Що тут є нового?
-
Тег
<meta>
<meta charset="utf-8">
Вказує, який набір символів використано в вашому документі. В абсолютній більшості сучасних HTML-документів немає ніякого сенсу використовувати щось окрім
utf-8
в значенні аргументуcharset
. -
Тег
<title>
Цей тег вказує назву документа. Вона відображається як надпис на вкладці браузера. Для цієї сторінки, наприклад, цей тег виглядає так:
<title>Структура і семантика HTML-документа - Притомний фронтенд</title>
-
Ще один тег
<meta>
<meta name="description" content="This is an example of a meta description.">
В значенні атрибута
content
треба вказувати опис сторінки. Ця інформація слугує для короткого опису веб-сторінки, який ви бачите, наприклад у видачі гугл-пошуку. Працює тільки в парі із атрибутомname="description"
. -
Тег
<link>
<link rel="stylesheet" type="text/css" href="style.css">
Таким чином підключається файл стилей до вашого документа, але не будемо забігати наперед, зараз це для загального розуміння.
Для цього треба:
- встановити редактор коду або скористатися вашим улюбленим і створити пустий файл
index.html
; - скопіювати в нього робочу заготовку документа, відредагувати її за бажанням, наприклад змінити контент елемента
<title>
на щось особливе; - додати контенту в тег
<body>
, наприклад, такого:<body> <h1>Мамо, я ще поки не в Інтернеті!</h1> <p>Але вже близько...</p> </body>
- зберегти документ;
- відкрити збережений файл
index.html
в браузері; - насолодитися результатом! 😎
Якщо у вас щось не вийшло, спробуйте це зробити за покроковою інструкцією із секціїї “Туторіали” — Як створити HTML-файл.
Трошки Санта-Барбари
Для того, щоб описувати позицію елемента відносно інших, вживають дещо дивну термінологію, наче хтось передивився Санта-Барбару: батьківський, дочірній, братній елемент, тощо. Але тут все досить просто і дійсно схоже на генеалогічне дерево:
...
<!-- Батьківський елемент (parent) для всіх вкладених -->
<div>
<!-- Нащадок (descendant) і Дочірній елемент (child) для <div> -->
<h1>Breaking news!</h1>
<!-- Нащадок (descendant) і Дочірній елемент (child) для <div> -->
<!-- А також батьківський елемент для <em> -->
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
<!-- Нащадок (descendant), але *не* Дочірній елемент для <div>, -->
<!-- бо не вкладений безпосередньо в <div>. -->
<!-- Нащадок і Дочірній елемент для <p> -->
<em>Veniam, hic.</em>
</p>
</div>
<!-- Братній елемент (general sibling) -->
<!-- і найближчий брат (adjacent sibling) для <div> -->
<p>Ut enim ad minim veniam, quis nostrud exercitation.</p>
<!-- Братній елемент (general sibling) для <div> -->
<p>Duis aute irure dolor in reprehenderit in nulla pariatur.</p>
...
Доречі, <!-- ... -->
— така конструкція дозволяє залишати коментарі в коді HTML, вони не відображаються браузером:
See the Pen Untitled by Epic Baboon (@ebaboon) on CodePen.
Вкладеність HTML-елементів
Ця тема здається інтуітивно-зрозумілою, особливо для тих, хто вже мав справу із HTML і це дійсно так. Ідея структури HTML в тому, що елементи можуть вкладатися один в одного і створювати ієрархію. Звучить трохи незвично, хоча, в результаті, все зводиться до зрозумілих аналогій із реального життя, наприклад, із друкарської справи.
Давайте на прикладі розглянемо основний принцип вкладення одних елементів в інші.
Кожен тег відноситься до певної категорії, відповідно стандарту HTML, який описує, теги якої категорії він може містити в собі. Наприклад, в специфікаціїї стандарту HTML щодо тегу <p>
сказано, що в нього можуть бути вкладені елементи тільки із категоріїї Phrasing content
. А сам тег <p>
до цієї категорії не відноситься, тому не можна вкладати абзац в абзац.
❌ Тобто отак робити не треба:
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. <p>Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p></p>
✔️ Можна вкладати теги, які відносяться до категорії Phrasing content
:
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi expedita illo,
asperiores at <b>voluptate</b> neque numquam voluptatem consequuntur.
Unde, laboriosam?</p>
Вкладення абзаців не логічно і з точки зору звичної нам моделі абзаців із друкарської справи: не буває вкладених абзаців. Такі аналогії працюють і із іншими елементами.
Якщо ви сумніваєтесь в правильності якогось вкладення — перевірте по документаціїї чи валідне воно. Або скористайтеся валідатором HTML.
Але, здебільшого, відповідь буде інтуітивно зрозуміла — більшість тегів імітуюють поведінку елементів тексту або сторінки, взятих із реального життя.
Якщо я вже згадав про друкарську справу в цьому розділі, то треба згадати про так звану “рибу” або Lorem Ipsum
— це такий класичний текст-заповнювач, який не має ніякого змісту, але він допомагає заповнити сторінку або частину сторінки текстом, максимально схожим на реальний контент.
Раніше він активно використовувався в друкарській справі та з часом став у нагоді в дизайні та фронтенді. Цікава і більш докладна стаття українською — https://uk.lipsum.com/
Багато редакторів коду вміють генерувати “рибу”, достатньо написати в редакторі слово lorem
і натиснути клавішу Tab
.
Семантика HTML
Остання версія стандарту HTML внесла багато змін в цю мову, і одна із найбільш значних — це семантика елементів. Дуже загадкове слово “семантика” означає, що абсолютна більшість елементів (близько 100) в HTML мають певний сенс і призначення, згідно яких їх треба використовувати. І тільки два теги офіційно несемантичні: <div>
і <span>
.
Давайте розберемося, про що тут йдеться.
Семантичні і несемантичні теги
Яке призначення тегу <img>
, для чого він слугує? Ви вже бачили, як працює цей тег, тому можете сміливо відповісти: він слугує для відображення світлини в браузері. Це і є його семантика, його призначення — розмічати світлини в HTML. В інший спосіб його застосувати просто не вийде, про такі теги кажуть, що вони семантичні, тобто призначення елемента зрозуміле і однозначне.
Але є такі елементи, які візуально дають один і той самий ефект, але відрізняються за призначенням і місцем застосування. Подивіться уважно на приклад нижче:
See the Pen HTML similar tags by Epic Baboon (@ebaboon) on CodePen.
Тут використано три різні теги, що майже однаково трансформують текст. В чому ж різниця?
-
Тег
<p>
— семантичний тег, призначений для розмітки тексту, перетворючи простий текст в абзац. -
Тег
<div>
— один із двох несемантичних тегів HTML. Цей елемент не має ніякого семантичного навантаження, використовується як контейнер для інших елементів або коли неможливо визначити зміст елемента. Ніяк не впливає на зовнішній вигляд контенту, аж допоки не буде стилізований.
- Тег
<article>
— семантичний тег, призначений для побудови структури в HTML, що схожа на структуру типу поста на форумі, статті в електронній газеті або статті блогу.
Тож який тег правильний в прикладі? Ніякий. В прикладі не зрозуміло, яку функцію має виконувати цей текст: якщо це абзац тексту — тег <p>
, якщо це окрема, автономна структура, типу посту блога, то це має бути <article>
, якщо це текст, який не несе ніякої функції, а є суто декоративною інформацією, або інформацією невизначеного характеру, то використовуйте тег <div>
.
Всі ці теги (і багато інших), в кінцевому результаті дають майже однаковий візуальний ефект. І це викликає у деяких розробників помилкове бажання застосовувати те, що їм більше подобається, замість того, щоб застосовувати підходящі теги.
Не будьте такими розробниками, застосовуйте теги за призначенням!
Помилковий підхід до семантики
Ще одна популярна помилка, коли розробник не хоче думати уникає обирати правильний тег, навіть коли він очевидний. Такі поганці просто беруть несемантичний тег <div>
, додають до нього атрибут, що допомагає стилізувати елемент (наприклад class
), вкладаючи в назву семантичну сутність елемента і застосовують цей підхід скрізь. Типу такого:
<div class="article">Текст статті</div>
Це валідний код HTML, з точки зору синтаксису, але є нюанс. Біда у тому, що атрибут class="article"
не додає семантики, він використовується виключно для стилізації, хоча і трошки покращує розуміння коду людиною. Якщо забрати цей атрибут, то елемент стане просто якимось абстрактним блоком для будь-якого контенту.
Використовуючи семантичні теги, ви покращуєте веб-доступність сторінки, при цьому, код стає більш зрозумілим:
<article>Текст статті</article>
Атрибути не суперечать семантиці елемента, тому сміло добавляйте їх до семантично правильного елемента, якщо це потрібно:
<article class="pinned">Текст статті</article>
На відміну від <div class="article">
, тег <article>
одразу повідомляє, до чого його готувало життя — бути тегом для розмітки контенту, що може позиціонуватися як стаття.
Семантичні теги — це допомога і програмісту, і браузеру, і скрінрідерам в тому, щоб однозначно розуміти, яка інформація розмічена в документі. Не нехтуйте семантикою, пишіть код HTML якісно і дбайте про ваших майбутніх користувачів!
Побудова структури сторінки
В першій секції ми говорили про структурний кістяк документа. Та, мабуть, ви вже почали здогадуватися, що це тільки вершина айсбергу структури веб-сторінки.
Так і є. Внутрішня структура документа, тобто все, що знаходиться всередині тегу <body>
, зазвичай набагато більша і розгалуженіша. “Внутрішня” структура залежить від дизайну веб-сторінки, тому якогось одного рецепту, по якому будуються всі веб-сторінки просто немає. Менше з тим, більшість веб-сторінок будуються за типовими макетами (англ. layout), які мають спільні по змісту блоки.
На жаль, переклад цієї термінології на українську мову не буде вдалим, тому я буду використовувати англіцизми.
Аналіз структури макету
Припустимо, потрібно створити розмітку веб-сторінки за наступним макетом:
Перше що треба зробити, це уважно роздивитися макет і спробувати виділити окремі логічні блоки. Притомні веб-дизайнери, готуючи макет або дизайн сайту, міркують категоріями, близькими до тих, якими оперує фронтенд-розробник і часто ці блоки досить легко виділити.
Я виділив наступні зони на цьому макеті:
Про що ці зони:
- Блок із назвою сайту (логотипом).
- Блок із навігацією.
- Контентна область.
- Блок із копірайтом.
В фронтент-розробці, як і в веб-дизайні, деякі із цих зон мають вже сталі терміни: верхівка сторінки називається хедером (шапкою), низ — футером (підвалом). Можливо, ця інформація якось допоможе нам у пошуку підходящих тегів для розмітки?
Підбір правильних тегів
Прийшов час подивитися в довідник тегів, наприклад, в секцію про розбивку контенту на логічні блоки, і пошукати підходящі HTML-елементи.
Перше, що я знайшов — тег <footer>
, в описі тегу сказано, що він добре підходить, в тому числі, для блоків із копірайтом. Здається, він підходить для розмітки зони 4
.
Далі я бачу тег <header>
, в описі якого сказано, що він гарно підходить для всіляких навігаційних штук, а також в ньому добре почувається логотип сайту. Хммм, здається, цей елемент ідеально підходить для зони 1
і 2
.
О, тут є ще один цікавий тег — <main>
, що слугує для розмітки головної контентної зони веб-сторінки. Вгадаєте, яка зона із цим тегом парочка? Так, та, що під номером 3
.
Ну і на солоденьке: <nav>
— буквально, тег для навігації, найкращий кандидат для області під номером 2
!
Отже, беремо робочу заготовку HTML-документа і додаєм в <body>
все, що ми знайшли:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Про мене - Epic Baboon</title>
<meta name="description" content="Да хто то такий цей Epic Baboon?">
</head>
<body>
<header>
<a href="#" title="Завітайте на головну сторінку">Epic Baboon</a>
<nav>
<a href="#posts">Пости</a> |
<a href="#gallery">Галерея</a> |
<a href="#about">Про мене</a>
</nav>
</header>
<main>
</main>
<footer>© Epic Baboon 2022</footer>
</body>
</html>
Зверніть увагу на елемент <a>
із назвою сайту. Категорії контенту, до яких відноситься тег <a>
дозволяють йому бути як тегом, що зустрічається всередині тексту (типу, як посилання в цій статті), так і структурним тегом. В прикладі він виступає саме як тег із категорії структурного контенту, тому сміливо використовуйте його таким чином, тобто без потреби загортати його в інший тег.
Я спеціально залишив пустим тег <main>
, в якому має бути розмічений контент із блоку 3
, щоб ви могли самостійно попрактикуватися. Попереднє практичне завдання якраз буде гарною основою до цієї практики.
Отже, на основі коду із попереднього практичного завдання і коду із прикладу вище, потрібно розмітити веб-сторінку із макету.
Що зробити
Додайте в тег <main>
необхідні елементи, що розмітять структуру сторінки:
- заголовок,
- світлину (
https://ebaboon.me/images/baboon.jpg
) - і абзац.
Додаткова задача, кому мало:
- Замість текстового логотипу
Epic Baboon
, зробіть логотип-світлину. Ось її адреса:
https://ebaboon.me/images/ebaboon_logo_black.png
☝️ Мушу вас попередити: без стилізації результат розмітки не буде виглядати таким, як на макеті. Не все зразу. Але не засмучуйтесь, адже ми розглядаємо саме розмітку документа і це база, яку треба вміти робити добре, і ви тільки вчитеся це робити. Структура — перша! А магія стилей буде трошечки згодом.
Cекретний інгрідієнт
Є дещо важливе, що розробники часто ігнорують — веб-доступність. Половина діла зроблена, якщо ви використовуєте елементи за призначенням і мінімізуєте використання несемантичних тегів. Тим не менше, треба звернути увагу на ті місця, де семантичності недостатньо і добавити ролі і атрибути aria-*
, або інші атрибути, що покращують веб-доступність.
Ця тема досить об’ємна і тут я опишу базовий підхід до цієї тематики на простому прикладі.
Спробуйте уявити себе на місці людини, що вперше попала на вашу веб-сторінку, має сенсорні порушення і орієнтується за скрінрідером. Давайте додамо деякі покращення до документа, що спростять життя такому користувачу:
-
Додаємо атрибут
lang="uk"
, що вказує на мову, яка використовується в документі, щоб скрінрідер правильно інтерпретував мову сторінки. -
Атрибут
aria-label
до посилання “Epic Baboon”, щоб той же скрінрідер зміг пояснити користувачу, що це теж частина навігаціїї сайта, хоча його текст трохи дивний і не пояснює, куди саме користувача перекине, якщо він перейде по цьому посиланню. До цього посилання особливе ставлення, бо воно не в середині тегу<nav>
, які скрінрідери розуміють однозначно, хоча теж навігаційного характеру.
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="utf-8">
<title>Про мене - Epic Baboon</title>
<meta name="description" content="Да хто то такий цей Epic Baboon?">
</head>
<body>
<header>
<a
href="#"
title="Завітайте на головну сторінку"
aria-label="Посилання на головну сторінку блогу 'Epic Baboon'"
>Epic Baboon</a>
<nav>
<a href="#posts">Пости</a> |
<a href="#gallery">Галерея</a> |
<a href="#about">Про мене</a>
</nav>
</header>
<main>
</main>
<footer>© Epic Baboon 2022</footer>
</body>
</html>
Якщо подивитися на код сторінки тієї ж Вікіпедії, як гарного приклада використання атрибутів, що покращують веб-доступність, то можна побачити, що ролі і атрибути aria-*
навішуються навіть на семантичні теги. Наприклад, використано семантичний тег <footer>
із атрибутом role="contentinfo"
, який означає, що елемент виконує роль футера:
<footer role="contentinfo">...</footer>
Це перестраховка свого роду, щоб вже точно спрацювало хоч щось і користувач із обмеженями зміг орієнтуватися на сторінці. Звісно, вам ніхто не заборонить так робити, але сучасні рекомендаціїї зводиться до того, щоб не використовувати додатково ці атрибути на семантичних тегах, окрім випадків, коли це доповнює семантику елемента, а не перевизначає її.
Логічно припустити, що після змін, які ви зробили в попередньому практичному завданні, було б непогано подумати про веб-доступність в цих елементах.
Загалом, той HTML, який ви маєте написати для попереднього практичного завдання, має бути і без того семантичним та не потребує додаткових ролей або атрибутів. Окрім елемента із світлиною.
Що зробити:
- розберіться, навіщо атрибут
alt
в елементі<img>
, - внесіть необхідні зміни в документ.
Все разом
-
Базова структура кожного HTML-документа однакова і досить проста:
<!DOCTYPE html> <html> <head> </head> <body> </body> </html>
-
Реальна заготовка для HTML-документа трошки складніша, але не набагато:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Назва сторінки</title> <meta name="description" content="Короткий опис, про що ця сторінка."> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> </body> </html>
Весь контент, який видно в браузері, має знаходитися всередині
<body>
-
Деякі елементи не можуть містити в собі інші. Перевіряйте по документації або валідатором HTML.
-
Ніколи не забувайте, що у тегів є семантика. Застосовуйте теги за призначенням!
-
Семантика і веб-доступність — нерозлучні.
Корисні посилання
- Більш докладна інформація про особливий тег
<!DOCTYPE>
від W3C. - W3Schools про семантичні елементи і особливості їх застосування.
- Валідатор HTML від W3C.
- Категорії контенту за специфікацією HTML від MDN.
- Розділ про веб-доступність в HTML від MDN з практичними рекомендаціями.
- Довідник ролей і
aria-*
атрибутів від MDN. - Довідкова інформація про атрибут
alt
від W3Schools. - Довідник мовних кодів від W3Schools.
Домашнє завдання
Виконайте всі практичні завдання із цієї статті:
- завдання по створенню HTML-документа,
- створення HTML-структури за макетом,
- покращення веб-доступності в створеному документі.
Невеличке завдання від W3Schools:
- HTML Коментар 1 і 2