Ниже приведены пять вариантов для достижения этого макета:
- CSS-позиционирование
- Flexbox с невидимым элементом DOM
- Flexbox с невидимым псевдоэлементом
- Флексбокс с
flex: 1
- Макет сетки CSS
Метод № 1: свойства позиционирования CSS
Примените position: relative
к гибкому контейнеру.
Примените position: absolute
к зеленому гибкому элементу.
Теперь зеленый квадрат абсолютно точно расположен внутри гибкого контейнера.
В частности, зеленый квадрат удаляется из потока документов, но остается в пределах ближайший предок.
Используйте свойства смещения CSS top
, bottom
, left
и right
для перемещения зеленого квадрата.
flex-container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
position: relative;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
display: flex;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
flex-container > flex-item:last-child {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%); /* fine tune horizontal centering */
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
Одно предостережение. Некоторые браузеры не могут полностью удалить flex-элемент с абсолютным позиционированием из обычного потока. Это меняет расклад нестандартным, неожиданным образом. Дополнительные сведения: Абсолютно позиционированный гибкий элемент не удаляется из обычного потока в Firefox и IE11
Метод № 2: автоматические поля Flex и невидимый элемент Flex (элемент DOM)
Благодаря сочетанию auto
полей и нового невидимого гибкого элемента макет может быть достигнут.
Новый гибкий элемент идентичен нижнему элементу и размещается на противоположном конце (сверху).
В частности, поскольку гибкое выравнивание основано на распределении свободного пространства, новый элемент является необходимым противовесом для сохранения вертикального центрирования трех синих прямоугольников. Новый элемент должен быть той же высоты, что и существующий зеленый элемент, иначе синие прямоугольники не будут точно центрированы.
Новый элемент удаляется из поля зрения с помощью visibility: hidden
.
Короче говоря:
- Создайте дубликат зеленого прямоугольника.
- Поместите его в начало списка.
- Используйте гибкие поля
auto
, чтобы синие поля располагались по центру, а оба зеленых поля создавали равный баланс с обоих концов.
- Примените
visibility: hidden
к дублирующемуся зеленому квадрату.
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
margin-top: auto;
visibility: hidden;
}
flex-container > flex-item:nth-child(2) {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
}
flex-container > flex-item:first-child,
flex-container > flex-item:last-child {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:nth-child(2) > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item></flex-item>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
Метод № 3: автоматические поля Flex и невидимый элемент Flex (псевдоэлемент)
Этот метод похож на № 2, за исключением того, что он семантически чище, и высота зеленого прямоугольника должна быть известна.
- Создайте псевдоэлемент той же высоты, что и существующий зеленый прямоугольник.
- Поместите его в начало контейнера с помощью
::before
.
- Используйте гибкие поля
auto
, чтобы синие прямоугольники были центрированы, а зеленые псевдоэлементы и элементы DOM создавали равный баланс с обоих концов.
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container::before {
content: "";
margin-top: auto;
height: calc(50px + 8px); /* height + borders */
visibility: hidden;
}
flex-container > flex-item:first-child {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
Способ № 4: добавьте flex: 1
к верхним и нижним элементам
Начиная с метода № 2 или № 3 выше, вместо того, чтобы беспокоиться об одинаковой высоте верхнего и нижнего элементов для сохранения одинакового баланса, просто дайте каждому из них flex: 1
. Это заставит их обоих использовать доступное пространство, тем самым центрируя средний элемент.
Затем вы можете добавить display: flex
к нижнему элементу, чтобы выровнять содержимое.
Метод № 5: макет сетки CSS
Это может быть самый чистый и эффективный метод. Нет необходимости в абсолютном позиционировании, поддельных элементах или других хакерских действиях.
Просто создайте сетку с тремя рядами. Затем выровняйте по центру элементы во второй и третьей строках. Первая строка может оставаться пустой.
grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
align-items: center;
justify-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
grid-item:nth-child(2) {
display: flex;
}
grid-item:nth-child(2)>flex-item {
width: 50px;
height: 50px;
margin: 0 5px;
border: 4px solid aqua;
}
grid-item:nth-child(3) {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<grid-container>
<grid-item></grid-item>
<grid-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</grid-item>
<grid-item></grid-item>
</grid-container>
person
Michael Benjamin
schedule
24.03.2016