Переповнення і втрата даних в CSS

У цій статті відомий веб-розробник Рейчел Ендрю розглядає ситуації, в яких можно зіткнутися з переповненням при верстці сайтів, і пояснює, як розвивався CSS, щоб створювати більш ефективні методи розмітки в ситуаціях, коли обсяги контенту заздалегідь невідомий.

CSS був спроектований, щоб вміст був легким для читання. Якщо ви розглядаєте HTML-документ, який розмічений за допомогою заголовків і параграфів (без застосування CSS), він відображається в браузері в зручному для читання вигляді. Заголовки великі і напівжирні, а між параграфами залишається простір, який контролюється таблицями стилів, вбудованими в браузер. Однак, як тільки буде потрібно змінити макет сторінки, ви почнете брати контроль над оформленням в свої руки. У деяких ситуаціях це означатиме, що ви берете на себе роботу з переповненням елементів.

У цій статті будуть розглянуті різні ситуації, при яких можно зіткнутися з переповненням в інтернеті. Буде відомо, як нові методи розмітки і нові значення в CSS можуть допомогти впоратися з переповненням і створювати менш крихкий дизайн. Також будуть пояснення про одну з фундаментальних концепцій, що лежать в основі проектування на CSS – це запобігання втрати даних.

Що мається на увазі під переповненням?

Якщо повернутися на кілька років назад (перед приходом таких методів розмітки, як Flexbox і Grid), подумайте, як би ви реалізували приклад, відображений нижче. Дуже простий макет з трьох блоків, що мають різну кількість вмісту, але нижня межа яких повинна бути на одній лінії.

За допомогою float таке, здавалося б, просте завдання було неможливе. Коли блок стає обтічним (float), він ніяк не взаємодіє з сусідніми; це означає, що немає можливості дізнатися, що наступний елемент вище і збільшити поточний до такої ж висоти.

Іноді, намагаючись вибудувати елементи на одній лінії, розробники ставили фіксовану висоту блоків, намагаючись вгадати кількість можливого вмісту, щоб зробити висоту однаковою. Звичайно, в інтернеті все не так просто і коли кількість вмісту відрізнялася, або розмір тексту ставав більше, текст починав виходити за нижню межу блоку. Це і було переповнення (overflow).

Іноді люди запитують, як вони можуть запобігти потраплянню занадто великої кількості вмісту на сайт. У техпідтримку CMS Ендрю зверталися користувачі, які запитували, як обмежити вміст з цієї самої причини. Вони говорили, що цей додатковий контент «ламає макет». Для тих з нас, хто розумів, що неможливість дізнатися висоту елементів було фундаментальною природою верстки, треба було створювати макети, які приховували відсутність рівних за висотою блоків. Поширеним рішенням було додавання градієнта з ефектом зникнення контенту, що виходить за межі. Ми б уникали використання фонових кольорів і рамок для блоків. Або ми б використовували техніки створення штучних колонок, щоб зробити висоту елементів однаковою.

Ця нездатність контролювати висоту одного елементу щодо інших впливала на веб-дизайн – технічне обмеження змінювало спосіб проектування сайтів. З появою Flexbox і Grid ця проблема не просто зникла, а й за замовчуванням поведінку цих нових методів розмітки розтягують блоки на однакову висоту. Початкове значення властивості align-items – stretch, через яку блоки розтягуються на висоту Grid-області або Flex-контейнеру.

Крім того, CSS Grid дає нам хороший спосіб задавати елементам певний розмір, але дозволяти збільшуватися, якщо їм це потрібно. Якщо ви задасте розмір треку (колонки або рядка), використовуючи функцію minmax (), зможете побачити його мінімальний і максимальний розмір. Установка для рядків значення minmax (200px, auto) означає, що трек завжди буде принаймні, 200px, навіть якщо елементи сітки порожні. Однак, якщо вміст grid-елементу більше 200px, завдяки значенню auto цей елемент може рости.

Функція minmax () дає можливість створювати інтерфейси так, ніби вони мають ідеальний фіксований розмір. В ідеальному світі (коли кількість вмісту відповідає очікуванням), ви отримаєте ці красиві однакові рядки. Однак, якщо додати додатковий контент, не відбудеться переповнення, як якщо б ви задали фіксовану висоту рядків в 200px. Рядок буде розширюватися; це може бути не зовсім те, чого хотілося б вам, як розробнику, але це не буде нечитабельним.

Рядкове переповнення

Ризик переповнення виникає щоразу, коли ми обмежуємо ширину блоку. Це те, що ми бачимо в мемі «CSS is Awesome».

Автор цього мему, прокоментував публікацію на CSS-Trick про це, сказавши:

“Тепер я трохи краще розумію концепцію переповнення, але в той час мій мозок просто підривало нерозуміння того, чому хтось подумав, що поведінка за умовчанням має просто виштовхувати текст праворуч від блоку, замість того, щоб зробити блок більше, як це завжди робили таблиці .”

Так чому CSS виштовхує текст за рамки блоку, замість збільшення розміру самого блоку?

У мемі виходить переповнення в рядковому напрямку. Слово «awesome» більше, ніж ширина, застосована до блоку, тому і переповнює його. CSS досить розумно передбачає, що якщо ви задали блоку певну ширину, вам потрібен блок саме такої ширини. Можливо, він повинен поміститися в макет, який зламається, якщо блоки раптово стануть більше, ніж було встановлено.

