От автора: в CSS мы можем контролировать ситуацию, когда содержимое элемента слишком велико, чтобы уместиться в контейнер. Свойство для этого – overflow, это сокращение от свойств overflow-x и overflow-y. В этой статье я познакомлю вас с этими свойствами, а затем мы вместе рассмотрим некоторые концепции и варианты использования, связанные с переполнением.
Вступление
Чтобы использовать свойство overflow, мы должны быть уверены, что элемент, к которому мы его применяем, соответствует следующему:
Это элемент уровня блока (например: div, section) с заданной высотой через height или max-height. Под заданной высотой я подразумеваю, что элемент должен иметь содержимое (не пустой), чтобы не указывать высоту явно.
Или элемент с установленным для white-space значением nowrap.
Возможные значения
Свойство overflow может принимать следующие возможные значения: visible, hidden, scroll, auto.
.element { height: 200px; overflow: [overflow-x] [overflow-y]; }
Поскольку overflow — это сокращенное свойство, оно может принимать одно или два значения. Первое значение для горизонтальной оси, а второе для вертикальной.
visible
Значение по умолчанию, при котором содержимое может выходить за пределы родительского элемента. Это может быть установлено как:
.element { height: 200px; overflow: visible; }
Интересный факт, который вы должны знать, это то, что когда для одной оси установлено visible, а для другой — auto, для оси с visible вычисляется ключевое слово auto.
Согласно Mozilla Developer Network MDN: Установка для одной оси visible (по умолчанию), а для другой – auto, приводит к тому, что visible ведет себя как auto.
Например, если мы установим для элемента следующее:
.element { height: 200px; overflow: visible auto; }
Значение свойства overflow будет вычислено, как auto auto.
hidden
Когда содержимое длиннее, чем его родитель, оно будет обрезано. Тем не менее, содержимое можно прокручивать с помощью Javascript.
scroll
Значение scroll позволяет добавлять прокрутку, чтобы показать обрезанное содержимое, и она может быть горизонтальной или вертикальной.
На рисунке выше полоса прокрутки всегда видна, независимо от того, длинное ли содержимое или нет. Обратите внимание, что это зависит от операционной системы.
auto
Я считаю это умным ключевым словом! Оно добавляет полосу прокрутки, только если содержимое длиннее контейнера.
Обратите внимание, что на рисунке полоса прокрутки видна только в том случае, когда содержимое длиннее контейнера. Далее мы пройдемся по свойствам, которые относятся к overflow.
Overflow-X
Это отвечает за ось X или горизонтальные стороны элемента.
Overflow-Y
Это отвечает за ось Y или вертикальные стороны элемента.
Примеры использования
Простой слайдер
Мы можем быстро создать простой слайдер, обрезая содержимое по горизонтали и позволяя ему прокручиваться.
В макете выше у нас есть карточки, которые уложены горизонтально, и есть полоса прокрутки, которая позволяет нам прокручивать и раскрывать больше контента. Чтобы реализовать это, нам нужно сделать следующее:
Вывести карточки в одну строку. Я буду использовать для этого flexbox.
Добавить для контейнера overflow-x.
.wrapper { display: flex; overflow-x: auto; }
И это работает в настольных браузерах. Однако при тестировании этого в Safari для iOS (12.4.1) прокрутка не работала. После некоторых проб и ошибок прокрутка все же заработала, когда я добавил дочерним элементам ширину. Работает без проблем в iOS (13.3).
Модальный контент
Когда модальное содержимое слишком длинное, мы можем легко сделать область прокручиваемой. Для этого у нас должно быть следующее:
Максимальная высота для модала.
Тело модала должно занимать все доступное пространство.
.modal { display: flex; flex-direction: column; max-height: 400px; max-width: 450px; } /* 1. Задаем, чтобы тело модала занимала все доступное пространство */ /* 2. Добавляем полосу прокрутки, если содержимое слишком длинное. Я использовал auto, потому что не хочу, чтобы полоса прокрутки добавлялась, пока содержимое не является достаточно длинным. */ .modal__content { flex-grow: 1; /* [1] */ overflow-y: auto; /* [1] */ }
Карточка с закругленными углами
Когда у нас есть карточка, и мы хотим, чтобы ее углы были закруглены, мы часто добавляем border-radius для верхнего и нижнего углов, как показано ниже:
.card-image { border-top-right-radius: 7px; border-top-left-radius: 7px; } .card-content { border-bottom-right-radius: 7px; border-bottom-left-radius: 7px; }
Для этого может потребоваться много работы, особенно если карточка имеет другой дизайн на мобильном телефоне. Например, вместо того, чтобы размещать дочерние элементы один над другим, они будут располагаться рядом друг с другом. Для этого случая полезно использовать для контейнера overflow: hidden, а затем добавить border-radius:
.card { overflow: hidden; border-radius: 7px; }
Тем не менее, это решение имеет некоторые оговорки, чтобы оно идеально подходило для всех случаев. Пожалуйста, не забудьте все протестировать.
Усечение текста
Для длинного контента мы можем обрезать текст с помощью свойства text-overflow.
Для элемента, который мы хотим усечь, я добавил следующее:
.user__name { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
Это все! Обратите внимание, чтобы это работало, важно использовать overflow: hidden.
Анимация
Когда дело доходит до анимации, преимущество overflow: hidden заключается в обрезании скрытых элементов, которые можно показывать при наведении курсора. Посмотрите на рисунок ниже:
В CSS это будет выглядеть так:
.button.slide-left { overflow: hidden; } .button.slide-left:after { content: ""; position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #000; opacity: 0.25; border-radius: 100px; transform: translateX(-100%); transition: 0.2s ease-in; }
У нас есть две кнопки, и у каждой есть псевдо-элемент, который переводится влево и вниз, соответственно.
Общие проблемы, связанные с переполнением
Прокрутка на мобильном устройстве
Например, когда у нас есть слайдер, недостаточно добавить overflow-x и тем ограничиться. В Chrome iOS нам нужно продолжать прокручивать и перемещать контент вручную. К счастью, есть свойство, которое может улучшить процесс прокрутки.
.wrapper { overflow-x: auto; -webkit-overflow-scrolling: touch; }
Это называется прокруткой на основе импульса. Согласно MDN: …содержимое продолжает прокручиваться некоторое время после завершения жеста прокрутки и удаления пальца с сенсорного экрана.
Встроенные блочные элементы
Согласно спецификации CSS: Базовая линия ‘inline-block’ является базовой линией его последнего блока строки в нормальном потоке, если у него нет либо линейных блоков в потоке, либо если его свойство ‘overflow’ не имеет вычисленного значения, отличного от ‘visible’, в этом случае базовая линия — это край нижнего блока.
Когда inline-block элемент имеет значение overflow, отличное от visible, это приведет к выравниванию нижнего края элемента на основе текстовой базовой линии его соседних элементов. Рассмотрим следующий пример.
Чтобы решить эту проблему, нам нужно изменить выравнивание кнопки, которая имеет overflow: hidden.
.button { vertical-align: top; }
Проблемы горизонтальной прокрутки
Часто мы сталкиваемся с проблемой горизонтальной прокрутки, когда причина нам неизвестна. В этом разделе я перечислю некоторые распространенные причины появления горизонтальной прокрутки, чтобы вы могли учесть их при создании макетов.
Элементы с абсолютным / фиксированным позиционированием
Когда есть элемент, который имеет значение свойства position absolute или fixed, существует возможность, что для него будет добавлена горизонтальная прокрутка. Это может произойти, когда одно из значений left или right позиционирует элемент снаружи элемента тела.
Чтобы решить эту проблему, вам необходимо проверить, почему этот элемент расположен вне области просмотра. Если в этом нет необходимости, его нужно удалить или отредактировать значение позиции.
Элементы сетки
Сетка CSS имеет три случая, которые могут привести к горизонтальной прокрутке. Давайте рассмотрим их.
Использование значений в пикселея для столбцов
При использовании значений в пикселях мы можем столкнуться с проблемами, когда ширина области просмотра мала. Смотри пример ниже:
.wrapper { display: grid; grid-template-columns: 200px 1fr; grid-gap: 1rem; }
Решение состоит в том, чтобы сбросить столбцы и использовать только тот, который указан выше, в области просмотра, где достаточно места.
.wrapper { display: grid; grid-template-columns: 1fr; grid-gap: 1rem; } @media (min-width: 400px) { grid-template-columns: 200px 1fr; }
Использование Minmax()
.wrapper { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); grid-gap: 1rem; }
Может быть заманчиво забыть о тестировании для мобильных устройств, но это приведет к появлению горизонтальной прокрутки в некоторой точке, поскольку минимальная ширина равна 300px.
Простое исправление для того — сбросить grid-template-columns на 1fr и изменить его, когда окно просмотра больше.
.wrapper { display: grid; grid-template-columns: 1fr; grid-gap: 1rem; } @media (min-width: 400px) { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
Использование процентов вместо fr
Согласно этому твиту Джейка Арчибальда, если мы использовали процент для столбцов сетки, а затем добавили grid-gap, это приведет к появлению горизонтальной прокрутки. Причина в том, что значение grid-gap добавляется к ширине контейнера.
.wrapper { display: grid; grid-template-columns: repeat(4, 25%); grid-gap: 10px; }
Чтобы исправить это, избегайте использования процентов для столбцов сетки и используйте вместо этого 1fr. При использовании grid-gap будет вычитаться из доступного пространства.
flex-wrap
Для flex-элементов важно добавлять для контейнера flex-wrap, иначе они могут стать беспорядочными на небольших областях просмотра.
.wrapper { display: flex; }
Кода выше недостаточно. Обязательно добавьте flex-wrap, чтобы избежать неожиданных переполнений.
.wrapper { display: flex; flex-wrap: wrap; }
Длинные слова или ссылки
Когда речь идет о длинных словах или ссылках, размещенных внутри контента, они должны переноситься на новую строку или иначе, как вы уже догадались, появится горизонтальная прокрутка!
Чтобы это исправить, нам нужно разбить длинные слова и ссылки. Вот как мы можем это сделать:
.post-content a { word-wrap: break-word; }
Или мы можем использовать text-overflow:
.post-content a { overflow: hidden; text-overflow: ellipsis; }
Изображения без max-width: 100%
Если вы не используете сброс CSS, то можете случайно забыть использовать max-width: 100% для всех img, так как это сделает их адаптивными на мобильных устройствах. Если нет, возникнут проблемы.
Использование фиксированной ширины
Фиксированная ширина может вызвать проблемы при использовании, и, как правило, я стараюсь избегать этого, когда возможно. Если это действительно необходимо, то лучше использовать max-width, потому что, если для значения width места недостаточно, с max-width все будет работать.
.element { width: 800px; }
Добавление max-width позволит избежать появления горизонтальной прокрутки.
.element { width: 800px; max-width: 100%; }
Как исправить проблемы с горизонтальной прокруткой
Теперь, когда мы знаем причины появления горизонтальной прокрутки, я объясню некоторые способы, которые могут помочь нам определить эти проблемы и решить их.
Используйте CSS outline
Это первое, что я обычно делаю для отладки.
*, *:before, *:after { outline: solid 1px #000; }
Добавляя это, мы можем заметить, какие элементы имеют большую ширину. Адди Османи развил это с помощью своего простого скрипта:
[].forEach.call(document.querySelectorAll("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
Этот скрипт выполняет случайное выделение цветов контура, что упрощает работу, так как все контуры не будут одного цвета.
Метка Firefox scroll
В Firefox есть небольшая метка, добавляемая к элементам, которые вызывают горизонтальную прокрутку. Разве это не круто?
Удаление элементов
Иногда описанные выше методы не работают. В этом случае я открываю инструменты разработчика, а затем начинаю удалять элементы и смотрю, что происходит. Как только горизонтальная прокрутка исчезла, я могу определить элемент, который вызывает проблему.
Пожалуйста, прибегайте к помощи overflow-x: hidden в последнюю очередь
Наконец, вы можете использовать overflow-x: hidden для решения проблемы горизонтальной прокрутки, но, пожалуйста, пусть это будет ваш последний вариант.
Автор: Ahmad Shadeed
Источник: https://ishadeed.com
Редакция: Команда webformyself.