Свойства Min и Max width-height в CSS

в 14:41, , рубрики: css, html, layout, верстка, Разработка веб-сайтов

Перевод «Min and Max Width/Height in CSS» Ахмада Шадида

Порой у разработчиков возникает необходимость ограничить ширину элемента относительно родителя, и в то же время, оставить её динамичной. Задав таким образом начальный размер с возможностью расширения при наличии доступного пространства. Например, нам нужна кнопка, которая должна иметь минимальную ширину. Именно в таких ситуациях удобно использовать свойства максимума и минимума.

В этой статье мы познакомимся с CSS-свойствами максимума и минимума для ширины и высоты, а также детально рассмотрим каждое из них и сценарии их использования.

Свойства ширины

Начать обсуждение хотелось бы со свойств, связанных с шириной. У нас есть min-width и max-width, и каждое из них крайне важно и полезно в определённых ситуациях

Минимальная ширина (min-width)

Своство min-width предназначено для предотвращения уменьшения ширины элемента ниже заданного значения. Значением по умолчанию является auto, которое может доходить до 0.

Чтобы продемонстрировать его, давайте рассмотрим базовый пример

Свойства Min и Max width-height в CSS - 1

Есть кнопка с текстом, размер которого может меняться от одного до нескольких слов. Чтобы быть уверенным, что эта кнопка будет иметь минимально допустимую ширину, даже если внутри будет только одно слово, нужно использовать min-width. Минимальную ширину задали равной 100px, поэтому даже если у кнопки будет очень короткое содержимое, как, например, только слово «Done» или только иконка, она всё равно будет достаточно большой, чтобы оставаться заметной. Это особенно важно, когда вы работаете с сайтами, переведёнными на разные языки

Рассмотрим пример с арабским языком в Twitter:

Свойства Min и Max width-height в CSS - 2

В примере выше кнопка содержит слово “تم”, что на арабском значит «Готово». Из-за короткого содержимого ширина и самой кнопки стала слишком мала, поэтому я обозначил минимум, задав ей свойство min-width, что можно увидеть на изображении справа (в секции «After»).

Минимальная ширина и Padding

Хотя свойство min-width и допускает увеличение ширины кнопки при увеличении размера её содержимого, по бокам всё же следует задавать padding, чтобы гарантировать внутренний отступ от её границ. Разница приведена на рисунке ниже

Свойства Min и Max width-height в CSS - 3

Максимальная ширина (max-width)

Свойство max-width предназначено для предотвращения увеличения ширины элемента выше заданного значения. Значение по умолчанию – none.

Распространённый и простой пример использования max-width заключается в его применении к изображениям. Рассмотрим пример ниже:

Свойства Min и Max width-height в CSS - 4

Если к изображению применить свойство max-width: 100% оно останется в границах родительского элемента, даже при том, что его изначальный размер больше. Если же изображение изначально меньше родителя, данное свойство никак на него не повлияет.

Использование min-width и max-width

Свойства Min и Max width-height в CSS - 5

Если к элементу применяются оба свойства, какое из них переопределит значение другого? Другими словами, у какого свойства приоритет выше?

Если значение min-width больше, чем max-width, оно будет принято за ширину элемента. Рассмотрим следующий пример:

HTML

<div class="wrapper">
  <div class="sub"></div>
</div>

CSS

.sub {
  width: 100px;
  min-width: 50%;
  max-width: 100%;
}

Свойства Min и Max width-height в CSS - 6

Исходное значение width равно 100px и в дополнение к этому заданы значения свойств min-width и max-width. В результате ширина данного элемента не будет превышать 50% ширины родительского блока

Свойства высоты

В дополнение к свойствам минимальной и максимальной ширины, есть такие же свойства для высоты

Минимальная высота (min-height)

Свойство min-height предназначено для предотвращения уменьшения высоты элемента ниже заданного значения. Значением по умолчанию является auto, которое может доходить до 0.

Чтобы продемонстрировать его, давайте рассмотрим простой пример.

У нас есть секция с текстовым содержимым. Необходимо, чтобы она смотрелась красиво как с большим, так и с малым количеством текста

Свойства Min и Max width-height в CSS - 7

CSS

.sub {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  min-height: 100px;
  color: #fff;
  background: #3c78dB;
}

Минимальная высота задана 100px, а содержимое центрировано с помощью flexbox по горизонтали и вертикали. Что произойдёт, если содержимого станет больше? Например, будет целый абзац

Свойства Min и Max width-height в CSS - 8

Да, вы уже догадались. Высота секции увеличится, чтобы вместить больше содержимого. С помощью этого мы может создавать гибкие компоненты, реагирующие на количество содержимого

