Como alinhar à direita o item flexível?

680

Existe uma maneira mais flexível de alinhar o "Contato" do que usar 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/

Mark Boulder
fonte
2
você pode usar float certo, mas é da mesma maneira ...! A melhor maneira é usar uma tabela de exibição com alinhamento de texto.
Yohann Tilotti 15/03/14
Claro, se isso é melhor. Ainda tendo problemas para alinhar o "Contato" corretamente: jsfiddle.net/vqDK9/1
Mark Boulder
2
Eu atualizei o seu violino jsfiddle.net/vqDK9/2
Yohann Tilotti 15/03/14
Aqui estão pelo menos duas maneiras de fazer isso: stackoverflow.com/a/33856609/3597276
Michael Benjamin

Respostas:

452

Aqui está. Coloque justify-content: space-betweenno recipiente flexível.

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

Kevin Suttle
fonte
291
Oujustify-content: flex-end
BT
1
Tente definir a largura de .c para 300px. O título não está mais centralizado. Então, sim, isso responde à pergunta, mas isso quebra o design.
Agamemnus
22
Observe que isso nem sempre funciona da maneira que você pode esperar, como quando há um .c::afterpseudo-elemento. Na minha experiência, margin-left: auto;é o caminho a percorrer.
Will
13
Ouflex-flow: row-reverse;
jchook
8
Não vejo essa resposta correta se você não quiser alinhar apenas um item em um contêiner flexível.
Foxhoundn
1097

Uma abordagem mais flexível seria usar uma automargem esquerda (os itens flexíveis tratam as margens automáticas de maneira um pouco diferente do que quando usadas em um contexto de formatação de bloco).

.c {
    margin-left: auto;
}

Violino atualizado:

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

à deriva
fonte
2
Obrigado. Você pessoalmente prefere isso ao método da tabela de exibição de Yohann Tilotti acima? Se sim, por quê?
Mark Boulder
4
@ MarkBoulder: Por motivos de compatibilidade, o método dele é melhor, mas se você já estiver usando o flexbox, minha resposta faria mais sentido.
à deriva
4
@ MarkBoulder: Ambos realizam a mesma coisa neste caso. A vantagem seria ter outras propriedades (e comportamentos) associados com itens flexíveis que a abordagem tabela não tem ( flex, order, etc).
à deriva
3
Se você não conseguir quebrar os elementos e precisar flutuar, diga os três últimos à direita, segmente o terceiro dos últimos apenas com este margin-left: auto;estilo.
Daniel Sokolowski
2
@ Justin descobriu, não há necessidade de embrulhá-los - eu não poderia no meu caso. A solução foi segmentar o primeiro dos três itens apenas com margin-left: auto;.
Daniel Sokolowski
41

Se você quiser usar o flexbox para isso, poderá fazê-lo ( display: flexno contêiner, flex: 1nos itens e assim por text-align: rightdiante .c):

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

... ou alternativamente (ainda mais simples), se os itens não precisarem ser atendidos, você poderá usar justify-content: space-betweeno contêiner e remover text-aligncompletamente as regras:

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

Aqui está uma demonstração no Codepen para permitir que você tente rapidamente o acima.

Nick F
fonte
2
space-betweenera exatamente o que eu procurava, obrigado!
Eddie Fletcher
As fronteiras desaparecem ao usar a segunda sugestão, comportamento esperado? codepen.io/oshihirii/pen/RygKRd
user1063287
38

Você também pode usar um preenchimento para preencher o espaço restante.

<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;
}

Atualizei a solução com 3 versões diferentes. Isso ocorre devido à discussão sobre a validade do uso de um elemento de preenchimento adicional. Se você executar o código cortado, verá que todas as soluções fazem coisas diferentes. Por exemplo, definir a classe de preenchimento no item b fará com que esse item preencha o espaço restante. Isso tem o benefício de que não há espaço "morto" que não seja clicável.

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

Arno
fonte
3
Finalmente alguém que entende flexbox
Kokodoko
9
@Kokodoko sim, usando um elemento html mais não-semântica para mover um outro elemento é o topo da flexbox entendimento ...
Zanshin13
@ Zanshin13 As outras respostas tudo escrever tanto css extra que você poderia muito bem deixar de fora o recipiente flexível e de código a coisa toda se :)
Kokodoko
2
@Kokodoko justify-content: space-betweené "muito" css, sério? Não há necessidade de mais comentários (mas se você quiser - bem-vindo ao bate-papo). Esta resposta tem o direito de estar aqui, porque é uma solução. Mas definitivamente não é o ideal. Idk, talvez você não tenha notado, mas a maioria dos css de outras respostas são OP e as respostas realmente reduzem (um pouco) a quantidade de css do autor. Esta resposta não tem menos css do que outras (não funcionará sem o css do OP - jsfiddle.net/63ma3b56 ). Mas tem mais um elemento html.
precisa saber é o seguinte
32

Ou você pode simplesmente usar justify-content: flex-end

.main { display: flex; }
.c { justify-content: flex-end; }
Melchia
fonte
3
O justify-contentatributo é um atributo do contentor-Flex, consulte cheatsheet flexy de Chris Coyer: css-tricks.com/snippets/css/a-guide-to-flexbox
Klaas van der Weij
1
Esta é a única solução nesta página que funcionou para mim.
user2847376
19

Tão fácil quanto

.main {
    display: flex;
    flex-direction:row-reverse;
}
CESCO
fonte
12

Adicione a seguinte classe CSS à sua folha de estilo:

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

Coloque um elemento vazio entre o elemento à esquerda e o elemento que você deseja alinhar à direita:

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

andreisrob
fonte
Para aqueles que não querem apenas alinhar à direita um elemento, mas podem alinhar à esquerda um elemento e alinhar à direita outro (dentro do mesmo layout flexível), este é o caminho a seguir!
Sensei James
8

Se você precisar que um item seja alinhado à esquerda (como um cabeçalho), mas vários itens alinhados à direita (como 3 imagens), faça algo assim:

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
}

Veja como será isso (apenas CSS relevante foi incluído no snippet acima)

insira a descrição da imagem aqui

TetraDev
fonte
6

'justify-content: flex-end' funcionou no contêiner de caixa de preço.

.price-box {
    justify-content: flex-end;
}
Mohammad Adeel
fonte
4

Acho que adicionar 'justify-content: flex-end' ao contêiner flex resolve o problema, enquanto 'justify-content: space-between' não faz nada.

noites
fonte
2

Para aqueles que usam layout angular e flex, use o seguinte no contêiner de itens flex:

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

Consulte os documentos fxLayoutAlign aqui e os documentos completos do fxLayout aqui .

Lindauson
fonte
0

Exemplo de código com base na resposta do TetraDev

Imagens à direita:

* {
  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>

Imagens à esquerda:

* {
  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>

1,21 gigawatts
fonte