Все об auto в CSS
В CSS у нас есть значение auto
, которое можно использовать для таких свойств, как поля, расположение, высота, ширина и многое другое. Я чувствовал, что мне нужно место, чтобы документировать все, что я о них знаю, чтобы он мог быть ориентиром для всех, кто заинтересован в этом auto
.
В этой статье я объясню технические детали того, как auto
в первую очередь работает, и как мы можем максимально использовать его. Конечно, будут некоторые варианты использования и примеры.
Вступление
Использование ключевого слова auto
варьируется от свойства к другому. В этой статье я объясню значение в контексте каждого свойства.
Width: Auto
Начальная ширина элементов уровня блока, такая как div
или p
есть auto
, заставляет их занимать все горизонтальное пространство содержащего их блока.
Согласно спецификации CSS:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = ширина содержащего блока
Когда элемент имеет значение auto
для ширины, он может иметь поля, отступы и границы, не становясь больше, чем его родительский элемент. Ширина его поля содержимого будет самим содержимым с вычитанием полей, отступов и границ.
Давайте рассмотрим приведенный выше макет в качестве примера в действии.
<div class="wrapper">
<div class="item"></div>
</div>
* {
box-sizing: border-box;
}
.wrapper {
max-width: 600px;
margin: 2rem auto 0;
padding: 1rem;
}
.item {
padding: 1rem;
margin: 0 50px;
border: 15px solid #1f2e17;
}
Все в порядке. Элемент ограничен в пределах своего родителя.
Однако что произойдет, если мы изменим ширину элемента 100%
вместо auto
? Элемент получит 100%
своего родителя, а также поля слева и справа.
.item {
width: 100%;
padding: 1rem;
margin: 0 50px;
border: 15px solid #1f2e17;
}
Ширина элемента составляет 568px
, что является суммой следующих параметров::
'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' = ширина элемента 15 + 16 + 506 + 16 + 15 = 506 пикселей
Если направление будет ltr
, оно будет полностью проигнорировано margin-right
. В нашем случае это происходит. Однако если макет есть rtl
, то margin-left
будет игнорироваться.
Примеры использования для Width: Auto
Объяснения основ недостаточно для понимания концепции, поэтому я провел исследование, чтобы выделить некоторые практические примеры использования width: auto
.
Различная ширина между мобильным и настольным компьютером
У нас есть группа кнопок. На мобильном устройстве мы хотим, чтобы они находились рядом друг с другом (каждая оболочка кнопки берет 50%
своего родителя), а на рабочем столе каждый должен занимать всю ширину своего родителя. Как это сделать?
<div class="group">
<div class="group__item">
<button class="c-button">Sign In</button>
</div>
<div class="group__item">
<button class="c-button c-button--ghost">Register</button>
</div>
</div>
Я использовал flexbox, чтобы кнопки появлялись рядом друг с другом.
.group {
display: flex;
}
.group__item {
width: 50%;
}
А на рабочем столе мне нужно, чтобы каждый из них занимал всю ширину. В этом случае у вас может возникнуть соблазн использовать width: 100%
, верно? Есть лучшее решение.
@media (min-width: 800px) {
/* Revert the wrapper to a block element instead of flex */
.group {
display: block;
}
.group__item {
width: auto;
}
}
Поскольку .group__item
это блочный элемент, использование width: auto
заставляет его красиво заполнить доступное пространство его родителя.
Height: Auto
Когда речь заходит о height
, все происходит по-другому.. Высота элемента равна его содержанию, где значение по умолчанию auto
.
Рассмотрим следующий пример.
<div class="wrapper">
<div class="item">What's my height?</div>
</div>
Чтобы .item
мог взять всю высоту своего контейнера, мы можем использовать один из следующих вариантов:
- Дайте
.wrapper
фиксированную высоту, а затем добавьтеheight: 100%
для элемента.item
. - Используйте flexbox для
.wrapper
и он растянет дочерний элемент.item
по умолчанию.
.wrapper {
height: 200px;
}
.item {
height: 100%;
}
Поля и ключевое слово Auto
Для полей, наиболее распространенный вариант использования для центрирования элементов с известной шириной по горизонтали.
Рассмотрим следующий пример:
Синий прямоугольник должен быть центрирован по горизонтали. Для этого следует использовать следующее:
.element {
margin-left: auto;
margin-right: auto;
}
Согласно спецификации CSS:
Если 'margin-left' и 'margin-right' равны 'auto', их используемые значения равны. Это горизонтально центрирует элемент относительно краев содержащего блока.
Поле auto с абсолютно позиционированными элементами
Другим менее распространенным вариантом использования для центрирования абсолютно позиционированного элемента является margin: auto
. Когда у нас есть элемент, который должен быть центрирован по горизонтали и вертикали внутри его родителя, у нас может возникнуть соблазн использовать translateX
или translateY
.
Для работы описанной выше техники нам необходимо следующее:
- Ширина и высота должны быть установлены.
- Элемент должен иметь
position: absolute
<div class="wrapper">
<div class="item">I am centered.</div>
</div>
.wrapper {
position: relative;
}
.item {
width: 200px;
height: 100px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
Flexbox
Использование автоматических полей с flexbox может быть очень полезным в некоторых случаях. Когда дочерний элемент имеет поле auto
, он будет перемещен далеко на противоположную сторону. Например, если гибкий элемент имеет margin-left: auto
, он будет сдвинут в крайнее правое положение.
Рассмотрим следующий макет. У нас есть две коробки, учитывая, что родительский элемент является гибким контейнером.
Мы хотим, чтобы пункт № 2 был перенесен в крайнее правое положение. Автоматические поля идеально подходят для этого.
.wrapper {
display: flex;
}
.item-2 {
margin-left: auto;
}
Не только это, но он также может работать в горизонтальном или вертикальном направлении. Смотрите следующий пример:
.item-2 {
margin-top: auto;
}
Также, если у нас есть только один дочерний элемент, мы можем использовать margin: auto
для его для центрирования по горизонтали и вертикали.
.item-1 {
margin: auto;
}
Свойство Flex и ключевое слово auto
В flexbox мы можем использовать flex: auto
для дочернего элемента. Что это значит? Хорошо, позвольте мне объяснить это. Если дочерний элемент имеет flex: auto
, это эквивалентно flex: 1 1 auto
, что означает следующее:
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
}
По данным Mozilla Developer Network (MDN) :
Размер изделия определяется в соответствии с его свойствами ширины и высоты, но увеличивается, чтобы поглотить любое дополнительное свободное пространство в гибком контейнере, и сжимается до минимального размера, чтобы соответствовать контейнеру. Это эквивалентно установке «flex: 1 1 auto».
Размер элемента flex: auto
будет определяться в зависимости от его ширины и высоты, но он может увеличиваться или уменьшаться в зависимости от доступного дополнительного пространства. Я не знал об этом до того, как начал работать над этой статьей!
<div class="wrapper">
<div class="item item-1">Item</div>
<div class="item">Item</div>
<div class="item">Item</div>
</div>
.wrapper {
display: flex;
flex-wrap: wrap;
}
.item {
width: 120px;
height: 500px;
}
.item-1 {
flex: auto;
}
CSS Grid и автоматическая настройка столбца
В CSS Grid мы можем установить столбец на auto
, что означает, что его ширина будет основываться на длине его содержимого. Смотрите ниже, чтобы понять, что я имею в виду:
.wrapper {
display: grid;
grid-template-columns: auto 1fr 1fr;
}
Grid и поле auto
При использовании CSS-сетки для достижения результатов, аналогичных flexbox, можно использовать автоматические поля. Когда у нас есть сетка, а из элементов сетки есть margin-left: auto
, оно будет отодвинуто вправо и его ширина будет зависеть от длины его содержимого.
Рассмотрим следующий пример.
Мы хотим, чтобы ширина элемента №1 основывалась на его содержимом, а не на области сетки. Используя margin-left: auto
, мы можем достичь следующего:
.item-1 {
margin-left: auto;
}
Макеты слева направо
Стоит отметить, что использование margin-left: auto
или margin-right: auto
может отлично работать для макетов слева направо, таких как английский. Тем не менее, будьте осторожны, чтобы изменить эти значения при работе на многоязычном веб-сайте. Более того, я бы порекомендовал использовать свойства flexbox или grid, если с ними можно выполнить работу. Если нет, тогда используйте auto margins как последнее средство и используйте логические свойства CSS .
Свойство overflow
Когда у нас есть элемент, мы должны думать о минимальном и максимальном содержании, которое он должен принимать. Если содержание превысило максимум, то нам нужно показать полосу прокрутки.
У вас может возникнуть соблазн использовать следующее:
.element {
overflow-y: scroll;
}
Однако это может показать полосу прокрутки, даже если высота содержимого мала. Смотрите пример ниже:
В Chrome Windows полоса прокрутки всегда отображается. Это неправильное и запутанное поведение.
Используя ключевое слово auto
вместо этого, мы можем гарантировать, что полоса прокрутки не будет отображаться, если высота содержимого не превышает его контейнер.
Согласно MDN :
Зависит от агента пользователя. Если содержимое помещается в поле заполнения, оно выглядит так же, как и видимое, но все равно создает новый контекст форматирования блока. Настольные браузеры предоставляют полосы прокрутки, если содержимое переполняется.
.element {
overflow-y: auto;
}
Свойства позиционирования
Для свойств позиционирования CSS top
, right
, bottom
и left
мы можем использовать ключевое слово auto
в качестве значения для них. Следующая вещь, которую я собираюсь объяснить, является новой для меня, и я узнал об этом во время исследования для этой статьи.
Рассмотрим следующий макет:
У нас есть обертка с отступом, и есть дочерний элемент. Дочерний элемент абсолютно позиционирован и все еще не имеет никакого свойства позиционирования.
.wrapper {
position: relative;
padding: 16px;
}
.item {
position: absolute;
width: 100px;
height: 100px;
}
В CSS есть начальное значение / значение по умолчанию для каждого свойства. Если я проверил дочерний элемент и перешел к вычисленным стилям, как вы оцениваете значение свойства left
?
Значением по умолчанию для left
является 16px
! Почему это случилось, даже если я не установил это? Ну, причина в том, что абсолютно позиционированный элемент находится относительно своего ближайшего родителя с position: relative
. Этот родитель имеет padding: 16px
, поэтому дочерний элемент располагается на 16 пикселей сверху и слева. Интересно, нет?
Теперь вы можете спросить, в чем выгода? Хорошо, позвольте мне двигаться дальше.
Предположим, что дочерний элемент должен быть расположен на 100px
слева на небольших размерах видового экрана, а для рабочего стола он должен вернуться обратно в положение по умолчанию.
.wrapper {
position: relative;
}
.item {
position: absolute;
left: 100px;
width: 100px;
height: 100px;
}
Как сбросить left
на больших окнах просмотра? Мы не можем использовать left: 0
, так как это приведет ребенка к краю, а это не то, что мы хотим. Смотрите ниже макет для того, что я имею в виду.
Чтобы правильно сбросить дочерний элемент, мы должны использовать left: auto
. Согласно MDN:
Элемент расположен там, где он должен располагаться горизонтально, если бы он был статическим элементом.
Это означает, что он будет соблюдать отступы и не будет прикреплять дочерний элемент к краю своего родителя.
.item {
position: absolute;
left: 100px;
width: 100px;
height: 100px;
}
@media (min-width: 800px) {
.item {
/* This is equivalent to left: 16px */
left: auto;
}
}
То же самое относится и к свойству top
. Для right
и bottom
свойств, их вычисленное значение по умолчанию равно ширине и высоте элемента соответственно.
Примеры использования и примеры
Стоит отметить, что приведенных ниже вариантов использования может быть недостаточно, но я попытался добавить некоторые из них и надеюсь, что они будут вам полезны.
Всплывающая подсказка Arrow
Для всплывающей подсказки нам нужна стрелка, чтобы сделать ее более понятной для пользователя. Если мы работаем над системой проектирования, мы должны учитывать несколько состояний. Например, всплывающая подсказка со стрелкой, указывающей влево, а другая - справа.
.tooltip:before {
/* Arrow code */
position: absolute;
left: -15px;
}
/* This is a version where the arrow is pointing to the right */
.tooltip.to-right:before {
/* Arrow code */
position: absolute;
left: auto;
right: -15px;
}
Обратите внимание, что я использовал left: auto
для переопределения left: -15px
в начальной реализации. К вашему сведению, это используется очень часто, и я бы рекомендовал вместо этого использовать следующее:
.tooltip:before {
position: absolute;
right: 100%;
}
.tooltip.to-right:before {
/* Arrow code */
position: absolute;
right: auto;
left: 100%;
}
Используя 100%
, мы избегали использования жестко закодированного значения (ширины стрелки), которое может потерпеть неудачу, если мы изменим размер стрелки. Это более перспективное решение.
Компонент Card
У вас может быть компонент карты, с действием в верхнем левом углу, он может быть только для украшения или может быть полезным действием. Независимо от того, что есть, вы должны учитывать это в обоих направлениях.
Используя left: auto
, мы можем легко сбросить базовую реализацию.
.card .icon {
position: absolute;
left: 15px;
top: 15px;
}
.card.is-right .icon {
left: auto;
right: 15px;
}
Flexbox и поле Auto
Когда дело доходит до flexbox, возможности безграничны. Комбинируя его с автоматическими полями, мы можем создавать мощные макеты.
Рассмотрим следующий пример.
У нас есть строка, которая содержит заголовок, описание и кнопку действия с правой стороны. Мы хотим, чтобы кнопка действия придерживалась правой стороны.
<div class="item">
<div class="item-group">
<!-- Title and description -->
</div>
<button class="item__action">Confirm</button>
</div>
.item {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item__action {
margin-left: auto;
}
Вот и все! При использовании margin-left: auto
действие переносится в дальний правый угол. Более того, мы можем использовать логические свойства CSS, если вы создаете многоязычный веб-сайт. CSS будет выглядеть следующим образом:
.item__action {
margin-inline-start: auto;
}
CSS Grid и Auto Margins
При добавлении полей к элементам сетки это может быть фиксированное, процентное или автоматическое значение. Меня больше интересует auto
в этой статье. Учтите следующее:
<p class="input-group">
<label for="">Full Name</label>
<input type="email" name="" id="">
</p>
.input-group {
display: grid;
grid-template-columns: 1fr;
grid-gap: 1rem;
@media (min-width: 700px) {
grid-template-columns: 0.7fr 2fr;
}
}
Я хочу выровнять метку по левому краю ввода. Для этого мне нужно применить следующее:
.input-group label {
margin-left: auto;
}
Модальный Дизайн
При работе над модальным дизайном важно учитывать, что произойдет, если высота содержимого будет большой. Для этого случая мы можем использовать следующее:
.modal-body {
overflow-y: auto;
}
Имея это, он будет показывать полосы прокрутки только в том случае, если высота содержимого достаточно велика.