css wyrównanie w pionie pojedynczej lub wielu linii

80

Mam tytuł, który może mieć jedną lub więcej linii.

Jak mogę wyrównać tekst w pionie? Gdyby to był zawsze jeden wiersz, mógłbym po prostu ustawić wysokość wiersza na wysokość kontenera.

Mogę to zrobić używając JavaScript, ale nie bardzo mi się to podoba, szukam czystego sposobu CSS.

Również, jeśli pojemnik mógłby rozszerzać się wraz z liniami, byłby idealny, więc zawsze mogę mieć takie samo wypełnienie na górze i na dole.

wprowadź opis obrazu tutaj

uszkodzenie mózgu
źródło
W przypadku, gdy wysokość pojemnika może się zmienić ... co powiesz na to? jsbin.com/idiqih/edit#preview
Joonas

Odpowiedzi:

113

W tym celu możesz użyć display:table-cellwłaściwości:

.inline {
  display: inline-block;
  margin: 1em;
}
.wrap {
  display: table;
  height:  100px;
  width:   160px;
  padding: 10px;
  border:  thin solid darkgray;
}
.wrap p {
  display:        table-cell;
  vertical-align: middle;
}
<div class="inline">
  <div class="wrap">
    <p>Example of single line.</p>
  </div>
</div>

<div class="inline">
  <div class="wrap">
    <p>To look best, text should really be centered inside.</p>
  </div>
</div>

Ale działa w IE8 i nowszych. Przeczytaj ten artykuł, aby uzyskać więcej informacji: Sztuczki CSS: wyśrodkuj tekst wielowierszowy w pionie .

Sandeep
źródło
Chciałem dokładnie tego samego, ale potrzebowałem również, aby div zajmował całą dostępną wysokość. To powinno w tym pomóc: stackoverflow.com/a/16837667/260665
Raj Pawan Gumdal
Jeśli nie chcesz, .wrapaby miały magiczne liczby dla heighti width, możesz ustawić każdą z nich na 100%. Następnie zastosuj widthi heightdo rodzica .wrapelementów.
Pan Polywhirl
9

Jeśli nie lubisz display:tablesztuczki (wiem, że nie), oto rozwiązanie bez niej:

.cen {
  min-height:5em; width:12em; background:red; margin:1em 0;
}
.cen p {
  display:inline-block; vertical-align:middle;
  margin:0 0 0 1em; width:10em;
}
.cen::after {
   display:inline-block; vertical-align:middle; line-height:5em;
   width:0; content:"\00A0"; overflow:hidden;
}

z HTML

<div class="cen">
 <p>Text in div 1</p>
</div>

Daje to divowi wysokość 5em, chyba że zawartość jest wyższa, wtedy rośnie.
Przykład na żywo tutaj .

Edycja: Och, na których przeglądarkach ma to działać? IE8 nie będzie współpracować.

(Późniejsza edycja: zaktualizowany CSS do obsługi problemów w Chrome)

Panie Lister
źródło
Fajna technika. Jednym z problemów, na które natknąłem się, było to, że tekst w pudełku był zawinięty samodzielnie (zamiast <br>tagów pokazanych w przykładzie), w wyniku czego pojawiło się dużo dodatkowej białej przestrzeni na dole każdego elementu w Chrome. Wygląda na to, że pseudoelement jest zawijany do nowej linii. Masz jakiś pomysł, jak to złagodzić?
Dominic P
@DominicP Masz rację. Najwyraźniej ::afterblok myśli, że ma szerokość (ze względu na swoją zawartość), więc nie będzie pasował po p. Niestety wymaga zawartości, w przeciwnym razie całkowicie się zawali i nie zadziała. Ale nie jestem pewien, dlaczego robi to tylko z zawijaniem linii, a nie z pojedynczą linią p.
Pan Lister,
W każdym razie zaktualizowałem odpowiedź o rozwiązanie. Sztuczka polega na tym, aby zrobić pmniejszą szerokość niż element div, tak aby po jego prawej stronie było miejsce na ::afterblok o zerowej szerokości . Mam nadzieję że to pomoże!
Pan Lister,
Jeśli dostępność jest problemem, to jest prawidłowa odpowiedź. Nie należy klasyfikować a <div>jako table-item, ponieważ zmyli to czytnik ekranu i, oczywiście, użytkownika.
Cthulhu,
9

Bardzo podoba mi się to rozwiązanie:

<div>
    <span style="display: inline-block; vertical-align: middle; height: --The height of your box here--"></span>
    <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here</span>
</div>

Zapraszam do korzystania z arkuszy stylów i 100% na wysokość ...

Może być również konieczne wykomentowanie spacji między znacznikami span, ponieważ są to bloki inline

Kredyt trafia do Hadesa . Mam to stąd

<div style="outline:thin solid red;">
  <span style="display: inline-block; vertical-align: middle; height: 60px;"></span>
  <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here.</span>
</div>

<div style="outline:thin solid red;">
  <span style="display: inline-block; vertical-align: middle; height: 60px;"></span>
  <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here. Put your multi-line content here. Put your multi-line content here. Put your multi-line content here. Put your multi-line content here.</span>
</div>

