Изучение магии автоматических полей во гибких контекстах

внешний интерфейс CSS
Изучение магии автоматических полей во гибких контекстах

Чтобы перейти к теме этой статьи, взгляните на этот вопрос, каков самый быстрый путь к вертикальному элементу среднего уровня?

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

<div class="g-container">
    <div class="g-box"></div>
</div>
.g-container {
    display: flex;
}

.g-box {
    margin: auto;
}

надdisplay: flexзаменитьdisplay: inline-flex | grid | inline-gridэто тоже хорошо.

Демонстрация CodePen — использование автоматического поля для центрирования элементов по горизонтали и вертикали

как сделатьmargin: autoЦентрировать элемент по вертикали

Эм. На самом деле здесь возникает проблема, как сделатьmargin: autoВертикально работает?

Другими словами, традиционныеdisplay: blockпод контейнером, почемуmargin: autoМожно ли центрировать элемент по горизонтали, но не по вертикали?

Обычно мы использовали бы этот код:

div {
    width: 200px;
    height: 200px;
    margin: 0 auto;
}

Центрирует элемент по горизонтали относительно родительского элемента. Но если мы хотим центрировать элемент по вертикали относительно родительского элемента, используйтеmargin: auto 0не действует.

display: blockВнизmargin: autoПричины, по которым элемент не может быть центрирован по вертикали

Ознакомьтесь с документацией CSS по следующим причинам, вdisplay: blockВниз:

If both margin-left and margin-right are auto, their used values are equal, causing horizontal centring.

— Детали модели визуального форматирования CSS2: 10.3.3.

If margin-top, or margin-bottom are auto, their used value is 0.

CSS2 Visual formatting model details: 10.6.3

Простой перевод, вdisplay: block, еслиmargin-leftа такжеmargin-rightоба являются auto, их значения выражений равны, что приводит к центрированию элемента по горизонтали. (здесь расчетное значение равно половине доступного оставшегося места в элементе)

и еслиmargin-topа такжеmargin-bottomОба являются авто, тогда их значения равны 0, и, конечно же, это не может вызвать центрирование по вертикали.

Используйте FFC/GFC для созданияmargin: autoЦентрировать элемент по вертикали

Хорошо, здесь, чтобы использовать один элементmargin: autoЧтобы иметь возможность центрировать элемент в вертикальном направлении, элемент должен находиться в контексте FFC (контекст гибкого форматирования) или GFC (контекст форматирования сетки), который находится в следующих значениях:

{
    display: flex;
    display: inline-flex;
    display: grid;
    display: inline-grid;
}

Под ФФКmargin: autoПричины, по которым вы можете центрировать элементы по вертикали

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

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

Ознакомьтесь с документацией CSS по следующим причинам, вdispaly: flexВниз:

  • Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

CSS Flexible Box Layout Module Level 1 -- 8.1. Aligning with auto margins

Просто переведите, в том смысле, чтогибкий контекст форматирования, задаватьmargin: autoэлемент, вjustify-contentа такжеalign-selfПеред выравниванием любое свободное пространство будет выделено для автоматического поля в этом направлении.

Здесь очень важным моментом является то, что эффект margin auto не только в горизонтальном направлении, но и в вертикальном направлении для автоматического выделения этого оставшегося пространства.

Используйте автоматические поля для достижения гибкого макетаspace-between | space-around

Поймите суть приведенного выше предложения:

  • проходя черезjustify-contentа такжеalign-selfПеред выравниванием любое свободное пространство выделяется для автоматического поля в этом измерении.

После этого мы можем использовать автоматическую симуляцию полей при гибкой компоновке для достижения гибкой компоновки.space-betweenтак же какspace-around.

Автоматическая реализация маржиspace-around

Для такого гибкого макета:

<ul class="g-flex">
    <li>liA</li>
    <li>liB</li>
    <li>liC</li>
    <li>liD</li>
    <li>liE</li>
</ul>

Если его код CSS:

.g-flex {
    display: flex;
    justify-content: space-around;
}

li { ... }

Эффект следующий:

image

Тогда следующий код CSS полностью эквивалентен приведенному выше эффекту:

.g-flex {
    display: flex;
    // justify-content: space-around;
}

li { 
    margin: auto;
}

Демонстрация CodePen — маржа автоматически реализует пространство вокруг под flex

Автоматическая реализация маржиspace-between

Точно так же использование автоматических полей также легко реализовать в flex.space-between, следующие два кода CSS имеют одинаковый эффект:

.g-flex {
    display: flex;
    justify-content: space-between;
}

li {...}
.g-flex {
    display: flex;
    // justify-content: space-between;
}

li {
    margin: auto;
}

li:first-child {
    margin-left: 0;
}

li:last-child {
    margin-right: 0;
}

CodePen Demo -- margin auto реализует пробел между flex

Конечно, важно отметить, что:

Note: If free space is distributed to auto margins, the alignment properties will have no effect in that dimension because the margins will have stolen all the free space left over after flexing.

CSS Flexible Box Layout Module Level 1 -- 8.1. Aligning with auto margins

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

То есть гибкие подэлементы, которые используют автоматические поля, устанавливаются их родительскими элементами.justify-contentихalign-selfОн больше не будет действовать, то есть здесь приоритетное отношение.

Используйте автоматическую маржу для достижения минимальной гибкостиalign-self: flex-start | flex-end | center

