Елементи флексибокса вирівняйте по центру і вправо


147

Я хотів би мати A Bі Cвирівняти посередині.

Як я можу змусити Dйти повністю праворуч?

ПЕРЕД:

введіть тут опис зображення

ПІСЛЯ:

введіть тут опис зображення

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;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

Відповіді:


214

Нижче наведено п'ять варіантів досягнення цього макета:

  • CSS-позиціонування
  • Flexbox з невидимим елементом DOM
  • Flexbox з невидимим псевдоелементом
  • Flexbox с flex: 1
  • Макет сітки CSS

Спосіб №1: Властивості позиціонування CSS

Нанесіть position: relativeна гнучку ємність.

Застосувати position: absoluteдо пункту D.

Тепер цей предмет абсолютно розташований у гнучкому контейнері.

Більш конкретно, пункт D видаляється з документообігу, але залишається в межах найближчого розташованого предка .

Використовуйте властивості зміщення CSS topта rightперемістіть цей елемент у положення.

Одним із застережень цього методу є те, що деякі веб-переглядачі можуть не повністю видалити абсолютно розташований гнучкий елемент із звичайного потоку. Це змінює вирівнювання нестандартним, несподіваним чином. Детальніше: Абсолютно розташований гнучкий елемент не вилучається зі звичайного потоку в IE11


Спосіб №2: Автоматичні поля Flex та невидимий елемент Flex (елемент DOM)

За допомогою комбінації autoполя та нового невидимого гнучких елементів можна досягти макета.

Новий елемент гнучкості ідентичний елементу D і розміщується на протилежному кінці (лівий край).

Більш конкретно, оскільки гнучка вирівнювання заснована на розподілі вільного простору, новий елемент є необхідним противагою, щоб три середніх ящика залишалися горизонтально центрованими. Новий елемент повинен бути тієї ж ширини, що і існуючий елемент D, або середні поля не будуть точно центрировані.

Новий елемент видалено із перегляду за допомогою visibility: hidden.

Коротко:

  • Створіть дублікат Dелемента.
  • Розмістіть його на початку списку.
  • Використання гнучкого autoполя , щоб зберегти A, Bі по Cцентру, причому обидва Dелемента створення рівного балансу з обох кінців.
  • Застосовуємо visibility: hiddenдо дублікатаD


Спосіб №3: Автоматичні поля Flex та невидимий елемент Flex (псевдоелемент)

Цей спосіб схожий на №2, за винятком того, що він семантично чистіший, і ширина Dмає бути відома.

  • Створіть псевдоелемент тієї ж ширини, що і D.
  • Помістіть його на початок контейнера з ::before.
  • Використовуйте гнучкі autoкордону для A, Bі Cцентрування з псевдо і Dелементи , що створюють рівний баланс з обох кінців.


Спосіб №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 :

Рішення полягає в тому, щоб не використовувати процентну одиницю. Спробуйте pxабо просто нічого ( що саме рекомендує специфікація , незважаючи на те, що принаймні деякі з основних браузерів з будь-якої причини додали відсоткову одиницю).


Метод №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>


1
Дуже приємно, дякую за пояснення! Я думаю, що щойно додані фрагменти коду отримали б користь від скорочення прикладу тексту, оскільки з виводу фактично не видно, що вміст зосереджений / не центрований через малий вікно перегляду. Тільки я?
користувач2651804

"Новий елемент повинен бути тієї ж ширини, що і існуючий елемент D, або середні поля не будуть точно центрировані." - це гадає, що він повинен бути однакової ширини, але слава богу за сітку CSS :)
Вучко

Використовуючи техніку Grid, елементи не знаходяться в мертвому центрі, чи є спосіб, щоб логотип в центрі був мертвим? imgur.com/a/SVg9xsj
J86

Не достатньо знайомий з рішенням сітки, хоча він працює як шарм і є найчистішим. Одне запитання, яке я маю, - як надати більше місця середній колонці, не рівній усім трьом?
Саба Аханг

5

Найпростіший спосіб

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>


2

Якщо ви хочете вирівняти їх, ви можете просто прикріпити порожній проміжок і розділити на них три діапазони.


2
чи можете ви надати коротку демонстраційну версію для створення резервної копії вашої заяви?
klewis

2

Найпростішим рішенням буде виправдання контент-центру на батьківському контейнері та надання автоматичного залишеного поля першому та останньому дочірньому елементу.

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>


1

Використовуючи display:gridпідхід, ви можете просто помістити всіх ulдітей в одну клітинку, а потім встановити justify-self:

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>


0

Дуже чітке питання. Я не міг не опублікувати відповідь через кілька годин копання. Ми могли б вирішити це за допомогою таблиць, комірок таблиці, абсолютних позицій, перетворень, але нам просто довелося це робити за допомогою флексокса :)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd


8
Це справді не в центрі середніх елементів, оскільки воно містить лише фактори, що залишилися , а не весь простір. codepen.io/anon/pen/QKGrRk
Майкл Бенджамін

@Michael_B, ваше право цього не помітило, моє погано. Повернення до використання абсолютних позицій :( Можливо, з високим представником ви повинні встановити щедрість, щоб це вирішилось назавжди. Я б, але у мене дуже низький представник, навіть нижчий зараз, намагаючись вам допомогти.
rgfx

Жодна щедрість не збирається додавати нову поведінку до моделі флексбоксу, відповідь, надана Michael_B, така гарна, як і сьогодні ...
Асон

0

Я розширив Michael_B «s відповідь

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

Тут за допомогою SASS як кодексу


0

Натхненний методом №5: Макет сітки CSS рішення @Michal Benjamin і тому, що я використовую Tailwind, і на сьогоднішній день досі не мають доступу до всіх параметрів сітки за замовчуванням. Це, здається, працює:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Не впевнений, чи добре змішувати флекс та сітку, як це!


1
ви не змішуєте сітку та flex, виправданий вміст - це властивість CSS-мережі та властивість flexbox (те саме для align-self)
Temani Afif

-1

Прийняту відповідь можна трохи змінити, оскільки ви можете використовувати області шаблону сітки та робити це без фальшивого елемента

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

-1
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;
}
li:last-child {
  background: #ddd;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.