Jak wyrównać element Flex w prawo?

680

Czy istnieje bardziej elastyczny sposób na wyrównanie do prawej strony „Kontakt” niż użycie 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
źródło
2
możesz użyć pływaka w prawo, ale w ten sam sposób ...! Najlepszym sposobem jest użycie tabeli wyświetlania z wyrównaniem tekstu.
Yohann Tilotti
Jasne, jeśli tak będzie lepiej. Nadal występują problemy z wyrównywaniem „kontaktu”: jsfiddle.net/vqDK9/1
Mark Boulder
2
Zaktualizowałem skrzypce jsfiddle.net/vqDK9/2
Yohann Tilotti
Oto co najmniej dwa sposoby, aby to zrobić: stackoverflow.com/a/33856609/3597276
Michael Benjamin

Odpowiedzi:

453

Proszę bardzo. Ustaw justify-content: space-betweenna elastycznym pojemniku.

.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
źródło
291
Lubjustify-content: flex-end
BT
1
Spróbuj ustawić szerokość .c na 300px. Tytuł nie jest już wyśrodkowany. Tak, to odpowiada na pytanie, ale to łamie projekt.
Agamemnus,
22
Pamiętaj, że nie zawsze działa to tak, jak można się spodziewać, na przykład w przypadku .c::afterpseudoelementu. Z mojego doświadczenia margin-left: auto;wynika, że ​​jest to najlepsza droga.
Czy
13
Lubflex-flow: row-reverse;
jchook
8
Nie uważam tego za poprawną odpowiedź, jeśli nie chcesz wyrównać tylko jednego elementu w elastycznym pojemniku.
Foxhoundn
1097

Bardziej elastycznym podejściem byłoby użycie autolewego marginesu (elementy elastyczne traktują automatyczne marginesy nieco inaczej niż w przypadku formatowania blokowego).

.c {
    margin-left: auto;
}

Zaktualizowano skrzypce:

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

dryfujący
źródło
2
Dzięki. Czy osobiście wolałbyś to od powyższej metody wyświetlania tabeli Yohanna Tilottiego? Jeśli tak, to dlaczego?
Mark Boulder
4
@ MarkBoulder: Ze względu na kompatybilność jego metoda jest lepsza, ale jeśli już korzystasz z Flexboksa, moja odpowiedź byłaby bardziej sensowna.
dryfuje
4
@MarkBoulder: Obaj osiągają to samo w tym przypadku. Zaletą będzie o inne właściwości (i zachowanie) związane z zasilaniem flex przedmiotów, które podejście tabela nie ma ( flex, orderitp).
dryfuje
3
Jeśli nie możesz owijać elementów i musisz unosić się powiedz trzy ostatnie w prawo, celuj w trzeci z ostatnich tylko w tym margin-left: auto;stylu.
Daniel Sokołowski,
2
@Justin zorientował się, że nie trzeba ich owijać - w moim przypadku nie. Rozwiązaniem było skierowanie na pierwszy z trzech przedmiotów tylko za pomocą margin-left: auto;.
Daniel Sokolowski,
41

Jeśli chcesz do tego użyć Flexboksa, powinieneś być w stanie to zrobić ( display: flexna kontenerze, flex: 1na przedmiotach i text-align: rightdalej .c):

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

... lub alternatywnie (jeszcze prościej), jeśli przedmioty nie muszą się spełniać, możesz użyć justify-content: space-betweenna pojemniku i text-aligncałkowicie usunąć reguły:

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

Oto demo na Codepen, które pozwala szybko wypróbować powyższe.

Nick F.
źródło
2
space-betweenbyło dokładnie to, czego szukałem, dzięki!
Eddie Fletcher,
Granice znikają po zastosowaniu drugiej sugestii, oczekiwane zachowanie? codepen.io/oshihirii/pen/RygKRd
user1063287
38

Możesz również użyć wypełniacza, aby wypełnić pozostałe miejsce.

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

