Esta es una antigua Q, pero una solución moderna sin flexbox o posición absoluta funciona así.
margin-left: 50%;
transform: translateX(-50%);
.outer {
border: 1px solid green;
margin: 20px auto;
width: 20%;
padding: 10px 0;
/* overflow: hidden; */
}
.inner {
width: 150%;
background-color: gold;
/* Set left edge of inner element to 50% of the parent element */
margin-left: 50%;
/* Move to the left by 50% of own width */
transform: translateX(-50%);
}
<div class="outer">
<div class="inner">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos exercitationem error nemo amet cum quia eaque alias nihil, similique laboriosam enim expedita fugit neque earum et esse ad, dolores sapiente sit cumque vero odit! Ullam corrupti iure eum similique magnam voluptatum ipsam. Maxime ad cumque ut atque suscipit enim quidem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi impedit esse modi, porro quibusdam voluptate dolores molestias, sit dolorum veritatis laudantium rem, labore et nobis ratione. Ipsum, aliquid totam repellendus non fugiat id magni voluptate, doloribus tenetur illo mollitia. Voluptatum.</div>
</div>
Entonces, ¿por qué funciona?
A primera vista parece que cambiamos 50% a la derecha y luego 50% a la izquierda nuevamente. Eso resultaría en un cambio a cero, ¿y qué?
Pero el 50% no es lo mismo, porque el contexto es importante. Si utiliza unidades relativas, se calculará un margen como porcentaje del ancho del elemento principal , mientras que la transformación será del 50% en relación con el mismo elemento.
Tenemos esta situación antes de agregar el CSS
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E |
+-----------------------------------------------------------+
| |
+-------------------------------------------+
Con el estilo agregado margin-left: 50%
tenemos
+-------------------------------------------+
| Parent element P of E |
| |
| +-----------------------------------------------------------+
| | Element E |
| +-----------------------------------------------------------+
| | |
+---------------------|---------------------+
|========= a ========>|
a is 50% width of P
Y los transform: translateX(-50%)
cambios de vuelta a la izquierda
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E | |
+-----------------------------------------------------------+
|<============ b ===========| |
| | |
+--------------------|----------------------+
|========= a =======>|
a is 50% width of P
b is 50% width of E
Desafortunadamente, esto solo funciona para el centrado horizontal, ya que el cálculo del porcentaje de margen siempre es relativo al ancho. Es decir, no solo margin-left
y margin-right
, sino también margin-top
ymargin-bottom
se calculan con respecto al ancho.
La compatibilidad del navegador no debería ser un problema:
https://caniuse.com/#feat=transforms2d