Автоматическая маржа может осуществлять контроль в горизонтальном направлении, а также контроль в вертикальном направлении Принцип тот же.

использоватьmargin: autoАналоговый флекс подalign-self: flex-start | flex-end | center, вы можете взглянуть на следующие демонстрации:

Автоматические поля в разных направлениях

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

Будь то автоматическая маржа в нескольких направлениях или автоматическая маржа в одном направлении, это очень полезно.

Вот еще несколько интересных примеров:

использоватьmargin-left: autoРеализовать неправильный обоснованный макет

Предположим, нам нужно иметь следующий макет:

image

Структура DOM выглядит следующим образом:

<ul class="g-nav">
    <li>导航A</li>
    <li>导航B</li>
    <li>导航C</li>
    <li>导航D</li>
    <li class="g-login">登陆</li>
</ul>

Для использования последнего элементаmargin-left: auto, вы можете легко реализовать этот макет:

.g-nav {
    display: flex;
}

.g-login {
    margin-left: auto;
}

В настоящее время,autoВычисленное значение — это оставшееся пространство после того, как контейнер упорядочит все li в горизонтальном направлении.

Конечно, его не обязательно применять к первому или последнему элементу, например, этот макет — точно такая же реализация:

image

<ul class="g-nav">
    <li>导航A</li>
    <li>导航B</li>
    <li>导航C</li>
    <li>导航D</li>
    <li class="g-login">登陆</li>
    <li>注册</li>
</ul>
.g-nav {
    display: flex;
}

.g-login {
    margin-left: auto;
}

marginauto

Codepen Demo -- nav list by margin left auto

Центрирование нескольких строк по вертикали

ОК, или, у нас часто бывает такое требование, некий блок в большом сложном макете, высота или ширина не фиксированы, и его нужно центрировать относительно остального пространства, где он находится:

image

Есть 5 строк копии, и нам нужно, чтобы третья и четвертая строки были центрированы по вертикали относительно оставшегося пространства.

Здесь, если вы используете Flex Payout, простоalign-selfилиalign-itemsПохоже, быстрого решения проблемы не существует.

А с автоматическими полями нам нужно сделать это только для первого элемента, который должен быть центрирован по вертикали.margin-top: auto, выполненный на последнем элементеmargin-bottom: autoПросто посмотрите на подсказку кода:

<div class="g-container">
    <p>这是第一行文案</p>
    <p>这是第二行文案</p>
    <p class="s-thirf">1、剩余多行文案需要垂直居中剩余空间</p>
    <p class="s-forth">2、剩余多行文案需要垂直居中剩余空间</p>
    <p>这是最后一行文案</p>
</div>
.g-container {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
}

.s-thirf {
    margin-top: auto;
}

.s-forth {
    margin-bottom: auto;
}

Конечно, любой элемент, который должен быть центрирован по вертикали, а оставшееся пространство обернут в div, а divmargin: auto 0это тоже хорошо.

Что ж, очень полезно и удобно:Демонстрация CodePen -- автоматические поля для быстрого центрирования любого абзаца по вертикали

использоватьmargin-top: autoРеализуйте липкий макет нижнего колонтитула

Хорошо, давайте наконец рассмотрим такой пример.

Требование: На странице должен быть раздел нижнего колонтитула. Если высота содержимого всей страницы меньше высоты области просмотра, то нижний колонтитул фиксируется внизу области просмотра. Если высота содержимого всей страницы больше чем высота области просмотра, нижний колонтитул перемещается нормально (то есть требуется прокрутка. Вы можете видеть нижний колонтитул только внизу), что является своего рода липким макетом.

Взгляните на эффект:

margintopauto

Ну, если вы можете использовать flex для этого требования, используйтеjustify-content: space-betweenЭто может быть решено очень хорошо, так же, как использоватьmargin-top: autoТакже очень легко сделать:

<div class="g-container">
    <div class="g-real-box">
        ...
    </div>
    <div class="g-footer"></div>
</div>
.g-container {
    height: 100vh;
    display: flex;
    flex-direction: column;
}

.g-footer {
    margin-top: auto;
    flex-shrink: 0;
    height: 30px;
    background: deeppink;
}

Codepen Demo -- sticky footer by flex margin auto

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

CodePen Demo -- sticky footer by margin/paddig

Примечательные моменты

Автоматическая маржа по-прежнему очень практична, и есть много сценариев, которые можно использовать.Некоторые из упомянутых выше моментов необходимо подчеркнуть еще раз:

  • контекст форматирования блокасерединаmargin-topа такжеmargin-bottomЕсли значение auto, то их значение равно 0

  • гибкий контекст форматированияв, черезjustify-contentа такжеalign-selfПеред выравниванием любое свободное пространство будет выделено для автоматического поля в этом направлении.

  • Автоматический запас в одном направлении также очень полезен, он рассчитывается как оставшееся пространство в этом направлении.

  • гибкие дочерние элементы с автоматическими полями, установленными их родительским элементомjustify-contentи их собственныеalign-selfбольше не будет действовать

наконец

Другие замечательные технические статьи по CSS собраны в моемGithub -- iCSS, продолжайте обновлять, добро пожаловать, нажмите звездочку, чтобы подписаться на коллекцию.

Ну вот и конец этой статьи, надеюсь она вам поможет :)

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

Наконец, обратите внимание на недавно открытый официальный аккаунт в виде более коротких и качественных технических статей, включая, помимо прочего, CSS:

image