Zaktualizowałem rozwiązanie o 3 różne wersje. Jest to spowodowane dyskusją na temat ważności zastosowania dodatkowego elementu wypełniającego. Jeśli uruchomisz wycięty kod, zobaczysz, że wszystkie rozwiązania działają inaczej. Na przykład ustawienie klasy wypełniacza dla elementu b spowoduje, że ten element wypełni pozostałe miejsce. Ma to tę zaletę, że nie ma „martwej” przestrzeni, której nie można kliknąć.

<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
źródło
3
Wreszcie ktoś, kto rozumie flexbox
Kokodoko
9
@Kokodoko tak, użycie jeszcze jednego nie-semantycznego elementu HTML do przeniesienia innego elementu jest szczytem zrozumienia Flexbox ...
Zanshin13
@ Zanshin13 Wszystkie pozostałe odpowiedzi piszą tak dużo dodatkowego css, że równie dobrze możesz pominąć elastyczny pojemnik i sam kodować całość :)
Kokodoko
2
@Kokodoko justify-content: space-betweento poważnie? Nie potrzebujesz dalszych komentarzy (ale jeśli chcesz - witaj na czacie). Ta odpowiedź ma prawo być tutaj, ponieważ jest rozwiązaniem. Ale zdecydowanie nie optymalny. Idk, może nie zauważyłeś, ale większość css z innych odpowiedzi to OP i odpowiedzi faktycznie zmniejszają (trochę) ilość css autora. Ta odpowiedź nie ma mniej css niż inne (nie będzie działać bez css OP - jsfiddle.net/63ma3b56 ). Ale ma jeszcze jeden element HTML.
Zanshin13,
32

Lub możesz po prostu użyć justify-content: flex-end

.main { display: flex; }
.c { justify-content: flex-end; }
Melchia
źródło
3
Ten justify-contentatrybut jest atrybutem elastycznego kontenera, zobacz elastyczny ściągawka Chrisa Coyera: css-tricks.com/snippets/css/a-guide-to-flexbox
Klaas van der Weij
1
To jest jedyne rozwiązanie na tej stronie, które działało dla mnie.
user2847376,
19

Łatwy jak

.main {
    display: flex;
    flex-direction:row-reverse;
}
CESCO
źródło
12

Dodaj następującą klasę CSS do swojego arkusza stylów:

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

Umieść pusty element między elementem po lewej stronie a elementem, który chcesz wyrównać do prawej:

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

andreisrob
źródło
Dla tych, którzy nie chcą po prostu wyrównać jednego elementu do prawej, ale mogą chcieć wyrównać jeden element w lewo, a drugi wyrównać w prawo (w tym samym układzie Flex), jest to droga!
Sensei James
8

Jeśli potrzebujesz wyrównania do lewej strony (jak nagłówek), a następnie wyrównania wielu elementów do prawej (jak 3 obrazy), możesz zrobić coś takiego:

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
}

Oto jak to będzie wyglądać (tylko fragment CSS został uwzględniony we fragmencie powyżej)

wprowadź opis zdjęcia tutaj

TetraDev
źródło
6

„justify-content: flex-end” działało w ramach kontenera cenowego.

.price-box {
    justify-content: flex-end;
}
Mohammad Adeel
źródło
4

Uważam, że dodanie „justify-content: flex-end” do elastycznego kontenera rozwiązuje problem, podczas gdy „justify-content: space-between” nic nie robi.

noce
źródło
2

Dla tych, którzy używają Angular i Flex-Layout, użyj następujących elementów na kontenerze flex-item:

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

Zobacz fxLayout Wyrównaj dokumenty tutaj i pełne dokumenty fxLayout tutaj .

Lindauson
źródło
0

Przykładowy kod oparty na odpowiedzi TetraDev

Obrazy po prawej:

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

Obrazy po lewej:

* {
  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 gigawata
źródło