Нижче наведено п'ять варіантів досягнення цього макета:
- CSS-позиціонування
- Flexbox з невидимим елементом DOM
- Flexbox з невидимим псевдоелементом
- Flexbox с
flex: 1
- Макет сітки CSS
Спосіб №1: Властивості позиціонування CSS
Нанесіть position: relative
на гнучку ємність.
Застосувати position: absolute
до пункту D.
Тепер цей предмет абсолютно розташований у гнучкому контейнері.
Більш конкретно, пункт D видаляється з документообігу, але залишається в межах найближчого розташованого предка .
Використовуйте властивості зміщення CSS top
та right
перемістіть цей елемент у положення.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Одним із застережень цього методу є те, що деякі веб-переглядачі можуть не повністю видалити абсолютно розташований гнучкий елемент із звичайного потоку. Це змінює вирівнювання нестандартним, несподіваним чином. Детальніше: Абсолютно розташований гнучкий елемент не вилучається зі звичайного потоку в IE11
Спосіб №2: Автоматичні поля Flex та невидимий елемент Flex (елемент DOM)
За допомогою комбінації auto
поля та нового невидимого гнучких елементів можна досягти макета.
Новий елемент гнучкості ідентичний елементу D і розміщується на протилежному кінці (лівий край).
Більш конкретно, оскільки гнучка вирівнювання заснована на розподілі вільного простору, новий елемент є необхідним противагою, щоб три середніх ящика залишалися горизонтально центрованими. Новий елемент повинен бути тієї ж ширини, що і існуючий елемент D, або середні поля не будуть точно центрировані.
Новий елемент видалено із перегляду за допомогою visibility: hidden
.
Коротко:
- Створіть дублікат
D
елемента.
- Розмістіть його на початку списку.
- Використання гнучкого
auto
поля , щоб зберегти A
, B
і по C
центру, причому обидва D
елемента створення рівного балансу з обох кінців.
- Застосовуємо
visibility: hidden
до дублікатаD
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Спосіб №3: Автоматичні поля Flex та невидимий елемент Flex (псевдоелемент)
Цей спосіб схожий на №2, за винятком того, що він семантично чистіший, і ширина D
має бути відома.
- Створіть псевдоелемент тієї ж ширини, що і
D
.
- Помістіть його на початок контейнера з
::before
.
- Використовуйте гнучкі
auto
кордону для A
, B
і C
центрування з псевдо і D
елементи , що створюють рівний баланс з обох кінців.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Спосіб №4: Додайте flex: 1
елементи вліво і вправо
Починаючи з способу №2 або №3 вище, замість того, щоб турбуватися про однакову ширину лівого та правого елементів, щоб підтримувати рівний баланс, просто надайте кожному flex: 1
. Це змусить їх обох споживати доступний простір, тим самим центруючи середній елемент.
Потім ви можете додавати display: flex
до окремих елементів, щоб вирівняти їх вміст.
ПРИМІТКА щодо використання цього методу з min-height
: Наразі в Chrome, Firefox, Edge та, можливо, інших браузерах правило скороченняflex: 1
до цього:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Цей відсоток одиниця (%) по flex-basis
причинам цей метод , щоб зламати , коли min-height
використовується на контейнері. Це відбувається тому, що, як правило, відсоткові висоти дітей вимагають чіткого height
налаштування властивостей для батьків.
Це давнє правило CSS, яке починається з 1998 року ( рівень CSS 2 ), яке досі чиниться в багатьох браузерах. Повні деталі дивіться тут і тут .
Ось приклад проблеми , опубліковану в коментарях user2651804 :
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Рішення полягає в тому, щоб не використовувати процентну одиницю. Спробуйте px
або просто нічого ( що саме рекомендує специфікація , незважаючи на те, що принаймні деякі з основних браузерів з будь-якої причини додали відсоткову одиницю).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Метод №5: Макет сітки CSS
Це може бути найчистішим і найефективнішим методом. Не потрібно абсолютного позиціонування, фальшивих елементів чи іншого хакерства.
Просто створіть сітку з кількома стовпцями. Потім розмістіть свої предмети в середній та кінці стовпців. В основному, просто залиште перший стовпець порожнім.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>