Skip to content

Instantly share code, notes, and snippets.

@a-x-
Last active May 6, 2024 20:20
Show Gist options
  • Save a-x-/ffef74c3a0fda6029ad16c37320b4c7c to your computer and use it in GitHub Desktop.
Save a-x-/ffef74c3a0fda6029ad16c37320b4c7c to your computer and use it in GitHub Desktop.
`overflow: scroll` in the `display: flex` 👿😳🤔🤯

Как поместить scroll-контейнер во flexbox и не облажаться.

overflow-flex-grid-hack

Столкнулись с проблемой: блок со скролом распепячивает flex. Давайте разбираться.

4 месяца назад показалось, что хак найден, о чём мы поспешили рассказать в твиттере, но потом стало ясно что таки поспешили.

Помотрели в спеку и mdn, но ключей к решению не нашли.

MDN: In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

После экспериментов (демки ниже) стало понятно что приводит к растяжению ширины scroll-контейнера: родительские flex-контейнеры без заданной через width ширины, см. сниппет 1.4. Ширина-то необходима как следует из статьи с MDN.

Но очевидно, задание width элементу flex-контейнера ломает flex-поведение, см. сниппеты 1.6. и 2.2.

А коли во flex мы не имеем права задавать width, то и scroll справедливо не работает.


Слава Гридам, был найден ХАК: Если обернуть scroll в грид из одного элемента, то задавать ширину или white-space, как указано в документации не трубуется, см. сниппет 0.0.

Демки в порядке дебага

0. Хак

  1. 🧡 Grid hack

1. Попытка сломать простой работающий скрол внутри ширины в %

  1. ❎ Just overflow
  2. ❎ Just overflow in flex wrap
  3. ❎ Just overflow with single scrollable
  4. ссылка сломалась 👹 Minimal reproducing: after extra flex added!
  5. ссылка сломалась Fixed: .flex-wrap.inner { width: 100%; }
  6. ссылка сломалась But it's broken at all

2. Попытка починить сломанное решение из проекта

  1. ссылка сломалась 🚩 Reproducing (copied from project)
  2. ссылка сломалась ✴️ Removing div.scroll-wrap fixes it! But width still overflows
  3. 🧡 With Grid hack

Ответы на вопросы

Почему просто не заворачивать всё в гриды

В динамических SPA компонентах содержимое может произвольным образом меняться, часто нельзя задавать в css жёсткую структуры. Хотя гриды и обладают гибкостью к содержимому контейнера (например, можно описать колонки для произвольного количества «строк»), часто это или излишне или всё же недостаточно гибко и требует дублировать знание о структуре динамического контента в css.

Где это нужно

Мы эту проблему решили для скролящихся вкладок внутри 2-х вложенных flex-контейнеров составной шапки. Эта шапка состоит из родительского React-компонента, описывающего компоновку (layout) и встроенного фрагмента, специфичного для этого типа страниц.

Зачем в демках два вложенных флекса

Например .scroll-wrap-2 это прекрасный пример хака «scrollbar-hider»: прячущего скролбар внизу для любой платформы. В других демках вложенные флексы демонструруют реальную структуры вёрстки боевого проекта состоящего из встроенных из вне компонент.

Продолжение

В следующей статье расскажем про хак с display: grid и position: sticky в главных ролях.

Благодарности 😻

Эти результаты не стали бы реальностью без классных ребят из моей команды:

Спасибо Артёму @tetris0k и Жоре @boozingeorge

@a-x-
Copy link
Author

a-x- commented Mar 17, 2018

UPD
@SelenIT2 предложил более элегантный, но тоже непонятный хак:
overflow: hidden для flex-контейнера, содержащего scroll-контейнер
http://jsbin.com/meyudafize/edit?html,css,output

Собрал 3 примера в одной демке

@OnkelTem
Copy link

OnkelTem commented Dec 16, 2020

А как насчет вертикального layout?
Я уже несколько часов бьюсь с flex-ом, пытаясь позволить внутреннему элементу скроллиться, не ломая при этом весь layout, встраивая бесполезные overflow: auto, без которых, однако, ничего не работает.

Вот то, о чем я говорю: https://codepen.io/onkeltem/pen/MWjmJzo

Нужно чтобы скролился контейнер с чиселками 2222.
И чтобы это случилось, нужно ставить overflow: auto; на каждом контейнере типа flex-direction: column;, кроме первого, у которого родитель с flex-direction: row; — у него можно не ставить, это ничего не поломает, но лень писать исключение.
Разорвать этот порочный круг у меня не получилось.
Grid-хак не пробовал, сейчас как раз собираюсь и заранее благодарю.
P.S. О как же я обожаю тратить дни на это дерьмо.

UPDATE. Нет, либо я неправильно использую это грид, либо тут он не помощник:
https://codepen.io/onkeltem/pen/vYXmxRL

Как видим, скролл висит не там где надо.

@cyberspace-dev
Copy link

cyberspace-dev commented Aug 25, 2021

<div style="flex: 1;position: relative"><div style="position: absolute;width: 100%;height: 100%;overflow:scroll></div></div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment