2008-09-12 13 views
132

¿Cuál es la mejor manera de centrar verticalmente el contenido de un div cuando el alto del contenido es variable? En mi caso particular, la altura del contenedor div es fija, pero sería genial si hubiera una solución que funcionaría en casos donde el contenedor también tenga una altura variable. Además, me encantaría una solución sin, o con muy poco uso de CSS hacks y/o marcas no semánticas.¿Cómo centrar verticalmente el contenido con altura variable dentro de un div?

alt text

+0

el método en el que el artículo se desmorona en Safari (4.0.5) : S –

+7

@ ripper234 No exactamente, ya que esta pregunta es acerca de la altura variable div –

+9

También, esta questi se preguntó primero. –

Respuesta

93

Sólo tiene que añadir

position: relative; 
top: 50%; 
transform: translateY(-50%); 

a la div interna.

Lo que hace es mover el borde superior del div interior a la mitad de la altura del div exterior (top: 50%;) y luego el div interior a la mitad de su altura (transform: translateY(-50%)). Esto funcionará con position: absolute o relative.

Tenga en cuenta que transform y translate tienen prefijos de proveedor que no están incluidos por simplicidad.

Codepen: http://codepen.io/anon/pen/ZYprdb

+6

Me acabo de preguntar por qué esto funciona en Chrome y Firefox, pero no para Safari. Luego noté que la mayoría de las cosas relacionadas con 'transform' son' -webkit-'con prefijo y ahora funcionan. Tan solo como un recordatorio: No se olvide de agregar el prefijo '-webkit-' también. – miho

+5

Use una herramienta como https://github.com/postcss/autoprefixer para manejar los prefijos por usted. –

+6

Esta respuesta debe estar en la parte superior. –

16

Esto es algo que he necesitado hacer muchas veces y una solución consistente aún requiere agregar un poco de margen de beneficio no semántica y algunos hacks navegador específicos. Cuando obtengamos compatibilidad con el navegador para css 3 obtendrá su centrado vertical sin pecar.

Para una mejor explicación de la técnica puede mirar the article I adapted it from, pero básicamente implica agregar un elemento adicional y aplicar diferentes estilos en IE y navegadores compatibles con position:table\table-cell en elementos que no sean de tabla.

<div class="valign-outer"> 
    <div class="valign-middle"> 
     <div class="valign-inner"> 
      Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me. 
     </div> 
    </div> 
</div> 

<style> 
    /* Non-structural styling */ 
    .valign-outer { height: 400px; border: 1px solid red; } 
    .valign-inner { border: 1px solid blue; } 
</style> 

<!--[if lte IE 7]> 
<style> 
    /* For IE7 and earlier */ 
    .valign-outer { position: relative; overflow: hidden; } 
    .valign-middle { position: absolute; top: 50%; } 
    .valign-inner { position: relative; top: -50% } 
</style> 
<![endif]--> 
<!--[if gt IE 7]> --> 
<style> 
    /* For other browsers */ 
    .valign-outer { position: static; display: table; overflow: hidden; } 
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; } 
</style> 

Hay muchas maneras (hacks) para aplicar estilos en conjuntos específicos de navegadores. Usé comentarios condicionales, pero mira el artículo vinculado anteriormente para ver otras dos técnicas.

Nota: Hay formas simples de centrar verticalmente si conoce algunas alturas por adelantado, si está tratando de centrar una sola línea de texto, o en muchos otros casos. Si tiene más detalles, inclúyalos porque puede haber un método que no requiera hackers de navegador o marcas no semánticas.

Actualización: Estamos empezando a obtener un mejor soporte para CSS3 navegador, con lo que tanto la flexión de la caja y se transforma como métodos alternativos para conseguir vertical de centrado (entre otros efectos). Consulte this other question para obtener más información acerca de los métodos modernos, pero tenga en cuenta que el soporte del navegador todavía es incompleto para CSS3.

+0

Sí, Encontré ese artículo hoy y no he podido hacerlo funcionar para mi situación particular. Quizás necesito investigar eso más. – jessegavin

+0

¿Quizás pueda publicar el código que está utilizando que no funciona? –

+3

No, estoy equivocado. ¡Ese método funciona totalmente! – jessegavin

151

Esta parece ser la mejor solución que he encontrado para este problema, siempre y cuando su navegador admita el pseudo elemento ::before: CSS-Tricks: Centering in the Unknown.

No requiere ningún marcado extra y parece funcionar extremadamente bien. No pude usar el método display: table porque los elementos table no obedecen a la propiedad max-height.

