Как правильно выровнять элемент 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.