Модель візуального форматування
У CSS модель візуального форматування описує те, як користувацькі агенти беруть дерево документа й обробляють і подають його візуальними медіа. Серед таких медіа – неперервні медіа, як то екран комп'ютера, та медіа зі сторінками, як то книга чи документ, надрукований за допомогою функцій друку браузера. Більшість інформації застосовується однаково до неперервних медіа та медіа зі сторінками.
У моделі візуального форматування кожний елемент у дереві документа генерує нуль або більше рамок, відповідно до рамкової моделі. Розміщення цих рамок визначається:
- Розмірами та типом рамок.
- Схемою розташування (нормальним потоковим, пливним та абсолютним розташуванням).
- Взаємовідношенням між елементами в дереві документа.
- Зовнішньою інформацією (наприклад, розміром області перегляду, природними розмірами зображень тощо).
Значна частина інформації про модель візуального форматування визначена в CSS2, проте різні специфікації рівня 3 також доклалися до такої інформації. При читанні специфікацій нерідко зустрічаються посилання на модель, як вона визначена в CSS2, тож розуміння цієї моделі та термінів, що використані для її опису в CSS2, є цінним при читанні інших специфікацій компонування.
У цьому документі дається визначення цієї моделі, а також вводяться деякі пов'язані терміни та концепції, з посиланнями на більш конкретні сторінки ВебДоків, для отримання додаткових відомостей.
Роль області перегляду
В неперервних медіа область перегляду – це область перегляду вікна браузера. Користувацькі агенти можуть змінювати компонування сторінки, коли змінюється розмір області перегляду – наприклад, якщо змінюється розмір вікна, або змінюється орієнтація мобільного пристрою.
Якщо область перегляду менша за розмір документа, то користувацькому агенту необхідно запропонувати спосіб прокручення до частин документа, що не показані. Найчастіше це спостерігається у вигляді прокручення у блоковому напрямку – вертикально у горизонтальній мові, що записується згори вниз. Проте також можна розробити щось, що вимагає прокручення у рядковому напрямку.
Породження рамок
Породження рамок – це частина моделі візуального форматування CSS, що утворює рамки на основі елементів документа. Породжені рамки належать до різних типів, що впливає на їхнє візуальне форматування. Тип породженої рамки залежить від значення властивості CSS display
.
Бувши спершу визначеною в CSS2, властивість display
була розширена в Модулі виведення CSS рівня 3. Крім цього, частина термінології щодо виведення була оновлена та уточнена протягом років після CSS2.
CSS бере вихідний документ та візуалізує його на полотні. Щоб це виконати, вони породжують проміжну структуру, рамкове дерево, котре представляє форматувальну структуру документа, що візуалізується. Кожна рамка рамкового дерева представляє відповідний собі елемент (або псевдоелемент) у просторі чи часі на полотні, тоді як кожен текстовий рядок у рамковому дереві також представляє вміст відповідних йому текстових вузлів.
Після цього CSS генерують для кожного елемента нуль або більше рамок, як це задано значенням властивості display
такого елемента.
[!NOTE] Рамки нерідко називають за їхніми типами виведення: наприклад, рамку, породжена елементом з
display: block
, зветься "блоковою рамкою" або просто "блоком". Проте зверніть увагу, що блокові рамки, рамки блокового рівня та рамкові контейнери – трохи не одне й те саме; більше подробиць дивіться у розділі Блокові рамки нижче.
Головна рамка
Коли елемент породжує одну або більше рамок, то одна з них – головна рамка, що містить рамки-нащадки та породжений вміст у рамковому дереві, а також є рамкою, що бере участь у будь-якій схемі позиціонування.
Частина елементів може породжувати додаткові рамки, окрім головної, наприклад, display: list-item
породжує більше одної (наприклад, головну блокову рамку та дочірню маркерну рамку). А деякі значення (наприклад, none
і contents
) змушують елемент чи його нащадків не породжувати жодних рамок узагалі.
Анонімні рамки
Анонімна рамка утворюється тоді, коли немає HTML-елемента, що можна використати для рамки. Ця ситуація виникає, наприклад, коли визначається display: flex
для батьківського елемента, а безпосередньо всередині є рядок тексту, що не міститься в іншому елементі. Щоб виправити рамкове дерево, навколо цього рядка тексту створюється анонімна рамка.Далі вона поводиться як гнучкий елемент, проте її не можна виділити та оформити як звичайну рамку, оскільки немає елемента, на який можна спрямувати правило.
<div class="flex">
Я загорнутий у анонімну рамку
<p>Я в абзаці</p>
Я загорнутий у анонімну рамку.
</div>
body {
font: 1.2em sans-serif;
margin: 20px;
}
.flex {
display: flex;
}
.flex > * {
background-color: rebeccapurple;
color: white;
}
Те саме трапляється, коли є рядки тексту, що перериваються блоковими елементами. У наступному прикладі є рядок всередині <div>
; посередині рядка є елемент <p>
, що містить частину тексту.
<div class="example">
Я загорнутий у анонімну рамку
<p>Я в абзаці</p>
Я загорнутий у анонімну рамку.
</div>
body {
font: 1.2em sans-serif;
margin: 20px;
}
.example > * {
background-color: rebeccapurple;
color: white;
}
У рамковому дереві цей рядок розбивається на три рамки. Частина рядка перед елементом абзацу обгортається анонімною рамкою, потім стоїть <p>
, що породжує рамку, і ще одна анонімна рамка.
Про ці анонімні рамки слід усвідомити, що вони успадковують стилі від свого безпосереднього предка, але не можна змінити їхній вигляд, націливши правило на анонімну рамку. У прикладах тут використовується безпосередній дочірній селектор, щоб націлитись на дочірні елементи в контейнері. Це не впливає на анонімні рамки, адже вони не є "елементами" як такі.
Рядкові анонімні рамки утворюються тоді, коли рядок розбивається рядковим елементом, наприклад, це речення, що вміщає розділ, загорнутий в <em></em>
. Це розбиває речення на три рядкові рамки: анонімну рядкову рамку перед виділеним розділом, розділ, що обгортається елементом <em>
, і ще одну анонімну рядкову рамку. Як і анонімні блокові рамки, такі анонімні рядкові рамки не можна оформити незалежно, як <em>
, вони лише успадковують стилі свого контейнера.
Інші контексти форматування також утворюють анонімні рамки. Сіткове компонування поводиться так само, як і приклад флексбоксу вище, перетворюючи рядки тексту на елемент сітки з анонімною рамкою. Багатоколонкове компонування створює анонімні рамки навколо колонок; їх також не можна оформити або ще якось націлити на них правила. Табличне компонування додає анонімні рамки, щоб створити правильну структуру таблиці, – наприклад, додаючи анонімний рядок таблиці, – якщо немає рамки з display: table-row
.
Рядкові рамки
Рядкові рамки – це рамки, що обгортають кожен рядок тексту. Різницю між рядковими рамками та їхнім контейнером можна побачити, якщо зробити елемент пливним, а потім додати блок з фоновим кольором.
У наступному прикладі рамкові рамки, що стоять після пливного <div>
, скорочені, щоб обійти пливун. Тло рамки йде під пливуном, адже пливний елемент – вийнятий з потоку.
<div class="float"></div>
<p class="following">
Цей текст стоїть після пливуна, рядкові рамки скорочені, щоб утворити простір
для пливуна, проте рамка елемента все одно займає позицію в звичайному плині.
</p>
body {
font: 1.2em sans-serif;
margin: 20px;
}
.float {
float: left;
width: 150px;
height: 150px;
background-color: rebeccapurple;
margin: 20px;
}
.following {
background-color: #ccc;
}
Схеми позиціонування та елементи в потоці й поза ним
У CSS рамка може бути розміщена за трьома схемами позиціонування: звичайним потоком, пливунами й абсолютним позиціонуванням.
Звичайний потік
У CSS звичайний потік включає форматування блокового рівня блокових рамок, форматування рядкового рівня рядкових рамок, а також відносне та липке позиціонування рамок блокового та рядкового рівнів.
Читайте більше про потокове компонування в CSS.
Пливуни
У пливній моделі рамка спершу розміщається згідно зі звичайним потоком, а потім виймається з потоку та позиціонується, зазвичай до лівого або правого краю. Вміст може розтікатися вздовж краю пливуна.
Дізнайтеся більше про пливуни.
Абсолютне позиціонування
У моделі абсолютного позиціонування (котра також вміщає фіксоване позиціонування) рамка повністю прибирається зі звичайного потоку та отримує позицію відносно контейнерного блока (у випадку фіксованого позиціонування це область перегляду).
Елемент зветься позапотоковим, якщо він пливний, абсолютно позиціонований, або є кореневим елементом. Елемент зветься потоковим, якщо він не перебуває поза потоком.
Читайте більше про позиційне компонування CSS.
Форматувальні контексти та властивість display
Можна сказати, що рамки мають зовнішній тип виведення – або block
, або inline
. Цей тип зовнішнього виведення вказує на те, як рамка поводиться поруч з іншими елементами на сторінці.
Рамки також мають внутрішній тип виведення, що диктує те, як поводяться їхні дочірні рамки. Для звичайного блокового та рядкового компонування, тобто звичайного потоку, цей тип виведення – flow
. Це означає, що дочірні елементи також будуть або block
, або inline
.
Проте внутрішній тип виведення може бути чимось штибу grid
або flex
, у випадку чого безпосередні дочірні елементи виводитимуться як сітка або як гнучкі елементи. У такому випадку про елемент кажуть, що він утворює сітковий або гнучкий форматувальний контекст. Багато в чому це подібно до блокового форматувального контексту, але дочірні елементи поводяться як гнучкі або сіткові елементи, а не елементи у звичайному потоці.
Взаємодія між рамками блокового та рядкового рівнів описана в документації ВебДоків про display
.
На додачу, довідка про конкретні значення display пояснює те, як ці форматувальні контексти працюють у термінах рамкового компонування.
Незалежні форматувальні контексти
Елементи або беруть участь у форматувальному контексті їхнього контейнерного блока, або утворюють незалежний форматувальний контекст. Сітковий контейнер, наприклад, утворює для своїх дочірніх елементів новий Сітковий форматувальний контекст.
Незалежні форматувальні контексти вміщають пливуни, а зовнішні поля не перекриваються через межі форматувального контексту. Тож створення нового блокового форматувального контексту може забезпечити, що пливуни та зовнішні поля залишаться всередині рамки. Для цього необхідно додати до рамки, на якій потрібний новий блоковий форматувальний контекст, display: flow-root
.
Наступний приклад демонструє дію display: flow-root
. Рамка з чорним тлом ніби обгортає пливний елемент і текст. Якщо вилучити display: flow-root
, то пливун виступатиме знизу рамки, оскільки він більше не буде обмежуватися всередині.
<div class="container">
<div class="item">Пливун</div>
<p>Текст, що стоїть після пливуна.</p>
</div>
.container {
display: flow-root;
}
.item {
margin: 10px;
float: left;
}
Блокові рамки
У специфікаціях, у певних місцях, і блокові рамки, і рамки блокового рівня, і блокові контейнери звуть блоковими рамками. Ці поняття трохи відрізняються, і термін блокової рамки повинен вживатися лише тоді, коли немає неоднозначності.
Блокові контейнери
Блоковий контейнер або вміщає лише рамки рядкового рівня, що беруть участь в рядковому форматувальному контексті, або лише рамки блокового рівня, що беруть участь у блоковому форматувальному контексті. Через це спостерігається поведінка, описана вище, коли вводяться анонімні рамки, аби пересвідчитися, що всі елементи можуть брати участь у блоковому або рядковому форматувальному контексті. Елемент є блоковим контейнером лише тоді, коли вміщає рамки блокового або рядкового рівня.
Рамки рядкового та блокового рівня
Це рамки, вміщені всередині блокового контейнера, що беруть участь у рядковому і блоковому компонуванні відповідно.
Блокові рамки
Блокова рамка – це рамка блокового рівня, що також є блоковим контейнером. Як описано в CSS display
, елемент може бути рамкою блокового рівня, але не бути блоковим контейнером (наприклад, він може бути гнучким або сітковим контейнером).
Дивіться також
- Ключові концепції CSS: