¿Por qué se necesita translateY (-50%) para centrar un elemento que está en la parte superior: 50%?

83

Puedo ver que este código funciona para alinear un div verticalmente dentro de su elemento padre:

.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

La pregunta es ¿por qué? Mi primer pensamiento fue que el elemento padre abarcaba más que la ventana gráfica. Hice que la altura 100vhy el ancho de la ventana gráfica de mi padre fueran iguales 100%. Eso no funcionó. Todavía necesitaba la traducción o una compensación de margen negativo. ¿Por qué necesito un desplazamiento negativo cuando el elemento principal está configurado en margin: 0;? ¿Es por un margen calculado que no estoy tomando en cuenta?

ltrainpr
fuente
top es relativo al padre, transform es relativo a sí mismo. hacer los cálculos, podrás cómo esto da lugar a centrar el elemento
njzk2

Respuestas:

157

top: 0 (predeterminado)

De forma predeterminada, su elemento está en la parte superior de la página y la parte superior del elemento está en 0:

--------Top of Page--------
{element}


------Middle of  Page------



------Bottom of  Page------

arriba: 50%

Cuando lo mueve hacia abajo en un 50% de altura (50% de toda la página), la parte superior del elemento está en la marca del 50%, lo que significa que el elemento comienza en el 50% y no está centrado.

--------Top of Page--------



------Middle of  Page------
{element}


------Bottom of  Page------

arriba: 50%; transformar: translateY (-50%);

Cuando la parte superior del elemento está a la mitad, podemos mover el elemento hacia arriba a la mitad de su propia altura para centrarlo con toda la página. Eso es exactamente lo que transform:translateY(-50%);hace:

--------Top of Page--------



{element}-Middle of Page---



------Bottom of  Page------

Pero, ¿por qué no podemos simplemente decir top: 25%algo así? Hice un fragmento rápido para mostrarle la diferencia con esa implementación:

body {
  margin: 0;
}
.row {
  display: flex;
  justify-content: space-between;
}
.container {
  display: inline-block;
  margin: 5px;
  width: 200px;
  height: 200px;
  background: tomato;
}
.inner {
  position: relative;
  margin: 0 auto;
  height: 50%;
  width: 50%;
  background: #FFC4BA;
}
.inner.small {
  width: 25%;
  height: 25%;
}
.inner.big {
  width: 75%;
  height: 75%;
}
.percent {
  top: 25%
}
.transform {
  top: 50%;
  transform: translateY(-50%);
}
<b>First row </b>looks alright, but that's because the gap works well with the 25%
<div class="row">
  <div class="container">
    <div class="inner percent"></div>
  </div>
  <div class="container">
    <div class="inner transform"></div>
  </div>
</div>
<b>Second row </b>made the center square a bit smaller, and the 25% now is too high as we'd expect the bottom of the element to reach 75%
<div class="row">
  <div class="container">
    <div class="small inner percent"></div>
  </div>
  <div class="container">
    <div class="small inner transform"></div>
  </div>
</div>
<b>Third row </b>now I've made the center box big and it ends lower than 75% making 25% start too late
<div class="row">
  <div class="container">
    <div class="big inner percent"></div>
  </div>
  <div class="container">
    <div class="big inner transform"></div>
  </div>
</div>

Andrew Bone
fuente
Entiendo parcialmente lo que estás diciendo. Tengo preguntas de seguimiento que agregué en los comentarios de la respuesta de @Quentin.
ltrainpr
Me gusta la representación visual de lo que está sucediendo. Gracias.
ltrainpr
2
TL; DR topaplica 50% de la altura de la página / contenedor, transform: translateYaplica -50% de la altura del propio elemento.
aldo.roman.nurena
73

Mientras que otros han dado la respuesta de que el -50 mueve el elemento interno hacia la mitad de su propia altura, pensé que esta pequeña animación que muestra el movimiento top: 50%;primero, seguido del transform: translateY(-50%);segundo, podría ayudar.

