- Столкнулись с этой проблемой в середине рабочего дня. Вы устали, и у вас есть много работы, которую нужно сделать.
- Вы уже проголодались.
- Первопричину проблемы легко упустить, поскольку она не связана с компонентом, над которым вы работаете.
Учитывая всё это, давайте погрузимся в проблему.
Что должно получиться
Я дам немного контекста. Вот макет, который должен получиться. Обратите внимание, что в конце раздела main есть контейнер с прокруткой.
Определим проблему
Работая над разделом контейнера с прокруткой, я заметил горизонтальную прокрутку по всей странице, увидеть которую не ожидал.
У раздела было свойство display: flex без обёртки, поэтому контент мог оставаться в той же строке. Кроме того, чтобы разрешить прокрутку по оси x, я воспользовался overflow-x: auto.
.section { display: flex; overflow-x: auto; }
Однако эффекта не последовало. Это сбивало с толку: я был уверен, что так я делаю контейнер с прокруткой. Я открыл браузер DevTools, чтобы проверить раздел main, и заметил, что раздел очень широкий. Расширился он за счёт прокручиваемого контейнера.
Странно, правда? Когда я впервые увидел эту проблему, то задался следующими вопросами:
- Может, я забыл добавить overflow-x: hidden?
- Что-то не так с flexbox?
Я дважды перепроверил flexbox и overflow-x. Всё должно было работать так, как я ожидал. Тогда я заподозрил, что причиной проблемы может оказаться CSS-сетка (grid) для родительского элемента. Проверил подозрение, и оно подтвердилось. Макет сломался из-за grid.
Первопричиной проблемы могла быть особенность CSS (т. е. из-за какого-то контекста ожидается именно такое поведение) либо то, что свойство неверно реализовали в браузере.
Почему же появилась прокрутка?
Возможно, вы задумались, почему grid прикрепляет прокрутку к контейнеру? Смотрите: вот сетка, на которой расположены разделы main и aside.
<div class="wrapper"> <main> <section class="section"></section> </main> <aside></aside> </div>
@media (min-width: 1020px) { .wrapper { display: grid; grid-template-columns: 1fr 248px; grid-gap: 40px; } }
В свойствах main есть значение 1fr. Это означает, что main займет доступное пространство, кроме aside и отступа. Это не подлежит сомнению. Однако минимальный размер содержимого элемента сетки auto. Это означает, что элемент сетки может расширяться из-за длинного содержимого (в нашем случае из-за контейнера с прокруткой).
Как убрать лишнюю прокрутку?
Решается проблема так: нужно сообщить браузеру, что нам необходим конкретный и фиксированный минимальный размер, но не auto. Сделать это можно при помощи функции minmax().
.wrapper { display: grid; grid-template-columns: minmax(0, 1fr) 248px; grid-gap: 40px; }
Проблему мы решили. Но мы также можем решить эту проблему на уровне элемента сетки. Вот два решения, которые применимы к элементу .main:
- Установить свойство min-width: 0.
- Или overflow: hidden.
В зависимости от контекста можно воспользоваться одним из двух решений выше. Однако эти решения могут иметь кое-какие побочные эффекты, один из них связан с overflow-hidden. Представьте, что дочерний элемент раздела main имеет декоративный псевдоэлемент, который размещается вне границ main. В таком случае, если применить overflow-hidden, свойство обрежет этот псевдоэлемент.
На рисунке выше у нас два элемента, которые расположены вне main (кнопка шаринга слева и декоративная фигурка внизу справа). Учитывая это, вы должны выбрать решение, которое лучше всего подходит именно в вашем случае.
Статьи по теме
Другие профессии и курсы
ПРОФЕССИИ
КУРС
- Профессия Java-разработчик
- Профессия QA-инженер на JAVA
- Профессия Frontend-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия Разработчик игр на Unity
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРС
- Курс по JavaScript
- Курс по Machine Learning
- Курс Математика и Machine Learning для Data Science
- Курс по Data Engineering
- Курс Алгоритмы и структуры данных
- Курс Python для веб-разработки
- Курс по аналитике данных
- Курс по DevOps