Ця конкретна проблема (тобто, необхідність ставити розміри всіх елементів макету і переконуватися, що в сумі вони не перевищують обсяг пам’яті, доступний контейнеру), – це та проблема, яку сучасні методи верстки вирішують для нас. Якщо ми уявимо, що наш блок має такий спеціально підібраний розмір, щоб поміститися в рядок з іншими блоками в float-сітці, сьогодні замість цього ви можете вибрати використання Flexbox.

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

Однак, якщо ми використовуємо Flexbox, ми можемо дозволити браузеру розрахувати, скільки простору віддавати кожному елементу. Flexbox забезпечить більші елементи більшим простором, а маленькі отримають менше. Цей гнучкий розподіл розмірів означає, що блок, який містить слово «awesome» збільшиться, щоб вмістити весь контент і текст не вийде за його рамки. Проблема переповнення вирішена; така поведінка є саме тим, для чого Flexbox був створений. Flexbox відмінно справляється з елементами різного розміру і організовує їх в найбільш підходящий для них макет.

Поза Flexbox можна сказати, що наш блок повинен бути настільки великим, наскільки це потрібно для контенту і не більше. Ключове слово min-content може бути використано як значення для властивості width або inline-size при роботі з логічними властивостями, що відносяться до потоку. Встановіть width: min-content і блок збільшиться настільки, щоб вмістити слово «awesome».

Запобігання втрати даних

Причина, за якою блок переповнюється (як в прикладі зі словом, що виходить за кордон блоку) полягає в тому, що у властивості overflow значенням за замовчуванням є visible. Ви можете (якщо захочете) керувати переповненням по-іншому. Наприклад, використання overflow: auto або overflow: scroll могло дати вашому блоку смугу прокрутки. Це, можливо, не те, чого б вам хотілося в цій ситуації, але можуть бути ситуації, коли блок зі смугою прокрутки буде доречний.

Також можна було припустити, що ви готові обрізати переповнення за допомогою overflow: hidden. Можливо, ви могли подумати, що приховувати переповнення було б краще за замовчуванням, однак, той факт, що CSS вибрав робити переповнення за замовчуванням видимим (а не прихованим), є ключем до основної цінності CSS-розробки. В CSS (як і в безлічі інших технологій), ми намагаємося уникнути втрати даних. Коли ми говоримо про втрату даних в CSS, ми зазвичай говоримо саме про частину контенту, яку стане не видно. У випадку з overflow: hidden, контент, який переповнює батьківський блок, зникає. Це означає, що у нас немає способу дістатися до нього, щоб дізнатися яку частину ми втратили.

У певних ситуаціях це може бути серйозною проблемою. Якщо ви примудрилися зробити верстку настільки крихкою, що кнопка вашої форми вийшла за межі видимої області, у ваших користувачів не буде можливості відправити форму. Якщо останній абзац тексту обрізаний, ми ніколи не дізнаємося, чим закінчилася історія. Також, проблема зі зникаючим елементами полягає в тому, що не завжди очевидно, що вони пропали. Як розробник, ви можете не помітити проблему, особливо якщо це відбувається тільки за певними розмірами області перегляду в чуйному дизайні. Ваші користувачі можуть не помітити проблему – вони просто не побачать заклик до дії, або подумають, що проблема, через яку вони не можуть зробити замовлення, в їх пристрої і просто підуть. Проте, якщо елементи переповнюються там, де не повинні, ви, швидше за все, помітите це. Або, в гіршому випадку, хтось, хто зайшов на сайт, помітить це і дасть вам знати.

Саме тому в CSS елементи переповнюються неохайно і досить помітно. Явно бачачи переповнення, ви з більшою ймовірністю виправите помилку, ніж якщо зайвий вміст просто буде прихований. Однак, за допомогою властивості overflow ви отримуєте можливість самостійно приймати рішення щодо того, що має статися. Якщо ви хотіли б, щоб переповнення обрізалось (що може бути правильним рішенням в певних ситуаціях), використовуйте overflow: hidden.

Втрата даних і вирівнювання

Кращі інструменти вирівнювання, які ми отримали за останні кілька років, також можуть призводити до втрати даних. Розглянемо колонку flex-елементів, які знаходяться біля краю області перегляду і мають різні розміри. При вирівнюванні значенням flex-start, елементи виступають вправо. Однак, при вирівнюванні у центрі значенням center, більш широкий елемент буде виходити за межі області перегляду. Тому вирівнювання може привести до втрати даних.

Щоб запобігти випадкової втрати даних, викликану вирівнюванням, тепер в CSS є кілька нових ключових слів, які можуть бути використані спільно з властивостями вирівнювання. Вони визначені в «Box Alignment» – специфікації, яка стосується вирівнювання у всіх методах проектування, включаючи Grid і Flexbox. В даний момент вони підтримуються тільки в Firefox.

Якщо вам потрібно вирівнювання (навіть якщо це призведе до переповнення), тоді ви можете вказати unsafe center. В цьому випадку ви запросили, щоб браузер виконав вибране вами вирівнювання, незалежно від того, що станеться з вмістом. Якщо у вас Firefox, тоді ви можете бачити два приклади: перший – з безпечним вирівнюванням, а другий – з небезпечним.

У доповіді, на підставі якої була написана ця стаття, описувалось верстку як постійну боротьбу з переповненням. Одна з істин проектування для інтернету полягає в тому, що дуже важко дізнатися, наскільки великим буде елемент, який містить текст. Проте, як показано вище, у нас ще ніколи не було стільки способів управляти переповненням або можливістю переповнення. Це означає, що наша верстка може бути набагато більш стійкою і ми можемо створювати шаблони, які будуть працювати з різним об’ємом контенту.

Джерело: habr.com