CSS alineación vertical de una o varias líneas


80

Tengo un título que puede tener una o más líneas.

¿Cómo puedo alinear el texto verticalmente? Si siempre fuera una línea, simplemente podría establecer la altura de la línea a la altura del contenedor.

Puedo hacerlo usando JavaScript, pero realmente no me gusta, estoy buscando una forma de CSS puro.

Además, si el contenedor pudiera expandirse con las líneas, sería perfecto, por lo que siempre puedo tener el mismo relleno en la parte superior e inferior.

ingrese la descripción de la imagen aquí


En caso de que la altura del contenedor pueda cambiar ... ¿qué tal esto? jsbin.com/idiqih/edit#preview
Joonas

Respuestas:


113

Para esto, puede usar la display:table-cellpropiedad:

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

Pero funciona IE8 y superior. Lea este artículo para obtener más información: Trucos CSS: centrar verticalmente el texto con varias líneas .


Quería exactamente lo mismo, pero también necesitaba que el div consumiera toda la altura disponible. Esto debería ayudar: stackoverflow.com/a/16837667/260665
Raj Pawan Gumdal

Si no desea .wrapque tenga números mágicos para heighty width, puede configurar cada uno de ellos en 100%. Luego aplique widthy heightal padre de los .wrapelementos.
Mr. Polywhirl

9

Si no te gusta el display:tabletruco (sé que no) aquí tienes una solución sin él:

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

con HTML

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

Esto le da al div una altura de 5em, a menos que el contenido sea más alto, entonces crece.
Ejemplo en vivo aquí .

Editar: Oh, ¿en qué navegadores se supone que funciona? IE8 no cooperará.

(Edición posterior: CSS actualizado para manejar problemas en Chrome)


Técnica genial. Un problema con el que me encontré fue cuando el texto del cuadro se ajustaba por sí solo (en lugar de con las <br>etiquetas que se muestran en el ejemplo) terminé con una gran cantidad de espacio en blanco adicional en la parte inferior de cada elemento en Chrome. Parece que el pseudo elemento se está ajustando a una nueva línea. ¿Alguna idea de cómo mitigar eso?
Dominic P

@DominicP Tienes razón. Aparentemente, el ::afterbloque cree que tiene un ancho (debido a su contenido), por lo que no cabe después del p. Desafortunadamente, necesita el contenido, o colapsaría por completo y no funcionaría. Pero no estoy seguro de por qué hace esto solo con líneas de ajuste y no con s de una sola línea p.
Mr Lister

De todos modos, actualicé la respuesta con la solución. El truco consiste en hacer el pmenos ancho que el div, por lo que hay espacio a la derecha para el ::afterbloque de ancho cero . ¡Espero que esto ayude!
Mr Lister

Si la accesibilidad es una preocupación, esta es la respuesta correcta. No debe clasificar a <div>como a table-item, confundirá al lector de pantalla y, por supuesto, al usuario.
Cthulhu

9

Realmente me gusta esta solución:

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

Siéntase libre de usar hojas de estilo y 100% para la altura ...

También es posible que tenga que comentar los espacios entre las etiquetas de intervalo, ya que estos son bloques en línea

El crédito es para Hades . Lo tengo de aqui

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

Nota: Parece que esto no funciona con contenido de varias líneas.


2
Esta es una solución increíble :) ¡Gracias! ¡Odio tener que depender de las mesas!
3066d0

¡No puedo creer que esto haya funcionado! ¡De lejos, la única solución que funcionó!
keji

1
Esta es la solución más limpia para mi gusto. Me pregunto si las especificaciones de CSS proporcionarán una forma no pirata de hacerlo en mi vida.
DannyB

4

En lugar de usar vertical-align: centery display: table-cell, es posible que desee echar un vistazo al método más nuevo llamado CSS display flex, que es MUCHO más simple

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


funciona muy bien, pero es difícil limitarlo a la cantidad de líneas, se desborda
luky

¡La mejor respuesta para nuevos navegadores! Gracias por agregar esta nueva solución flexible a la pregunta anterior.
Kai Noack

3

algo como esto

HTML

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

CSS

div {
   display: table;
}
p {
   display:table-cell;
   vertical-align: middle;
}

3

Si desea que su texto responda, ajustar palabras de una a varias líneas a medida que el ancho cambia dinámicamente, el truco mencionado anteriormente con el inline-blockayudante (que tiene la mejor compatibilidad aquí) puede no ser suficiente, ya que .inlinehelperpuede empujar el texto de ajuste hacia abajo.
Aquí hay una solución completa para una tarea tan sencilla:

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

Observe la white-space:nowrappropiedad, que previene .inlinehelpery se #contentenvuelve en relación con los demás. white-space:initialen #contentrestablece la capacidad de ajustarse por spansí mismo;

Otra opción: más una cuestión de preferencia personal. Puede utilizar un pseudo elemento en lugar de .inlinehelper. Elimine las .inlinehelperreglas y el elemento css y agregue este selector de css de pseudo-elemento:

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

PD: Me di cuenta de que esta es una pregunta realmente vieja demasiado tarde, por lo tanto, deje que esta respuesta sea, tal vez sea útil para alguien.


1

En cuanto al estilo, una tabla sería la mejor manera de diseñar su contenido (coloque las etiquetas de estilo en 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>

El recuento de líneas requerirá un script JS, eche un vistazo aquí:

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


0

Me gusta ese tipo de solución. Vi en alguna parte este truco en stackoverflow pero no recuerdo dónde exactamente. Muy útil! :)

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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.