Jak wyrównać tekst pionowo w flexbox?


424

Chciałbym użyć Flexboksa do pionowego wyrównania niektórych treści wewnątrz, <li>ale nie odnosząc wielkiego sukcesu.

Sprawdziłem online i wiele samouczków faktycznie używa div otoki, który pobiera align-items:centerz ustawień Flex na rodzicu, ale zastanawiam się, czy można wyciąć ten dodatkowy element?

W tym przypadku zdecydowałem się użyć Flexboksa, ponieważ wysokość elementu listy będzie dynamiczna %.

* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
}

ul {
  height: 100%;
}

li {
  display: flex;
  justify-content: center;
  align-self: center;
  background: silver;
  width: 100%;
  height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>

Odpowiedzi:


543

Zamiast używać align-self: centeruse align-items: center.

Nie ma potrzeby zmiany flex-directionani używania text-align.

Oto twój kod z jedną korektą, aby wszystko działało:

ul {
  height: 100%;
}

li {
  display: flex;
  justify-content: center;
  /* align-self: center;    <---- REMOVE */
  align-items: center;   /* <---- NEW    */
  background: silver;
  width: 100%;
  height: 20%; 
}

align-selfWłaściwość dotyczy Flex przedmiotów . Tyle że twój linie jest elementem elastycznym, ponieważ jego element nadrzędny - ulnie ma - display: flexlub nie został display: inline-flexzastosowany.

Dlatego ulnie jest to elastyczny pojemnik, linie jest elastyczny i align-selfnie ma żadnego efektu.

align-itemsNieruchomość jest podobna do align-self, oprócz tego, że odnosi się do typu flex pojemnikach .

Ponieważ lijest to elastyczny pojemnik, align-itemsmożna go użyć do pionowego wyśrodkowania elementów potomnych.

demo codepen


Technicznie oto jak align-itemsi jak align-selfdziała ...

align-itemsNieruchomość (na zbiorniku) ustawia domyślną wartość align-self(w sztukach). Oznacza align-items: centerto , że wszystkie elementy Flex zostaną ustawione na align-self: center.

Możesz jednak zmienić to ustawienie domyślne, dostosowując align-selfposzczególne elementy.

Na przykład możesz chcieć kolumn o jednakowej wysokości, więc kontener jest ustawiony na align-items: stretch. Jednak jeden element musi być przypięty do góry, więc jest ustawiony na align-self: flex-start.

przykład


W jaki sposób tekst jest elementem elastycznym?

Niektórzy ludzie mogą się zastanawiać, jak ciąg tekstu ...

<li>This is the text</li>

jest elementem potomnym li.

Powodem jest to, że tekst, który nie jest jawnie zawinięty przez element poziomu śródliniowego, jest algorytmicznie zawijany przez pole śródliniowe. To sprawia, że ​​jest anonimowym elementem wbudowanym i dzieckiem elementu nadrzędnego.

Ze specyfikacji CSS:

9.2.2.1 Anonimowe pola śródliniowe

Każdy tekst zawarty bezpośrednio w elemencie kontenera bloku musi być traktowany jako anonimowy element wbudowany.

Specyfikacja Flexbox zapewnia podobne zachowanie.

4. Zegnij przedmioty

Każde dziecko przepływające w kontenerze elastycznym staje się elementem elastycznym, a każdy ciągły ciąg tekstu, który jest bezpośrednio zawarty w elastycznym kontenerze, jest zawijany w anonimowy element elastyczny.

Dlatego tekst w lielemencie jest elementem elastycznym.


2
Lubię align-items: baseline. Dobre dla różnych wysokości pochodzących z różnych znaków Unicode itp.
qräbnö

1
Dziękujemy za wyjaśnienie i powiązanie z koncepcją anonimowych skrzynek wbudowanych ... naprawdę pomaga wyjaśnić, dlaczego niektóre efekty, które można uzyskać metodą prób i błędów, działają w ten sposób.
squarecandy

39

Najczęściej głosowana odpowiedź dotyczy rozwiązania tego konkretnego problemu opublikowanego przez OP, w którym treść (tekst) była zawijana w inline-blockelement. Niektóre przypadki mogą dotyczyć centrowania normalnego elementu w pionie wewnątrz kontenera , co również miało zastosowanie w moim przypadku, więc do tego wystarczy:

align-self: center;

25

Najlepszym ruchem jest po prostu zagnieżdżenie Flexboksa w Flexboksie . Wszystko, co musisz zrobić, to dać dziecku align-items: center. Spowoduje to wyrównanie tekstu w pionie wewnątrz jego elementu nadrzędnego.

// Assuming a horizontally centered row of items for the parent but it doesn't have to be
.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

.child {
  display: flex;
  align-items: center;
}

Jeśli chcesz idealnie wyśrodkować tekst. text-align:centernie działa sam. Skorzystaj align-items: centerz tym.
Tzwenni

8

WYNIK

wprowadź opis zdjęcia tutaj

HTML

<ul class="list">
  <li>This is the text</li>
  <li>This is another text</li>
  <li>This is another another text</li>
</ul>

Użyj align-itemszamiast, align-selfa także dodałem flex-directiondo column.

CSS

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

.list {
  display: flex;
  justify-content: center;
  flex-direction: column;  /* <--- I added this */
  align-items: center;   /* <--- Change here */
  height: 100px;
  width: 100%;
  background: silver;
}

.list li {  
  background: gold;
  height: 20%; 
}

1

* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
}

ul {
  height: 100%;
}

li {
 display: flex;
 justify-content: center;
 align-items: center;
 background: silver;
 width: 100%;
 height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>


0

* {
  padding: 0;
  margin: 0;
}
html, body {
  height: 100%;
}
ul {
  height: 100%;
}
li {
  display: flex;
  justify-content: center;
  align-items:center;
  background: silver;
  width: 100%;
  height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>


Odpowiedzi tylko w kodzie nie są zbyt przydatne ... dodaj komentarze lub wyjaśnienie tego, co zrobiłeś i dlaczego to działa.
random_user_name

0

Za pomocą display: flexmożesz kontrolować pionowe wyrównanie elementów HTML.

.box {
  height: 100px;
  display: flex;
  align-items: center; /* Vertical */
  justify-content: center; /* Horizontal */
  border:2px solid black;
}

.box div {
  width: 100px;
  height: 20px;
  border:1px solid;
}
<div class="box">
  <div>Hello</div>
  <p>World</p>
</div>


-6

Można zmienić uli liwyświetlaczy do tablea table-cell. Wtedy vertical-alignpracowałby dla ciebie:

ul {
    height: 20%;
    width: 100%;
    display: table;
}

li {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    background: silver;
    width: 100%; 
}

http://codepen.io/anon/pen/pckvK


Działa dobrze, dopóki nie dodasz tam kolejnego elementu listy.
George

1
To prawda ... Ale nigdy o tym nie wspomniano
Lc Salalazar

zmieniłeś wysokość na ul zamiast li? każda wysokość li będzie dynamiczna, więc nie jest to coś, czego mógłbym się obawiać
styler

@LcSalazar Zazwyczaj nie używałbyś listy, gdybyś chciał mieć tylko jeden przedmiot. Po to są divy.
Ben Visness

2
Znowu prawda ... Ale nie mówię, że to idealny scenariusz. Właśnie opublikowałem rozwiązanie, które odpowiada na pytanie w obecnej formie. Mam nadzieję, że ta informacja przyda się komuś, kto ją przeczyta i ma inny scenariusz ...
LcSalazar
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.