.block { 
 
    height: 300px; 
 
    text-align: center; 
 
    background: #c0c0c0; 
 
    border: #a0a0a0 solid 1px; 
 
    margin: 20px; 
 
} 
 

 
.block::before { 
 
    content: ''; 
 
    display: inline-block; 
 
    height: 100%; 
 
    vertical-align: middle; 
 
    margin-right: -0.25em; /* Adjusts for spacing */ 
 

 
    /* For visualization 
 
    background: #808080; width: 5px; 
 
    */ 
 
} 
 

 
.centered { 
 
    display: inline-block; 
 
    vertical-align: middle; 
 
    width: 300px; 
 
    padding: 10px 15px; 
 
    border: #a0a0a0 solid 1px; 
 
    background: #f5f5f5; 
 
}
<div class="block"> 
 
    <div class="centered"> 
 
     <h1>Some text</h1> 
 
     <p>But he stole up to us again, and suddenly clapping his hand on my 
 
      shoulder, said&mdash;"Did ye see anything looking like men going 
 
      towards that ship a while ago?"</p> 
 
    </div> 
 
</div>

+3

Ahora, eso es una solución -BRILLANTE. Muchas gracias por publicar esto! –

+0

Como con la otra respuesta, esta sería mucho mejor si describiera el enfoque y el código incluido en el enlace. – KatieK

+3

+1, ¡Esta solución es realmente bastante ingeniosa! Por cierto, podrías agregar '.block {white-space: nowrap; tamaño de fuente: 0; línea-altura: 0; } 'y deje el margen derecho negativo en el pseudo elemento, solo tiene que restablecer fs y lh en .centered ...así se asegura de que el elemento esté correctamente posicionado incluso si es más ancho que la ventana gráfica (y no tiene que usar el margen negativo demasiado desordenado). – Simon

7

Uso del selector de niño, he tomado Fadi's incredible answer arriba y se hierven a una sola regla CSS que puedo aplicar. Ahora todo lo que tengo que hacer es añadir el nombre contentCentered clase de elementos Quiero centro:

.contentCentered { 
 
    text-align: center; 
 
} 
 

 
.contentCentered::before { 
 
    content: ''; 
 
    display: inline-block; 
 
    height: 100%; 
 
    vertical-align: middle; 
 
    margin-right: -.25em; /* Adjusts for spacing */ 
 
} 
 

 
.contentCentered > * { 
 
    display: inline-block; 
 
    vertical-align: middle; 
 
}
<div class="contentCentered"> 
 
    <div> 
 
    <h1>Some text</h1> 
 
    <p>But he stole up to us again, and suddenly clapping his hand on my 
 
     shoulder, said&mdash;"Did ye see anything looking like men going 
 
     towards that ship a while ago?"</p> 
 
    </div> 
 
</div>

bifurcada CodePen: http://codepen.io/dougli/pen/Eeysg

+0

Cool. Gracias por compartir. Una nota de precaución es que el selector '*' va a funcionar peor que la respuesta aceptada. Puede que no sea un problema, pero vale la pena señalarlo. http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/ – jessegavin

+0

Gracias. Sí, probablemente funcionará peor, pero hoy en día las reglas de CSS probablemente no afecten demasiado. Probablemente podamos mejorar esto seleccionando '> div 'en su lugar. http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/ – dougli

+0

Simple y genial. Funciona para mí perfectamente –

0

Ésta es mi solución impresionante para un div con una altura dinámica (porcentual).

CSS

.vertical_placer{ 
    background:red; 
    position:absolute; 
    height:43%; 
    width:100%; 
    display: table; 
} 

.inner_placer{ 
    display: table-cell; 
    vertical-align: middle; 
    text-align:center; 
} 

.inner_placer svg{ 
    position:relative; 
    color:#fff; 
    background:blue; 
    width:30%; 
    min-height:20px; 
    max-height:60px; 
    height:20%; 
} 

HTML

<div class="footer"> 
    <div class="vertical_placer"> 
     <div class="inner_placer"> 
      <svg> some Text here</svg> 
     </div> 
    </div> 
</div> 

Try this by yourself.

2

Usted puede utilizar auto margen. Con flex, el div parece estar centrado verticalmente también.

body, 
html { 
    height: 100%; 
    margin: 0; 
} 
.site { 
    height: 100%; 
    display: flex; 
} 
.site .box { 
    background: #0ff; 
    max-width: 20vw; 
    margin: auto; 
} 
<div class="site"> 
    <div class="box"> 
    <h1>blabla</h1> 
    <p>blabla</p> 
    <p>blablabla</p> 
    <p>lbibdfvkdlvfdks</p> 
    </div> 
</div> 
+0

: flex sigue siendo prácticamente una característica experimental; ningún navegador lo admite correctamente aún – andreszs

+0

Hoy no tan experimental: http://caniuse.com/#search=flex –

2

mejor resultado para mí hasta ahora:

div a estar centrada:

position: absolute; 
top: 50%; 
transform: translateY(-50%); 
margin: 0 auto; 
right: 0; 
left: 0; 
Cuestiones relacionadas