Overflow в CSS
В 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
![](/static/storage/219941388615570477720148407831654126987.png)
Значение по умолчанию, при котором содержимое может выходить за пределы родительского элемента. Это может быть установлено как:
.element {
height: 200px;
overflow: visible;
}
Интересный факт, который вы должны знать, это то, что когда одна ось установлена visible
, а другая ось установлена auto
, ось с visible
вычисляет ключевое слово auto
.
По словам разработчиков сети Mozilla MDN :
Установка одной оси в положение visible (по умолчанию), а другой-в другое значение приводит к тому, что visible ведет себя как auto.
Например, если мы установим элемент со следующим:
.element {
height: 200px;
overflow: visible auto;
}
Значение свойства overflow
будет вычислено auto auto
.
Hidden
![](/static/storage/310897859498536322056462764014249458371.png)
Когда содержимое длиннее, чем его родитель, оно будет обрезано. Тем не менее, содержимое можно прокручивать с помощью Javascript.
Scroll
Значение scroll позволяет прокручивать, чтобы показать обрезанное содержимое, и оно может быть горизонтальным или вертикальным.
![](/static/storage/63829150027608252576300247068906623176.png)
На рисунке выше полоса прокрутки всегда видна, независимо от того, длинное ли содержимое или нет. Обратите внимание, что это зависит от операционной системы.
Auto
Я считаю это умным ключевым словом! Она показывает полосу прокрутки, только если содержимое длиннее своего контейнера.
![](/static/storage/79042018030760721132142673519422886121.png)
Обратите внимание, что на рисунке полоса прокрутки видна только в том случае, если содержимое длиннее контейнера. Далее мы пройдемся по свойствам, которые относятся к overflow
.
Overflow-X
Это отвечает за ось X или горизонтальные стороны элемента.
Overflow-Y
Это отвечает за ось Y или вертикальные стороны элемента.
Примеры использования и примеры
Простой слайдер
Мы можем создать быстрый и простой слайдер, обрезая содержимое по горизонтали и позволяя ему прокручиваться.
![](/static/storage/234063282483013916043464238935183896970.png)
В макете выше у нас есть карты, которые разложены горизонтально, и есть полоса прокрутки, которая позволяет нам прокручивать и раскрывать больше контента. Чтобы реализовать это, нам нужно будет сделать следующее:
- Показать карты в одной строке. Я буду использовать
flexbox
для этого. - Добавьте
overflow-x
в контейнер.
.wrapper {
display: flex;
overflow-x: auto;
}
И это работает на настольных браузерах. Однако при тестировании этого в Safari для iOS (12.4.1) прокрутка не работала. После некоторых проб и ошибок прокрутка сработала, когда я добавил ширину дочерним элементам. Работает без проблем для iOS (13.3).
Модальный контент
![](/static/storage/48049380028151182052531368949958805121.png)
Когда модальное содержимое слишком длинное, мы можем легко сделать область прокручиваемой. Для этого у нас должно быть следующее:
- Максимальная высота для modal.
- Модальное тело должно занимать все доступное пространство.
.modal {
display: flex;
flex-direction: column;
max-height: 400px;
max-width: 450px;
}
/* 1. Letting the modal body take the remaining available space */
/* 2. Allow scrolling if the content is long. I used auto because it won't show a scrollbar until the content is long enough. */
.modal__content {
flex-grow: 1; /* [1] */
overflow-y: auto; /* [1] */
}
Карта с закругленными краями
![](/static/storage/286399476418751175709450159466846202284.png)
Когда у нас есть карта, и мы хотим, чтобы ее углы были закруглены, мы склонны добавлять 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
.
![](/static/storage/307009020861160234452402297032250644503.png)
На элемент, который мы хотим усечь, я добавил следующее:
.user__name {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Вот и все! Обратите внимание, что overflow: hidden
важно, чтобы это работало.
Анимации
Когда дело доходит до анимации, выгода overflow: hidden
заключается в обрезании скрытых элементов, которые можно показывать при наведении курсора. Посмотрите на рисунок ниже:
![](/static/storage/275185836693044345422064010892724656564.png)
В 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
, это приведет к выравниванию нижнего края элемента на основе текстовой базовой линии его родных элементов.
Рассмотрим следующий пример.
![](/static/storage/143502934814299517720848957901689654243.png)
Чтобы решить эту проблему, мы должны изменить выравнивание кнопки, которая имеет overflow: hidden
.
.button {
vertical-align: top;
}
Проблемы горизонтальной прокрутки
Часто мы сталкиваемся с проблемой горизонтальной прокрутки, и становится все труднее, когда причина неизвестна. В этом разделе я перечислю некоторые распространенные причины горизонтальной прокрутки, чтобы вы могли учесть их при создании макетов.
Элементы, которые абсолютно / фиксированы
Когда есть элемент, который имеет значение позиции absolute
или fixed
, существует возможность вызвать для него горизонтальную прокрутку. Это может произойти , когда одно из значений left
, right
позиционирует элемент снаружи элемента тела.
![](/static/storage/111058981721639362251795087729243962698.png)
Чтобы решить эту проблему, вам необходимо проверить, почему этот элемент расположен вне области просмотра. Если в этом нет необходимости, его нужно удалить или отредактировать значение позиции.
Элементы Grid
Сетка CSS имеет три случая, которые могут привести к горизонтальной прокрутке. Давайте посмотрим их.
Использование значений пикселей для столбцов
![](/static/storage/39904785554868615698827322760267258118.png)
При использовании значений пикселей это приведет к проблемам, когда ширина области просмотра мала. Увидеть ниже:
.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;
}
![](/static/storage/262535613929035518468020488837394962941.png)
Использование 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));
}
Использование процентов вместо фракции
Согласно этому твиту от Джейка Арчибальда, если мы использовали процент для столбцов сетки, а затем добавили grid-gap
, это вызовет горизонтальную прокрутку. Причина в том, что значение grid-gap
добавляется к ширине контейнера.
.wrapper {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 10px;
}
Чтобы исправить это, избегайте использования процентов для столбцов сетки и используйте вместо этого 1fr
. При использовании grid-gap
будет вычитаться из доступного пространства.
Flex Wrap
Для гибких элементов важно добавить их в контейнер flex-wrap
, иначе они могут стать беспорядочными для небольших областей просмотра.
.wrapper {
display: flex;
}
Выше не достаточно. Обязательно добавьте, flex-wrap
чтобы избежать неожиданных переполнений.
.wrapper {
display: flex;
flex-wrap: wrap;
}
Длинные слова или ссылки
Когда речь идет о длинных словах или ссылках, размещенных внутри контента, он должен переходить на новую строку или иначе, как вы уже догадались! Там будет горизонтальная прокрутка.
![](/static/storage/22001294711762023146111382562216904919.png)
Чтобы это исправить, нам нужно разбить длинные слова и ссылки. Вот как мы можем это сделать:
.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 есть небольшая метка, добавленная к элементам, которые вызывают горизонтальную прокрутку. Разве это не круто?
![](/static/storage/73407571088809735766074804660910237417.png)
Удаление элементов
Иногда описанные выше методы не работают. В этом случае я открываю DevTools, а затем начинаю удалять элементы и замечаю. Как только горизонтальная прокрутка исчезла, я могу определить элемент, который вызывает проблему.
Пожалуйста, сделайте Overflow-X: Hidden своим последним решением
Наконец, вы можете использовать overflow-x: hidden
для решения проблемы горизонтальной прокрутки, но, пожалуйста, сделайте это вашим последним вариантом.