Максимальная высота (max-height)

Свойство max-height предназначено для предотвращения увеличения высоты элемента больше заданного значения. Значением по умолчанию является none.

На следующем примере я задал max-height для содержимого. Но так как оно больше указанной области, происходит переполнение и текст выходит за границы родительского элемента

Свойства Min и Max width-height в CSS - 9

Примеры использования свойств

Рассмотрим некоторые распространённые и редкие сценарии использования свойств min-width, min-height, max-width, и max-height

Список тегов

В списке тегов рекомендуется указывать минимальную ширину каждого тега, чтобы не страдал их внешний вид в случае короткого содержимого.

Свойства Min и Max width-height в CSS - 10

Обладая такой гибкостью, тег будет хорошо выглядеть независимо от того, насколько коротким является его содержимое. Но что случится, если автор задал очень большое имя тега, а используемая им CMS (content management system) не имеет ограничений по количеству символов в теге? В этой ситуации также можно использовать max-width

CSS

.c-tag {
  display: inline-block;
  min-width: 100px;
  max-width: 250px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  /*Other styles*/
}

С помощью max-width можно ограничить максимальную ширину определённым значением. Однако, недостаточно применения только этого свойства. Содержимое, превышающее максимальную ширину, должно быть усечено.

https://codepen.io/shadeed/pen/320e42b7ad75c438a9e633417d737d16

Кнопки

Существуют разные сценарии использования свойств минимума и максимума для кнопок, поскольку и самих вариантов компонентов кнопок также немало. Рассмотрим следующий макет:

Свойства Min и Max width-height в CSS - 11

Обратите внимание, что ширина кнопки «Get» слишком мала. Если по какой-то причине у кнопки еще и не будет текста (а только иконка), всё может стать еще хуже. В этом случае установка минимальной ширины очень важна

Обнуление минимальной ширины для Flexbox

Значение по умолчанию у свойства min-width равняется auto, что вычисляется как ноль. Когда элемент является flex-элементом, значение min-width не становится нулём. Минимальный размер flex-элемента равняется размеру его содержимого.

Согласно CSSWG:
По умолчанию, flex-элементы не становятся меньше минимального размера, необходимого их содержимому (длина самого длинного слова или элемента с фиксированным размером). Чтобы изменить это, задайте свойство min-width или min-height.

Рассмотрим следующий пример

Свойства Min и Max width-height в CSS - 12

Имя пользователя содержит очень длинное слово, которое вызывает переполнение и горизонтальную прокрутку. Хотя я и добавил представленный ниже CSS для усечения содержимого:

CSS

.c-person__name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Поскольку заголовок является флекс-элементом, решение состоит в том, чтобы сбросить значение min-width и заставить его стать нулём

CSS

.c-person__name {
  /*Other styles*/
  min-width: 0;
}

Вот как это должно выглядеть после исправления:
Свойства Min и Max width-height в CSS - 13

Из описания в CSSWG следует, что установка свойства overflow в значение, отличное от visible, может привести к тому, что значение min-width будет вычислено как ноль, что также решает нашу проблему без необходимости явно задавать min-width: 0.

Обнуление минимальной высоты для Flexbox

Хотя это менее распространённая проблема по сравнению с min-width, она всё же может встретиться. Проблема связана с flex-элементами, которые не могут быть короче своего содержимого. В результате значение min-height устанавливается равным размеру контента.

Рассмотрим следующий пример:
Свойства Min и Max width-height в CSS - 14

Текст, окрашенный в красный цвет, должен быть обрезан границами контейнера. Но поскольку данный элемент является flex-элементом, его min-height равняется высоте содержимого. Чтобы предотвратить это, мы должны сбросить значение минимальной высоты. Давайте посмотрим на HTML и CSS код:

HTML

<div class="c-panel">
  <h2 class="c-panel__title"><!-- Title --></h2>
  <div class="c-panel__body">
    <div class="c-panel__content"><!-- Content --></div>
  </div>
</div>

CSS

.c-panel {
  display: flex;
  flex-direction: column;
  height: 180px;
}
 
.c-panel__body {
  min-height: 0;
}
 
.c-panel__content {
  overflow-y: scroll;
  height: 100%;
}

Добавление элементу min-height: 0 сбросит значение свойства и оно начнёт работать так, как ожидается
Демо

Свойства Min и Max width-height в CSS - 15

Одновременное использование min-width и max-width

