Cómo centrar el div verticalmente dentro del div padre absolutamente posicionado

146

Estoy tratando de obtener un contenedor azul en medio del rosa, sin embargo, parece vertical-align: middle;que no funciona en ese caso.

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

Resultado:

ingrese la descripción de la imagen aquí

Expectativa:

ingrese la descripción de la imagen aquí

Sugiera cómo puedo lograr eso.

Jsfiddle

Vladimirs
fuente
1
¿Hay alguna razón por la que estás usando en position: absolutetodas partes?
Vucko
los vertical-align: middle;trabajos con display: inline-blocko diseño de tabla
ctf0
mira este enlace: vanseodesign.com/css/vertical-centering ;)
Jordi Castilla
@Vucko sí, eso es un prerrequisito, ya que esta es solo una versión simplificada de un diseño muy complejo, pero la posición absoluta en ambos divs superiores es la clave.
Vladimirs
@Vladimirs Solo puedo pensar en margin-top: calc((56px - 16px) / 2)dónde 56px - parent height, 16px - element height/font-size- JSFiddle
Vucko

Respuestas:

332

En primer lugar, tenga en cuenta que vertical-alignsolo es aplicable a celdas de tabla y elementos de nivel en línea.

Hay dos formas de lograr alineaciones verticales que pueden o no satisfacer sus necesidades. Sin embargo, te mostraré dos métodos de mis favoritos:

1. Usando transformytop

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

El punto clave es que un valor de porcentaje en topes relativo al del heightbloque contenedor; Mientras que un valor porcentual en transforms es relativo al tamaño del cuadro en sí (el cuadro delimitador).

Si experimenta problemas de representación de fuente (fuente borrosa), la solución es agregar perspective(1px)a la transformdeclaración para que se convierta en:

transform: perspective(1px) translateY(-50%);

Vale la pena señalar que CSS transform es compatible con IE9 + .

2. Usando inline-block(pseudo-) elementos

En este método, tenemos dos inline-blockelementos hermanos que están alineados verticalmente en el medio por vertical-align: middledeclaración.

Uno de ellos tiene uno heightde 100%sus padres y el otro es nuestro elemento deseado cuyo que queríamos alinear en el medio.

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Finalmente, debemos usar uno de los métodos disponibles para eliminar la brecha entre los elementos de nivel en línea .

Hashem Qolami
fuente
Gracias por estos consejos útiles. Estaba funcionando para mi proyecto. Buen trabajo.
Sedat Kumcu
Para el primer valignelemento del método debe serdisplay: block
Oleg
transform: translateY(-50%);Nunca he visto esto antes, pero funciona a la perfección. Protector de la vida real.
Benny Bottema
55

utilizar este :

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

consulte este enlace: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

Điển Trương
fuente
¿Cómo no es esta la solución principal? ¡Tan fácil y funciona!
Mason
21
Tenga en cuenta que la heightpropiedad debe estar definida (en px, em, etc.) para que esto funcione.
Vaidas
¿Qué pasa si tengo múltiples divs dentro del padre? ¿No se colocarían todos uno encima del otro?
psykid
no funciona si hay un niño más en el mismo nivel con "centro absoluto"
Pascut
18

Usa flex blox en tu div posicionado para centrar su contenido.

Ver ejemplo https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}
Chris Aelbrecht
fuente
11

Centro vertical y horizontalmente:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}
Juan angel
fuente
3

Puedes usar display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>

G-Cyrillus
fuente
Gracias, su ejemplo funciona perfecto, sin embargo, .bfalta lo position: absolute;que es importante para mostrar otras cosas que no incluí para mantener el código más claro. Sé que no tiene sentido tener-celda de la tabla con posición absoluta, pero quizá no hay otro enfoque que permita retener position: absolute;en tanto .ay .bclases?
Vladimirs
Si a es una posición absoluta yb (el niño) le da su tamaño, b está en posición absoluta hacia el resto del contenido. a menos que se suponga que a permanecer sin tamaño no entiendo el propósito de absoluto dentro de absoluto?
G-Cyrillus
1

Aquí hay una manera simple de usar el objeto Top.

Por ejemplo: si el tamaño absoluto del elemento es 60px.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}
Sainul Abid
fuente
2
Usar calces útil, aunque esto debería ser top: calc(50% - 30px)para que realmente esté centrado.
brainbag
1

Una solución simple adicional

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}
Hicham
fuente
0

Verifique esta respuesta a un problema similar.

Esta es, con mucho, la forma más fácil que he encontrado.

https://stackoverflow.com/a/26079837/4593442

NOTA. Solía pantalla: -webkit-flex; en lugar de mostrar: flex;para probar dentro de safari.

NOTA. Solo soy un novato, comparto la ayuda de alguien que tiene una experiencia clara.

Whanau Paitai
fuente
0

Puede hacerlo utilizando display:table;en div padre y display: table-cell; vertical-align: middle;en div hijo

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>

Arindam Sarkar
fuente
3
es posible que su respuesta sea buena, pero puede mejorarla mucho agregando una descripción de lo que hace su código ...
DaFois