DevGang
Авторизоваться

Все об 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 мог взять всю высоту своего контейнера, мы можем использовать один из следующих вариантов:

  1. Дайте .wrapper фиксированную высоту, а затем добавьте height: 100% для элемента .item .
  2. Используйте 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 .

Для работы описанной выше техники нам необходимо следующее:

  1. Ширина и высота должны быть установлены.
  2. Элемент должен иметь 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 toprightbottom и 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;
}

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

Источник:

#CSS
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Напиши статью и выиграй годовую подписку на Яндекс плюс или лицензию от Jet Brains

Участвовать