Центрирование и выравнивание по правому краю элементов flexbox

Я хотел бы, чтобы 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>

Ответ 1

Ниже приведены пять вариантов достижения этой схемы:

  • Позиционирование CSS
  • Flexbox с невидимым элементом DOM
  • Flexbox с невидимым псевдоэлементом
  • Flexbox с flex: 1
  • CSS Grid Layout

Метод №1: Свойства позиционирования CSS

Применить position: relative гибкого контейнера.

Применить position: absolute к пункту D.

Теперь этот элемент абсолютно расположен внутри контейнера flex.

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

Используйте свойства смещения CSS top и right чтобы переместить этот элемент в 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>

Ответ 2

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

Ответ 3

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

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

.center {
  margin: auto;
}

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

Ответ 4

Я расширил ответ Michael_B

.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>

Ответ 5

Используя подход 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>

Ответ 6

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

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