Skip to main content

Властивість CSS overflow

CSS overflow визначає, що відбувається з контентом, який не вміщується в контейнер: він може вийти за межі, обрізатися або стати прокручуваним.

Теорія

Коротко

  • Уявіть акваріум: visible дає воді розтекатися, hidden герметично запечатує, scroll додає постійні трубки, auto додає їх тільки коли вода переповнюється.
  • Головна різниця між auto і scroll: auto показує скролбар тільки коли контент виходить за межі; scroll завжди його рендерить.
  • overflow: hidden створює Block Formatting Context (BFC), який автоматично огортає флоатовані елементи.
  • Правило вибору: hidden для чіткого обрізання UI (картки, аватари), auto для динамічного контенту як чати або сайдбари.

Швидкий приклад

css
/* Обрізає дочірній контент до форми картки */ .card { overflow: hidden; border-radius: 12px; width: 300px; height: 200px; } /* Скролбар з'являється тільки коли повідомлення переповнюють контейнер */ .chat { overflow-y: auto; max-height: 400px; /* Без цього контейнер просто росте нескінченно */ }

Перше правило обрізає все що виходить за межі картки. Друге фіксує висоту списку повідомлень і додає вертикальний скролбар тільки за потреби.

Значення

ЗначенняПоведінка
visibleЗа замовчуванням. Контент рендериться за межами блоку.
hiddenОбрізає контент. Без скролбара. JS scrollTop працює.
scrollСкролбар завжди видимий, навіть на короткому контенті.
autoСкролбар з'являється тільки при переповненні.
clipЯк hidden, але JS scrollTop не має ефекту.

Ключова різниця

auto і scroll обидва роблять контент прокручуваним, але scroll завжди рендерить доріжку скролбара незалежно від розміру контенту. На деяких платформах це резервує місце і зміщує layout. auto - безпечніший варіант для більшості ситуацій. scroll має сенс коли потрібно щоб скролбар завжди був присутній візуально, наприклад у горизонтальній навігації де ви хочете показати що контент продовжується за межами екрана.

overflow-x та overflow-y

Осі можна контролювати незалежно:

css
/* Горизонтальний скрол, вертикальне переповнення приховане */ .tag-list { overflow-x: auto; overflow-y: hidden; white-space: nowrap; -webkit-overflow-scrolling: touch; /* Нативне відчуття на iOS */ }

Цей патерн зустрічається в списках тегів, горизонтальних каруселях і Bootstrap-компоненті .table-responsive.

Коли застосовувати

  • Картка з довгим текстом: overflow: hidden (чисте обрізання)
  • Чат, сайдбар, тіло модального вікна: overflow-y: auto з max-height
  • Горизонтальна навігація або таблиця даних: overflow-x: auto для мобільних
  • Елемент body при відкритті модалки: overflow: hidden блокує фоновий скрол
  • Картка з округленими кутами або аватар: overflow: hidden обрізає зображення до форми контейнера

overflow: hidden та BFC

Встановлення overflow в hidden, auto або scroll створює Block Formatting Context (контекст форматування блоку). Практичний результат: контейнер огортає флоатовані дочірні елементи замість того щоб зколапсуватися до нульової висоти. Це був стандартний спосіб очистки флоатів до появи display: flow-root. У старих кодових базах такий підхід зустрічається досі.

css
.container { overflow: hidden; /* BFC: огортає флоатовані елементи, без колапсу висоти */ }

Типові помилки

Забути висоту при overflow: auto.

css
/* Неправильно: контейнер росте нескінченно, скрол не спрацьовує */ .list { overflow-y: auto; } /* Правильно */ .list { overflow-y: auto; height: 300px; }

Без обмеження висоти контейнер просто розтягується. Нема чого переповнювати.

Вважати що overflow: hidden обрізає обидві осі.

css
/* Дочірній елемент може виходити горизонтально */ .parent { overflow: hidden; } .child { width: 500px; } /* Вкажіть потрібну вісь явно */ .parent { overflow-x: hidden; }

Використовувати overflow: scroll на мобільних. Постійно видимий скролбар може конфліктувати з нативним прокручуванням і створювати подвійні доріжки. Краще overflow: auto з -webkit-overflow-scrolling: touch.

Плутати hidden і clip. Обидва обрізають контент візуально. clip також блокує JS scrollTop. Якщо потрібно керувати позицією скролу в коді, використовуйте hidden.

Де зустрічається на практиці

  • shadcn/ui Dialog: overflow: auto на .modal-body для прокручуваного контенту модалки
  • TailwindCSS: клас overflow-hidden на картках в шаблонах Next.js
  • Bootstrap: .table-responsive використовує overflow-x: auto для широких таблиць на мобільних
  • VS Code: панелі сайдбара комбінують overflow: hidden з ресайз-хендлерами

Питання на співбесіді

Q: Яка різниця між overflow: hidden і overflow: clip?
A: Обидва обрізають контент візуально. clip додатково блокує всі scroll-події, зокрема JS scrollTop. hidden дозволяє програмне прокручування. Якщо потрібно змінювати позицію скролу в коді, використовуйте hidden.

Q: Як overflow взаємодіє з flexbox?
A: Встановлення overflow на flex-контейнері тільки обрізає або прокручує вміст. На вирівнювання flex-елементів воно не впливає. Щоб окремий flex-елемент прокручувався, ставте overflow на нього, не на контейнер.

Q: Чому overflow-x: auto не показує скролбар коли контент влазить?
A: Браузери приховують доріжку скролбара поки контент не переповниться. Це і є суть auto. Якщо потрібна постійна доріжка, використовуйте scroll.

Q: Як overflow: hidden на body блокує фоновий скрол при модалці і що ламається в iOS Safari?
A: Він обрізає прокручуваний вміст body, тому користувач не може скролити за модалкою. iOS Safari може обійти це через momentum scroll. Фікс: body { overflow: hidden; position: fixed; width: 100%; }. Майте на увазі, що це скидає scrollY до 0, тому позицію потрібно зберегти і відновити вручну.

Приклади

Обрізання зображення до форми картки

html
<style> .card { width: 250px; height: 180px; overflow: hidden; border-radius: 12px; } .card img { width: 100%; height: 100%; object-fit: cover; } </style> <div class="card"> <img src="photo.jpg" alt="Фото профілю" /> </div>

Без overflow: hidden кути зображення виходять за межі округленого бордера. З ним зображення обрізається по формі картки. Саме такий патерн TailwindCSS використовує на картках у своїх шаблонах.

Прокручуваний контейнер чату

jsx
function ChatMessages({ messages }) { return ( <div style={{ height: '400px', overflowY: 'auto', /* Скрол тільки за потреби */ border: '1px solid #ccc', padding: '8px' }}> {messages.map(msg => ( <div key={msg.id}>{msg.text}</div> ))} </div> ); }

Контейнер залишається фіксованим на 400px. Як тільки повідомлення перевищують цю висоту, з'являється скролбар. Приберіть height: 400px і скролбар не з'явиться ніколи, скільки б повідомлень не завантажилося. Це найпоширеніша помилка яку зустрічаю на код-рев'ю.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?