Порой бывают ситуации, когда у нас есть элемент с минимальной шириной, но в то же время, максимальная ширина не задана. Это может привести к тому, что элемент станет слишком широким, хотя такое поведение не задумывалось. Рассмотрим следующий пример:

Свойства Min и Max width-height в CSS - 16

Поскольку ширина определена в пикселях, нет уверенности, что описанное выше будет работать для мобильных. Чтобы решить эту проблему, мы можем использовать проценты вместо пикселей для свойств минимума и максимума. Рассмотрим пример ниже:

Я добавил следующий CSS-код для изображений:

CSS

img {
  min-width: 35%;
  max-width: 70%;
}

Свойства Min и Max width-height в CSS - 17

Контейнер для страницы

Один из наиболее полезных сценариев применения свойства max-width – для обёртки (или контейнера) страницы. Задав странице максимальную ширину, мы можем быть уверены, что пользователям будет удобно просматривать и читать содержимое

Свойства Min и Max width-height в CSS - 18

Ниже приведён пример центрированной обёртки, имеющей padding слева и справа

CSS

.wrapper {
  max-width: 1170px;
  padding-left: 16px;
  padding-right: 16px;
  margin-left: auto;
  margin-right: auto;
}

Максимальная ширина и единица измерения «ch»

Свойства Min и Max width-height в CSS - 19

Единица измерения ch равняется ширине символа 0 (ноль), используемого в шрифте текущего элемента. Используя её в свойстве max-width, мы можем регулировать количество символов в строке. Согласно этой статье с сайта Smashing Magazine, рекомендованная длина строки от 45 до 75 символов.

В предыдущем примере с элементом-обёрткой, мы могли извлечь пользу от использования этого символа, поскольку это элемент статьи

CSS

.wrapper {
  max-width: 70ch;
  /* Other styles */
}

Анимирование элемента с неизвестной высотой

Порой мы сталкиваемся с проблемой анимирования аккордеона или мобильного меню с неизвестной высотой содержимого. В этом случае применение max-height может быть хорошим решением.

Рассмотрим следующий пример:

Свойства Min и Max width-height в CSS - 20

Когда нажимается кнопка меню, само меню должно плавно появляться сверху вниз. Сделать это без JavaScript невозможно, если только у элемента не задана фиксированная высота (а это делать не рекомендуется). Тем не менее, это возможно с помощью max-height. Идея заключается в добавлении элементу очень большой высоты, например, max-height: 20rem, которая, не будет достигнута, после чего мы можем задать шаги анимации от max-height: 0, до max-height: 20rem

CSS

.c-nav {
  max-height: 0;
  overflow: hidden;
  transition: 0.3s linear;
}
 
.c-nav.is-active {
  max-height: 22rem;
}

Нажмите на гамбургера, чтобы увидеть анимацию в действии

Минимальная высота для верхней секции (hero)

Как видите, я не люблю задавать элементам фиксированную высоту. Я чувствую, что поступая так, иду против концепции, согласно которой компоненты в вебе должны быть гибкими. Добавление минимальной высоты для первой секции сайта (секция «hero») полезно в ситуациях, когда добавляется очень большое содержимое (такое бывает).

Рассмотрим следующий пример, где у нас есть секция «hero» с фиксировано заданной высотой. Вроде смотрится хорошо.

Свойства Min и Max width-height в CSS - 21

Однако, когда содержимое увеличивается, оно переполняет контейнер и выходит за рамки обёртки секции. Это плохо.

Свойства Min и Max width-height в CSS - 22

Чтобы заранее избежать этой проблемы, мы можем вместо height добавить min-height. Мы поступаем именно так, по крайней мере, для того, чтобы очистить нашу совесть. Даже при том, что это может быть причиной весьма странного отображения страницы, я считаю, что подобные ситуации должны быть предотвращены в первую очередь, в системе управления контентом (CMS). После этого проблема исправлена и страница выглядит хорошо

Свойства Min и Max width-height в CSS - 23

Проблема переполнения содержимым заключается не только в том, что оно может быть больше фиксированной высоты родителя. Это может произойти в результате уменьшения размера экрана и, как следствие, увеличения высоты текстового содержимого из-за переносов

Свойства Min и Max width-height в CSS - 24

Если задавать не фиксированную высоту, а лишь ограничивать минимальную с помощью min-height, описанная выше проблема не произойдёт вовсе.

Модальное окно

Для компонента модального окна необходимо задавать и минимальную и максимальную ширину, следовательно, это будет работать на экранах любых размеров (от мобильных до десктопных). Это напоминает об интересной статье на CSS-Tricks, в которой рассказывается, что делать в этом случае.

1 способ