@keyframes centerMe {
  0% { top: 0%; transform: translateY(0%); }
  50% { top: 50%; transform: translateY(0%); }
  100% { top: 50%; transform: translateY(-50%); }
}

.outer {
  position: relative;
  border: solid 1px;
  height: 200px;
  width: 200px;
}

.inner {
  position: relative;
  background-color: red;
  height: 50px; width: 50px;
  margin: auto;
  animation: centerMe 5s;
  animation-fill-mode: forwards;
}

/* rules for example */
.hline,.vline{background:#000;position:absolute}.vline{height:100%;width:1px;left:calc(50% - .5px);top:0}.hline{width:100%;height:1px;top:calc(50% - .5px)}
<div class="outer">
  <div class="hline"></div>
  <div class="vline"></div>
  <div class="inner"></div>  
</div>

JonSG
fuente
2
¡Disparar! Esta es una animación visual impresionante. Es por eso que me gusta más el front-end que la programación back-end. Gracias.
ltrainpr
1
@Itrainpr ¡Siempre hay una recompensa! :-)
wizzwizz4
29
position: relative;
top: 50%;

... mueve el elemento hacia abajo una distancia igual a la mitad de la altura del padre.

Dado que la posición predeterminada coloca la parte superior del elemento interior en la parte superior del elemento exterior, esto coloca la parte superior del elemento interior en la medio del elemento exterior.

transform: translateY(-50%);

Esto mueve el elemento interior hacia atrás una distancia de la mitad de la altura del elemento interior .

Combinarlos coloca el medio del elemento interno en el medio del elemento principal.

Quentin
fuente
Si entiendo lo que está diciendo, la parte superior del elemento secundario se mueve por debajo de la mitad del elemento principal. Luego, estamos moviendo el elemento secundario hacia atrás a la mitad de la distancia del elemento secundario, lo que equivale al 25% del elemento principal. ¿Es eso correcto? Si es así, ¿por qué no simplemente bajarlo haciendo top: 25%? Si no es así, ¿en qué se top: 25%diferencia de este trabajo?
ltrainpr
3
"Entonces estamos moviendo el elemento secundario hacia atrás la mitad de la distancia del elemento secundario, lo que equivale al 25% del elemento principal. ¿Es eso correcto?" - Sería correcto si (y solo si) el elemento secundario tuviera height: 50%(o equivalente), pero nada en el código de la pregunta sugiere que se conozca la altura del niño.
Quentin
@ltrainpr, ¿tiene sentido? ¿Entiendes por qué no puedes decir el 25% ahora?
Andrew Bone
1
@AndrewBone Sí, lo entiendo ahora. Gracias por tomarse el tiempo de explicarlo.
ltrainpr
¿No es el posicionamiento predeterminado en la parte superior del elemento exterior solo cuando es el primer hijo position: absolute(ocupa espacio), o cuando se usa (asumiendo que el elemento exterior está posicionado él mismo)?
Bergi
11

¿Por qué el 50% superior necesita una compensación de conversión de -50%?

En lugar de responder esta pregunta directamente, responderé la pregunta más general de:

¿Cómo funciona el anclaje de posición en CSS?

Con suerte, al responder la pregunta en general, comprenderá las partes que se aplican a su caso específico.


¿Qué quieres decir con "anclaje de posición"?

El anclaje de posición es cuando un nodo DOM se coloca de una manera que está "anclado" a su padre en una dimensión determinada. Si la parte superior izquierda del nodo está anclada a la parte superior izquierda de su principal, los nodos permanecerán alineados en su esquina superior izquierda, sin importar el tamaño de cualquiera de los elementos.

¿Cómo se ve el anclaje de posición?

Voy a usar una plantilla para todos los ejemplos adicionales, por lo que es importante comprender el ejemplo base.

