display)position)Сучасна веб-розробка неможлива без глибокого розуміння того, як браузер відображає елементи на сторінці. Основою цього процесу є блокова модель CSS (Box Model). Усе, що ми бачимо на веб-сторінці — це прямокутники, які вкладаються один в одного, розташовуються поруч або перекриваються. Розуміння цієї моделі дозволяє розробникам точно контролювати розміри, відступи та межі елементів.
Другим критично важливим аспектом є позиціювання. Не завжди достатньо стандартного потоку документа (коли елементи йдуть один за одним). Часто виникає потреба закріпити меню навігації на екрані, створити спливаюче вікно, яке перекриває контент, або точно розмістити іконку всередині кнопки. Для вирішення цих задач існують спеціальні властивості позиціювання та управління шарами (z-index).
Мета цієї лекції — розібрати анатомію HTML-елемента з точки зору CSS і навчитися ефективно керувати його розміщенням на сторінці.
Існує три основні способи додати CSS-стилі до HTML-документа. Кожен з них має свої особливості, переваги та недоліки.
Це найбільш рекомендований спосіб. Стилі записуються в окремому файлі з розширенням .css, який підключається в секції <head> за допомогою тегу <link>.
<head>
<link rel="stylesheet" href="style.css" />
<!-- CDN -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
/>
</head>
CSS-правила розміщуються безпосередньо в HTML-файлі всередині тегу <style>, зазвичай у секції <head>.
<head>
<style>
body {
background-color: #f0f0f0;
}
h1 {
color: midnightblue;
}
</style>
</head>
Стилі задаються безпосередньо в атрибуті style конкретного HTML-елемента.
<h1 style="color: red; font-size: 24px;">Привіт, світ!</h1>
| Спосіб | Де розміщується | Пріоритет | Рекомендація |
|---|---|---|---|
| External | Окремий .css файл |
Низький | Найкраща практика |
| Internal | Тег <style> у <head> |
Середній | Для специфічних сторінок |
| Inline | Атрибут style в тегу |
Високий | Уникати (тільки для JS) |
Перш ніж занурюватися у складні макети, необхідно зрозуміти фундаментальні механізми того, як CSS знаходить елементи на сторінці та які стилі до них застосовує.
Одне правило CSS (Rule set) складається з селектора та блоку оголошень.
/* Селектор { Властивість: Значення; } */
h1 {
color: blue;
font-size: 24px;
}
{}.властивість: значення;. Завжди завершується крапкою з комою ;.Браузер має вбудовану таблицю стилів (User Agent Stylesheet), яка застосовується до сторінки автоматично. Саме тому без жодного вашого CSS:
<h1> великі й жирні.<ul> мають маркери-крапки.<a> сині й підкреслені.Одним із перших кроків професійної верстки є “скидання” цих стилів (CSS Reset або Normalize.css), щоб сайт виглядав однаково у всіх браузерах.
Приклад CSS Reset:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
Селектори дозволяють обирати елементи за різними ознаками.
p { ... } — обере всі параграфи..menu-item { ... } — обере всі елементи з атрибутом class="menu-item".#main-header { ... } — обере елемент з id="main-header". (ID має бути унікальним на сторінці).* { ... } — обирає абсолютно всі елементи.div p — всі параграфи, що знаходяться всередині div (на будь-якій глибині).ul > li — тільки li, які є безпосередніми нащадками ul.h2 + p — перший параграф, що йде одразу після h2.h2 ~ p — всі параграфи, що йдуть після h2 на тому ж рівні вкладеності.Приклад:
<div>
<p>Параграф 1</p>
<p>Параграф 2</p>
<p>Параграф 3</p>
</div>
/* Всі параграфи всередині div */
div p {
color: red;
}
/* Тільки параграфи, які є безпосередніми нащадками div */
div > p {
color: blue;
}
/* Перший параграф, який йде одразу після h2 */
h2 + p {
color: green;
}
/* Всі параграфи, що йдуть після h2 на тому ж рівні вкладеності */
h2 ~ p {
color: yellow;
}
:hover (наведення миші), :focus (фокус клавіатури), :active (натискання).:nth-child(n) — n-та дитина батька (напр., li:nth-child(2) — другий пункт списку).:nth-of-type(n) — n-ний елемент даного типу.:first-child, :last-child.header {
background: silver;
& h1 {
color: white;
} /* h1 всередині header */
}
::marker {
color: red; /* колір маркера списку */
}
::selection {
background-color: yellow; /* колір виділеного тексту */
}
Коли на один елемент діють суперечливі правила (наприклад, одне фарбує в червоний, а інше в синій), браузер обчислює “вагу” (специфічність) кожного селектора.
Вага селекторів (від меншого до більшого):
div, p) — 1 бал..my-class), псевдоклас (:hover) — 10 балів.#my-id) — 100 балів.style="...") — 1000 балів.!important:
Додавання !important до будь-якої властивості перебиває всі розрахунки специфічності.
color: red !important; завжди переможе.
Порада: Використання !important вважається поганою практикою і має використовуватися лише як останній аргумент в екстрених випадках, оскільки це ламає логіку каскаду.
CSS розшифровується як Cascading Style Sheets. Каскад — це алгоритм поєднання стилів з різних джерел:
Can I use (https://caniuse.com/) — це найважливіший онлайн-сервіс для веб-розробника, який дозволяє перевірити, які властивості CSS, HTML5 або JavaScript підтримуються різними браузерами (Chrome, Firefox, Safari, Edge тощо) та їх версіями.
Веб-стандарти розвиваються дуже швидко, але не всі користувачі вчасно оновлюють свої браузери. Тому, перед тим як використовувати нову чи експериментальну можливість CSS, розробник повинен переконатися, що вона працюватиме у цільової аудиторії проекту.
Як користуватися (Приклад):
aspect-ratio або grid).Приклад: Якщо ви вирішили використовувати властивість CSS Nesting, caniuse покаже, що вона підтримується всіма сучасними браузерами, але користувачі зі старими версіями Safari (до 16.5) її не побачать. Це сигнал для розробника, що потрібно або використати інструменти автоматичної обробки коду (PostCSS), або обрати старіший спосіб написання стилів.
Інструменти розробника (DevTools)
Браузери мають вбудовані інструменти для відлагодження CSS. Щоб відкрити їх, натисніть F12 або Ctrl+Shift+I (Windows/Linux) або Cmd+Option+I (Mac).
Основні вкладки для роботи з CSS:
Поширені проблеми та як їх знайти:
padding, border або margin.position, top, left, right, bottom та z-index у вкладці Computed.Коли проект стає великим (більше 500 рядків CSS), випадкові назви класів на кшталт .box1, .red-text або .btn2 призводять до хаосу. Щоб код був зрозумілим і легким у підтримці, розробники використовують спеціальні методології.
Це найпопулярніший спосіб іменування класів, створений для створення модульних інтерфейсів.
.card, .button, .menu)..card__image, .card__title). Використовується подвійне підкреслення __..card--hot, .button--disabled). Використовується подвійний дефіс --.Приклад BEM:
<article class="product-card product-card--featured">
<img src="..." class="product-card__image">
<h3 class="product-card__title">Назва товару</h3>
<button class="product-card__button product-card__button--primary">Купити</button>
</article>
Розділяє структуру елемента та його зовнішній вигляд (шкіру). Замість створення унікального класу для кожної кнопки, ви створюєте загальні класи.
.btn (розміри, відступи)..btn-blue (колір, градієнт).
Результат: Менше повторів коду (DRY - Don’t Repeat Yourself).Пропонує ділити весь CSS на 5 категорій:
html, body).header, footer, sidebar)..is-hidden, .is-active).Методологія для керування специфічністю. Весь код організовується у вигляді перевернутого трикутника: від найбільш загальних правил (вгорі) до найбільш специфічних та важливих (внизу). Це запобігає конфліктам, коли одне правило неочікувано перебиває інше.
Замість написання “семантичних” класів (.product-card), ви використовуєте сотні маленьких “утилітарних” класів, кожен з яких робить одну річ.
Приклад (Tailwind style):
<div class="flex p-4 bg-white rounded-lg shadow-md hover:bg-gray-50">
<h2 class="text-xl font-bold text-blue-600">Заголовок</h2>
</div>
Кожен елемент на веб-сторінці браузер розглядає як прямокутний блок. Блокова модель CSS описує структуру цього блоку та визначає, як обчислюються його кінцеві розміри.
Блок складається з чотирьох основних областей (від центру до країв):
width та height.Приклад структури блокової моделі:
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid black;
margin: 15px;
}
За замовчуванням у CSS застосовується властивість box-sizing: content-box. Це означає, що властивості width та height задають розміри лише контентної області.
У прикладі вище реальна ширина елемента на екрані складатиме:
200px (width) + 20px (padding-left) + 20px (padding-right) + 5px (border-left) + 5px (border-right) = 250px.
Це було незручно, оскільки додавання відступів “ламало” сітку макету.
Сучасний підхід полягає у використанні box-sizing: border-box. В цьому режимі width та height визначають повний розмір елемента (включаючи контент, padding та border). Якщо задати width: 200px, контентна область автоматично стиснеться так, щоб у ці 200 пікселів влізли і border, і padding.
Best Practice (Найкраща практика) — застосовувати скидання box-sizing для всіх елементів на сторінці:
*,
*::before,
*::after {
box-sizing: border-box;
}
Це специфічна поведінка браузерів: коли вертикальні margin двох блоків (один над одним) зустрічаються, вони не сумуються. Замість цього береться найбільше значення з двох.
Приклад: Блок 1 має margin-bottom: 20px, Блок 2 (під ним) має margin-top: 30px. Відстань між ними буде 30px, а не 50px.
Схлопування працює лише для вертикальних відступів блокових елементів у нормальному потоці.
display)Поведінка елемента в потоці документа залежить від його типу відображення.
display: block (Блокові елементи)
width, height, margin, padding.<div>, <p>, <h1>…<h6>, <ul>, <li>.display: inline (Рядкові елементи)
width) або висоту (height).margin та padding не впливають на розташування сусідніх рядків тексту.<span>, <a>, <strong>, <em>.Приклад
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav li {
display: inline;
margin: 0 10px;
}
display: inline-block (Рядково-блокові елементи)
width, height, та повноцінні відступи (як block).<img>, <input>, <button>.display: none; — елемент повністю видаляється візуально і вилучається з потоку документа. Інші елементи займають його місце.visibility: hidden; — елемент стає прозорим/невидимим, але продовжує займати своє місце в макеті (фізично присутній для потоку).position)За замовчуванням браузер розташовує елементи один за одним: блокові зверху вниз, рядкові — зліва направо. Це називається нормальним потоком документа (Normal flow). Властивість position дозволяє виймати елементи з цього потоку або зміщувати їх.
Керування позицією відбувається за допомогою координатних властивостей: top, right, bottom, left.
position: static (Статичне — за замовчуванням)
top, left тощо на нього не діють.z-index не працює.position: relative (Відносне)
top, left зміщують елемент відносно його початкового положення.position: absolute (Абсолютне)
top, left…) відносно найближчого батьківського елемента, який має позиціювання відмінне від static (зазвичай батьку задають position: relative).<html>)..card {
/* Батько */
position: relative;
width: 300px;
height: 200px;
}
.badge {
/* Дочірній */
position: absolute;
top: -10px;
right: -10px;
}
position: fixed (Фіксоване)
position: sticky (Липке)
relative та fixed.relative (прокручується разом з контентом), поки сторінка не доскролиться до певного порогу (наприклад, top: 0). У цей момент він стає fixed і “прилипає”.Коли елементи перекривають один одного (наприклад, через абсолютне позиціювання або від’ємні марджини), браузер повинен вирішити, що відобразити зверху. За замовчуванням, елемент, який написаний у HTML-коді нижче, буде перекривати елементи, які написані вище.
Властивість z-index дозволяє змінити цей порядок. Це працює як вісь Z (глибина), спрямована на користувача.
relative, absolute, fixed, sticky).z-index: 10;, z-index: -1;).z-index перекриває елемент із меншим.Важливо: Контексти накладання (Stacking Contexts)
z-index працює не глобально по всій сторінці, а в межах локальних контекстів. Якщо Батько А має z-index: 1, а Батько Б має z-index: 2, то будь-який дочірній елемент Батька А (навіть із z-index: 9999) ніколи не зможе перекрити Батька Б.
Властивість float була створена для “обтікання” зображень текстом, подібно до того, як це робиться у традиційній типографії та газетних статтях.
float: left; — елемент притискається до лівого краю свого контейнера, а текст і вбудовані елементи обтікають його праворуч.float: right; — елемент притискається до правого краю, а текст обтікає його ліворуч.float: none; — (за замовчуванням) елемент не плаває.Приклад обтікання зображення текстом:
<img src="logo.png" style="float: left; margin-right: 15px;" />
<p>
Цей текст буде обтікати зображення з правого боку. Якщо тексту багато, він
продовжиться під зображенням, коли пройде його висоту.
</p>
Основна проблема з плаваючими елементами полягає в тому, що вони частково вилучаються з нормального потоку документа. Якщо батьківський контейнер містить лише плаваючі елементи (float: left або float: right), його висота “склопнеться” до нуля (стане 0px), оскільки браузер не враховує висоту плаваючих нащадків. Це призводить до того, що фон батька зникає, а наступні неплаваючі елементи наїжджають на плаваючі.
clear та хак .clearfixЩоб сказати браузеру “зупини обтікання і повернися до нормального потоку”, використовується властивість clear (значення left, right, або both). Вона забороняє елементу підніматися поруч із плаваючим сусідом.
Історичний хак .clearfix:
Оскільки створення додаткового порожнього <div style="clear: both;"></div> після плаваючих елементів засмічувало HTML-код, розробники придумали CSS-рішення, яке застосовується до самого батьківського контейнера:
.clearfix::after {
content: "";
display: block;
clear: both;
}
Історична довідка: Протягом багатьох років (до появи Flexbox та Grid) розробники будували цілі сітки сайтів (колонки) за допомогою float. Сьогодні використання float для макетування вважається застарілим і поганою практикою (anti-pattern). Зараз цю властивість слід застосовувати виключно за прямим призначенням — для обтікання контенту навколо зображень чи окремих блоків.
Написання CSS-коду може здаватися простим, але з часом обсяг стилів зростає, і стає легше допустити помилки, які важко відстежити. Валідація допомагає підтримувати код чистим, виправляти синтаксичні помилки та забезпечувати кращу сумісність.
Основним інструментом для перевірки відповідності вашого CSS стандартам є W3C CSS Validator (Jigsaw).
color: bluee), не закриті фігурні дужки.У професійній розробці перевірка відбувається автоматично під час написання коду за допомогою лінтерів. Найпопулярнішим для CSS є Stylelint.
;): Наступна властивість не буде розпізнана браузером.collor: red замість color: red буде просто ігноруватися браузером без жодних попереджень.width та height для елементів з display: inline, що не має ефекту.box-sizing: border-box є необхідним стандартом для передбачуваного розмічання.display) визначає, чи буде елемент переносити рядок і чи можна йому вручну задавати розміри. Блокові, рядкові та рядково-блокові мають принципові відмінності у поведінці.position. Найпопулярніша комбінація — position: relative для батька та position: absolute для нащадка.z-index керує шарами перекриття, але вимагає обережності через формування локальних контекстів накладання. Може викликати складні для відладки баги.!important і чому його варто уникати?box-sizing: border-box у розрахунку розмірів елемента?display: none та visibility: hidden?display: inline і йому задати width: 100px та margin-top: 50px?position: absolute? Що станеться, якщо у нього немає жодного спозиційованого батьківського елемента?position: sticky відрізняється від position: fixed?z-index: 999 може знаходитись ПІД елементом із z-index: 2? У яких випадках це відбувається?