.c-modal__body {
  width: 600px;
  max-width: 100%;
}

2 способ

.c-modal__body {
  width: 100%;
  max-width: 600px;
}

Что касается меня, я предпочитаю второй способ, так как мне нужно только определить max-width: 600px. Модальное окно – это элемент div, поэтому у него уже ширина задана = 100% от родителя, правильно?

Рассмотрим приведённый ниже пример с модальным окном. Обратите внимание, как ширина становится равной 100% от ширины родителя, если в области просмотра недостаточно свободного места

Свойства Min и Max width-height в CSS - 25

https://codepen.io/shadeed/pen/5dcb1c4c6773cc3a97a766c327c36443

Минимальная высота и липкий footer

Когда содержимое страницы недостаточно большое, футер ожидаемо не прилипнет к нижней части. Давайте рассмотрим пример, который лучше продемонстрирует это

Свойства Min и Max width-height в CSS - 26

Обратите внимание, что футер не прилип к нижнему краю окна браузера. Это происходит из-за того, что высота содержимого меньше высоты окна браузера. После решения этой проблемы, страница должен выглядеть следующим образом:

Свойства Min и Max width-height в CSS - 27

Сначала я сделал элемент body flex-контейнером, после чего установил ему минимальную высоту 100% от области просмотра

CSS

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
 
footer {
  margin-top: auto;
}

Рекомендую ознакомиться с этой статьёй о липких футерах.
Демо

Пропорциональные размеры элемента и max-width/height

Чтобы сделать пропорциональный контейнер, который масштабируется в зависимости от размера области просмотра, однажды был представлен хак с использованием padding. Сейчас мы можем имитировать похожее поведение, комбинируя единицы измерения области просмотра и максимальную ширину/высоту.

На основе материалов статьи Miriam Suzanne, я хочу объяснить, как это работает.

Свойства Min и Max width-height в CSS - 28

У нас есть изображение с размерами 644 x 1000 пикселей. Нам нужно сделать следующее:

  • Соотношение сторон: height / width (высоту поделить на ширину)
  • Ширина контейнера: может быть фиксированной или динамической (100%)
  • Задайте height, равный 100% ширины области просмотра, умноженной на соотношение сторон
  • Задайте max-height, равный ширине контейнера, умноженной на соотношение сторон
  • Задайте max-width, равное ширине контейнера

CSS

img {
  --ratio: 664 / 1000;
  --container-width: 30em;
  display: block;
  height: calc(100vw * var(--ratio));
  max-height: calc(var(--container-width) * var(--ratio));
  width: 100%;
  max-width: var(--container-width);
}

Свойства Min и Max width-height в CSS - 29

HTML/Body с высотой 100%

Что делать, если нам нужно, чтобы элемент body занимал 100% высоты области просмотра? Это распространённый вопрос как в веб-сообществе в целом, так и на сайте StackOverflow в частности.

Сначала нужно задать height: 100% элементу html. Это будет гарантировать, что корневой элемент имеет высоту 100%. Затем добавляем min-height для элемента body. Причина, по которой используется именно min-height в том, что это свойство позволяет высоте элемента body быть динамичной, и подстраиваться, каким бы большим не было содержимое

CSS

html {
  height: 100%;
}
 
body {
  min-height: 100%;
}

Демо

Примечания

Минимальная ширина и блочные элементы

Порой мы забываем, что элемент, к которому пытаемся применить min-width, является блочным. В итоге это может сбить с толку и никак не влиять на элемент. Убедитесь, что элемент не является блочным

CSS функции сравнения

При исследовании на StackOverflow основных проблем, с которыми сталкиваются разработчики, я наткнулся на этот вопрос, в котором автор спрашивает следующее:

Реально ли сделать что-то подобное? max-width: calc(max(500px, 100% - 80px)) или может вот такое max-width: max(500px, calc(100% - 80px)))

Желаемое поведение заключается в том, чтобы удерживать ширину элемента не более 500px. Если ширина области видимости недостаточна, чтобы вместить элемент, то ширина должна быть 100% – 80px.

Что касается решения, опубликованного в ответ на вопрос, я попробовал применить его и он работает в Chrome 79 и Safari 13.0.3. Хоть это и выходит за рамки статьи, я всё же приведу здесь решение:

CSS

.yourselector {
  max-width: calc(100% - 80px);
}
 
/* Update: I changed the max-width from 500px to 580px. Thanks @fvsch */
@media screen and (max-width: 580px) {
  .yourselector {
    max-width: 500px;
  }
}

Источники и материалы для дальнейшего изучения

Автор: Зварич Рома

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js