.container {
  background-image: -webkit-linear-gradient(left, darkred 0, darkred 50%, goldenrod 50%, goldenrod 100%), -webkit-linear-gradient(left, darkgreen 0, darkgreen 50%, darkblue 50%, darkblue 100%);
  background-image: linear-gradient(to right, darkred 0, darkred 50%, goldenrod 50%, goldenrod 100%), linear-gradient(to right, darkgreen 0, darkgreen 50%, darkblue 50%, darkblue 100%);
  background-position: top, bottom;
  background-repeat: no-repeat;
  background-size: 100% 50.1%, 100% 50.1%;
  height: 70vh;
  margin: 15vh 15vw;
  position: relative;
  width: 70vw;
}
.box {
  background-image: -webkit-linear-gradient(left, red 0, red 50%, yellow 50%, yellow 100%), -webkit-linear-gradient(left, green 0, green 50%, blue 50%, blue 100%);
  background-image: linear-gradient(to right, red 0, red 50%, yellow 50%, yellow 100%), linear-gradient(to right, green 0, green 50%, blue 50%, blue 100%);
  background-position: top, bottom;
  background-repeat: no-repeat;
  background-size: 100% 50.1%, 100% 50.1%;
  height: 50vmin;
  position: absolute;
  width: 50vmin;
}
<div class="container">
  <div class="box"></div>
</div>

Este ejemplo muestra un padre .containerque tiene cuadrantes rojo oscuro, amarillo oscuro, verde oscuro y azul oscuro para ver fácilmente la alineación. En el interior, contiene un .boxcuadrante rojo, amarillo, verde y azul para mostrar el contraste de la alineación.

Todos los ejemplos adicionales tendrán este texto estándar reducido para que el código relevante se destaque más.

Tenga en cuenta que, de forma predeterminada, la parte superior izquierda del hijo está anclada a la parte superior izquierda del padre.

Anclaje de los padres

Anclaje de Padres se puede ajustar mediante el uso de los top, bottom, left, y rightpropiedades en el elemento secundario.

Parte superior

Utilizando el top propiedad anclará el borde superior del niño al borde superior del padre.

Suponiendo bottomque no está configurado, top: 0no se mostrará de manera diferente a la predeterminada detop: auto

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  top: 0;
}
<div class="container">
  <div class="box"></div>
</div>

El uso de un porcentaje alineará el borde superior del niño en el porcentaje dado desde la parte superior del padre.

top: 50% es el medio del padre:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  top: 50%;
}
<div class="container">
  <div class="box"></div>
</div>

top: 100% es la parte inferior del padre:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  top: 100%;
}
<div class="container">
  <div class="box"></div>
</div>

Anclaje inferior

El anclaje inferior anclará el borde inferior del niño al borde inferior del padre:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  bottom: 0;
}
<div class="container">
  <div class="box"></div>
</div>

bottom: 50%es el medio del padre, con el hijo alineado frente a top: 50%:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  bottom: 50%;
}
<div class="container">
  <div class="box"></div>
</div>

bottom: 100% es la parte superior del padre:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  bottom: 100%;
}
<div class="container">
  <div class="box"></div>
</div>

Anclaje a la izquierda

La leftpropiedad anclará el borde izquierdo del hijo al borde izquierdo del padre.

Suponiendo rightque no está configurado, left: 0no se mostrará de manera diferente a la predeterminada de left: auto.

left: 50% es el medio del padre:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  left: 50%;
}
<div class="container">
  <div class="box"></div>
</div>

left: 100% deja al niño colgando del lado derecho del padre.

Anclaje correcto

La rightpropiedad anclará el borde derecho del niño al borde derecho del padre:

right: 50%es el medio del padre, con el hijo alineado frente a left: 50%:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  right: 50%;
}
<div class="container">
  <div class="box"></div>
</div>

right: 100% deja al niño colgando del lado izquierdo del padre.

Anclaje infantil

El anclaje infantil se puede ajustar independientemente del anclaje principal haciendo uso de la transformpropiedad. Específicamente, el translate, translateXytranslateY funciones se usarán para resaltar el cuadro secundario y usar una alineación diferente.

