Как правильно выровнять элемент flex?


682

Есть ли более гибкий способ для выравнивания «Контакта» по правому краю, чем использовать position: absolute?

.main { display: flex; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { flex: 1; text-align: center; }
.c { position: absolute; right: 0; }
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <!--<div class="b"><a href="#">Some title centered</a></div>-->
    <div class="c"><a href="#">Contact</a></div>
</div>

http://jsfiddle.net/vqDK9/


2
Вы можете использовать float прямо, но это так же ...! Лучший способ - использовать таблицу отображения с выравниванием текста.
— Йохан Тилотти

Конечно, если так. Тем не менее, все еще возникают проблемы с выравниванием «Контакта» по правому краю
— Марк Боулдер

2
Я обновил вашу скрипку jsfiddle.net/vqDK9/2
— Йохан Тилотти

Вот как минимум два способа сделать это: stackoverflow.com/a/33856609/3597276
— Майкл Бенджамин

Ответы:


455

Ну вот. Установите justify-content: space-betweenна гибкий контейнер.

.main { 
    display: flex; 
    justify-content: space-between;
  }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { text-align: center; }
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
<!--     <div class="b"><a href="#">Some title centered</a></div> -->
    <div class="c"><a href="#">Contact</a></div>
</div>


291
Илиjustify-content: flex-end
— BT

1
Попробуйте установить ширину .c до 300px. Название больше не по центру. Так что да, это отвечает на вопрос, но это нарушает дизайн.
— Агамемн

23
Обратите внимание, что это не всегда работает так, как вы можете ожидать, например, когда есть .c::afterпсевдоэлемент. По моему опыту, margin-left: auto;это путь.
— Будет

13
Илиflex-flow: row-reverse;
— января

8
Я не вижу правильного ответа, если вы не хотите выровнять только один элемент во флекс-контейнере.
— Foxhoundn

1098

Более гибкий подход заключается в использовании autoлевого поля (элементы flex обрабатывают автоматические поля несколько иначе, чем при использовании в контексте форматирования блока).

.c {
    margin-left: auto;
}

Обновленная скрипка:

.main { display: flex; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { flex: 1; text-align: center; }
.c {margin-left: auto;}
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <!--<div class="b"><a href="#">Some title centered</a></div>-->
    <div class="c"><a href="#">Contact</a></div>
</div>
<h1>Problem</h1>
<p>Is there a more flexbox-ish way to right align "Contact" than to use position absolute?</p>


2
Спасибо. Вы лично предпочли бы это по сравнению с методом отображения таблицы Йоханна Тилотти выше? Если так, то почему?
— Марк Боулдер

4
@MarkBoulder: По причинам совместимости его метод лучше, но если вы уже используете flexbox, мой ответ будет более понятным.
— по течению

4
@MarkBoulder: они оба выполняют одно и то же в этом случае. Преимущество будет иметь другие свойства (и поведение), связанные с гибкими элементами, которых нет у табличного подхода ( flex, orderи т. Д.).
— дрейф

3
Если вы не можете обернуть элементы, и вам нужно плавать, скажем, три последних справа, нацельте третий из последнего только с этим margin-left: auto;стилем.
— Даниэль Соколовский

2
@ Джастин понял это, не нужно оборачивать их - я не мог в моем случае. Решение состояло в том, чтобы предназначаться для 1-го из трех пунктов только с margin-left: auto;.
— Даниэль Соколовский

41

Если вы хотите использовать Flexbox для этого, вы должны быть в состоянии, при этом ( display: flexна контейнере, flex: 1по пунктам, и text-align: rightна .c):

.main { display: flex; }
.a, .b, .c {
    background: #efefef;
    border: 1px solid #999;
    flex: 1;
}
.b { text-align: center; }
.c { text-align: right; }

... или, альтернативно (даже проще), если элементы не должны встречаться, вы можете использовать justify-content: space-betweenконтейнер и полностью удалить text-alignправила:

.main { display: flex; justify-content: space-between; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }

Вот демонстрация на Codepen, чтобы вы могли быстро попробовать выше.


2
space-betweenбыло именно то, что я искал, спасибо!
— Эдди Флетчер

Границы исчезают при использовании второго предложения, ожидаемое поведение? codepen.io/oshihirii/pen/RygKRd
— user1063287

38

Вы также можете использовать заполнитель, чтобы заполнить оставшееся пространство.

<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="filler"></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

.filler{
    flex-grow: 1;
}

Я обновил решение с 3 различными версиями. Это из-за обсуждения обоснованности использования дополнительного элемента-заполнителя. Если вы запускаете фрагмент кода, вы видите, что все решения делают разные вещи. Например, установка класса заполнителя для элемента b заставит этот элемент заполнить оставшееся пространство. Преимущество этого заключается в том, что нет «мертвого» пространства, на которое нельзя нажать.

<div class="mainfiller">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="filler"></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

<div class="mainfiller">
    <div class="a"><a href="#">Home</a></div>
    <div class="filler b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>



<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

<style>
.main { display: flex; justify-content: space-between; }
.mainfiller{display: flex;}
.filler{flex-grow:1; text-align:center}
.a, .b, .c { background: yellow; border: 1px solid #999; }
</style>


3
Наконец, кто-то, кто понимает flexbox
— Kokodoko

9
@Kokodoko да, использование еще одного несемантического HTML-элемента для перемещения другого элемента - вершина понимания flexbox ...
— Zanshin13

@ Zanshin13 Все остальные ответы пишут так много лишних css, что вы могли бы также не использовать гибкий контейнер и кодировать все это самостоятельно :)
— Kokodoko

2
@ Kokodoko justify-content: space-between- это так много, серьезно? Нет необходимости в дальнейших комментариях (но если вы хотите - добро пожаловать в чат). Ответ на этот вопрос имеет право быть здесь, потому что это решение. Но определенно не оптимальный. Idk, может быть, вы не заметили, но большинство css из других ответов - это OP, и ответы на самом деле уменьшают (немного) количество css автора. Этот ответ не имеет меньше css, чем другие (не будет работать без css ОП - jsfiddle.net/63ma3b56 ). Но у него есть еще один элемент HTML.
— Zanshin13

32

Или вы могли бы просто использовать justify-content: flex-end

.main { display: flex; }
.c { justify-content: flex-end; }

3
justify-contentАтрибут является атрибутом флекс-контейнера, см флекси Cheatsheet Криса Coyer в: css-tricks.com/snippets/css/a-guide-to-flexbox
— Клаас ван дер Weij

1
Это единственное решение на этой странице, которое сработало для меня.
— user2847376


12

Добавьте следующий класс CSS в вашу таблицу стилей:

.my-spacer {
    flex: 1 1 auto;
}

Поместите пустой элемент между элементом слева и элементом, который вы хотите выровнять по правому краю:

<span class="my-spacer"></span>


Для тех, кто не просто хочет выровнять по правому краю один элемент, но может захотеть выровнять по левому краю один элемент и выровнять по правому краю другой (в рамках одной и той же гибкой компоновки), это путь!
— Сэнсэй Джеймс

8

Если вам нужно выровнять один элемент по левому краю (например, заголовок), а затем выровнять несколько элементов по правому краю (например, 3 изображения), то вы должны сделать что-то вроде этого:

h1 {
   flex-basis: 100%; // forces this element to take up any remaining space
}

img {
   margin: 0 5px; // small margin between images
   height: 50px; // image width will be in relation to height, in case images are large - optional if images are already the proper size
}

Вот как это будет выглядеть (в приведенный выше фрагмент кода был включен только соответствующий CSS)

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



4

Я считаю, что добавление justify-content: flex-end к контейнеру flex решает проблему, в то время как justify-content: space -ween ничего не делает.


2

Для тех, кто использует Angular и Flex-Layout, используйте следующее для контейнера flex-item:

<div fxLayout="row" fxLayoutAlign="flex-end">

Смотрите документацию fxLayoutAlign здесь и полную документацию fxLayout здесь .


0

Пример кода на основе ответа от TetraDev

Изображения справа:

* {
  outline: .4px dashed red;
}

.main {
  display: flex;
  flex-direction: row;
  align-items: center;
}

h1 {
  flex-basis: 100%;
}

img {
  margin: 0 5px;
  height: 30px;
}
<div class="main">
  <h1>Secure Payment</h1>
  <img src="https://i.stack.imgur.com/i65gn.png">
  <img src="https://i.stack.imgur.com/i65gn.png">
</div>

Изображения слева:

* {
  outline: .4px dashed red;
}

.main {
  display: flex;
  flex-direction: row;
  align-items: center;
}

h1 {
  flex-basis: 100%;
  text-align: right;
}

img {
  margin: 0 5px;
  height: 30px;
}
<div class="main">
  <img src="https://i.stack.imgur.com/i65gn.png">
  <img src="https://i.stack.imgur.com/i65gn.png">
  <h1>Secure Payment</h1>
</div>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.