Uwaga: wydaje się, że nie działa to w przypadku zawartości wielu wierszy.

Rolf
źródło
2
To świetne rozwiązanie :) dziękuję! Nienawidzę polegać na stołach!
3066d0
Nie mogę uwierzyć, że to zadziałało! Zdecydowanie jedyne rozwiązanie, które zadziałało!
keji
1
To najczystsze rozwiązanie według mojego gustu. Zastanawiam się, czy specyfikacje CSS zapewnią niehackowy sposób na zrobienie tego za mojego życia.
DannyB
4

Zamiast używać vertical-align: centeri display: table-cell, możesz rzucić okiem na nowszą metodę zwaną CSS display flex, która jest DUŻO prostsza

.box {
    width: 200px;
    height: 50px; 
    padding: 10px;
    margin-bottom: 20px;
    background-color: red;
    
    /* Only add these 2 lines */
    display: flex;
    align-items: center;
  }
<div class="box">Lorem ipsum dolor</div>
<div class="box">Lorem ipsum dolor sit amet ipsum dolor</div>

Hans Tiono
źródło
działa świetnie, ale trudno ograniczyć go do liczby wierszy, przepełnia
luky
Najlepsza odpowiedź dla nowych przeglądarek! Dziękujemy za dodanie tego nowego rozwiązania flex do starego pytania.
Kai Noack
3

coś takiego

HTML

<div>
    <p>
       Lorem Ipsum is simply
    </p>
</div>

CSS

div {
   display: table;
}
p {
   display:table-cell;
   vertical-align: middle;
}
Aram Mkrtchyan
źródło
3

Jeśli chcesz, aby Twój tekst był responsywny, zawijanie słów od jednego do wielu wierszy, gdy szerokość zmienia się dynamicznie, wspomniana powyżej sztuczka z inline-blockpomocnikiem (który ma tutaj najlepszą kompatybilność) może nie wystarczyć, podobnie jak .inlinehelperzawijanie tekstu pod siebie.
Oto kompletne rozwiązanie dla takiego prostego zadania:

HTML:

<div id="responsive_wrap">
    <span class="inlinehelper"><span id="content">        
</div>

CSS:

#responsive_wrap {   
   display: block;    
   height: 100%; //dimensions just for   
   width: 100%;  //example's sake
   white-space: nowrap;
}

#content {   
   display: inline-block;        
   white-space: initial;
}

.inlinehelper {
   height: 100%;    
   width: 0;
   vertical-align: middle;
   display: inline-block;
}

Zwróć uwagę na white-space:nowrapwłaściwość, która zapobiega .inlinehelperi #contentzawija się względem siebie. white-space:initialpo #contentzresetowaniu możliwości samodzielnego owijania span;

Inna opcja: bardziej kwestia osobistych preferencji. Możesz użyć pseudoelementu zamiast .inlinehelper. Usuń .inlinehelperreguły i element css i dodaj ten pseudoelement selektor css:

#responsive_wrap:before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    height: 100%;
    width: 0px;
}

PS: Za późno zorientowałem się, że to naprawdę stare pytanie, więc niech taka odpowiedź będzie, może komuś się przyda.

Max Yari
źródło
1

Jeśli chodzi o styl, tabela byłaby najlepszym sposobem na układ treści (umieść tagi stylu w CSS):

<table style="border:1;collapse;width:300px;padding:5px;background-color:red;">
<tr>
    <td style="width:250px;vertical-align:middle;">Lorem ipsum dolor sit amet ipswum dolor</td>
    <td style="width:50px;vertical-align:top;color:white;">1 Line</td>
</tr>

Liczba linii będzie wymagać skryptu JS, spójrz tutaj:

http://www.webdeveloper.com/forum/archive/index.php/t-44333.html

Ryan Brodie
źródło
0

Lubię takie rozwiązania. Widziałem gdzieś tę sztuczkę w przepełnieniu stosu, ale nie pamiętam, gdzie dokładnie. Bardzo przydatne! :)

ul {
background: #000; 
  padding-left: 0;
}
ul li {
  height: 130px;
  position: relative;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  border-bottom: 3px solid #F7F7F7;
}
ul li:last-of-type {
  border-bottom: none;
}
ul li:after {
  color: #333;
  position: absolute;
  right: 35px;
  font-size: 40px;
  content: ">";
  top: 50%;
  margin-top: -24px;
  color: #FFDA00;
  -webkit-transition: 0.25s all ease;
  transition: 0.25s all ease;
}
ul li a {
  font-size: 35px;
  font-family: Arial;
  color: #fff;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  padding-left: 40px;
  height: 100%;
  line-height: 38px;
  display: inline-block;
  width: 100%;
  text-align: left;
  text-decoration: none;
}
ul li a:before {
  display: inline-block;
  vertical-align: middle;
  content: " ";
  height: 100%;
}
ul li a span {
  display: inline-block;
  vertical-align: middle;
}
<ul>
	<li class="dn">
		<a href="kapec.ru.php"><span> Lorem ipsum 1 LINE</span></a>
		</li>
		<li>
			<a href="varianti.ru.php"><span>Lorem ipsum <br> 2 lines </span></a>
		</li>

	</ul>

Алексей Воробьёв
źródło