La razón por la que esto funciona es porque los porcentajes en el translatevalor son en relación con el niño , mientras que los porcentajes en top, bottom, left, y rightpropiedades son en relación con el padre .

Alineamiento vertical

Usando transform: translateY(), la alineación del niño se puede subir o bajar.

transform: translateY(0) dejará al niño donde está, y generalmente no es muy útil.

Cuando el niño está anclado a la parte superior del padre, transform: translateY(-50%)alineará al niño en su centro:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  top: 0;
  transform: translateY(-50%);
}
<div class="container">
  <div class="box"></div>
</div>

Asimismo, cuando el niño está anclado a la parte inferior del padre, transform: translate(50%)alineará al niño en su centro:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  bottom: 0;
  transform: translateY(50%);
}
<div class="container">
  <div class="box"></div>
</div>

Esto también significa que top: 100%es equivalente a bottom: 0; transform: translateY(100%):

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  bottom: 0;
  transform: translateY(100%);
}
<div class="container">
  <div class="box"></div>
</div>

Alineación horizontal

Usando transform: translateX(), la alineación del niño se puede golpear hacia la izquierda o hacia la derecha.

transform: translateX(0) dejará al niño donde está por defecto.

Cuando el niño está anclado a la izquierda del padre, transform: translateX(-50%)alineará al niño en su centro:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  transform: translateX(-50%);
}
<div class="container">
  <div class="box"></div>
</div>

Asimismo, cuando el niño está anclado a la derecha del padre, transform: translateX(50%)alineará al niño en su centro:

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  right: 0;
  transform: translateX(50%);
}
<div class="container">
  <div class="box"></div>
</div>

left: 100%es equivalente a right: 0; transform: translateX(100%).

Anclaje central

Centrar es solo una cuestión de alinear al niño con el centro del padre y luego colocar el origen del niño en su lugar.

.container{background-image:-webkit-linear-gradient(left,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),-webkit-linear-gradient(left,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-image:linear-gradient(to right,darkred 0,darkred 50%,goldenrod 50%,goldenrod 100%),linear-gradient(to right,darkgreen 0,darkgreen 50%,darkblue 50%,darkblue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:70vh;margin:15vh 15vw;position:relative;width:70vw;}.box{background-image:-webkit-linear-gradient(left,red 0,red 50%,yellow 50%,yellow 100%),-webkit-linear-gradient(left,green 0,green 50%,blue 50%,blue 100%);background-image:linear-gradient(to right,red 0,red 50%,yellow 50%,yellow 100%),linear-gradient(to right,green 0,green 50%,blue 50%,blue 100%);background-position:top,bottom;background-repeat:no-repeat;background-size:100% 50.1%,100% 50.1%;height:50vmin;position:absolute;width:50vmin;}

.box {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
<div class="container">
  <div class="box"></div>
</div>

Debido a la simetría, también podrías usar:

bottom: 50%;
right: 50%;
transform: translate(50%, 50%);
zzzzBov
fuente
2
Gran respuesta más general sobre el posicionamiento. Quizás esta sería una excelente manera de reforzar la documentación de posicionamiento CSS. Echa un vistazo a la edición de stackoverflow.com/documentation/css/935/…
JonSG
@zzzzBov Si toma su contenido y lo invierte, presentando el contenido más relevante primero y luego expandiéndolo / explicándolo gradualmente a lo más general, sería mucho más motivador, ya que cada lector podría detenerse temprano y aún así tener una mejor comprensión del contexto de la pregunta.
jpaugh
@jpaugh, sí, todavía se necesitan algunas mejoras aquí, una de las cuales es reducir los ejemplos para que sean menos, menos repetitivos y con mejor interactividad. Gracias por sus comentarios y veré qué puedo hacer para incorporarlo en mi próximo borrador.
zzzzBov
¡Genial gracias! Encuentro que, al igual que con el código, la escritura prefiere al lector o al escritor, pero no ambos. ¡Salud!
jpaugh