Questa è una vecchia Q, ma una soluzione moderna senza flexbox o posizione assoluta funziona così.
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>
Quindi perché funziona?
A prima vista sembra che spostiamo di nuovo il 50% a destra e poi di nuovo il 50% a sinistra. Ciò comporterebbe uno spostamento zero, e allora?
Ma il 50% non è lo stesso, perché il contesto è importante. Se si utilizzano unità relative, un margine verrà calcolato come percentuale della larghezza dell'elemento principale , mentre la trasformazione sarà del 50% rispetto allo stesso elemento.
Abbiamo questa situazione prima di aggiungere il CSS
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E |
+-----------------------------------------------------------+
| |
+-------------------------------------------+
Con lo stile aggiunto margin-left: 50%
che abbiamo
+-------------------------------------------+
| Parent element P of E |
| |
| +-----------------------------------------------------------+
| | Element E |
| +-----------------------------------------------------------+
| | |
+---------------------|---------------------+
|========= a ========>|
a is 50% width of P
E i transform: translateX(-50%)
turni tornano a sinistra
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E | |
+-----------------------------------------------------------+
|<============ b ===========| |
| | |
+--------------------|----------------------+
|========= a =======>|
a is 50% width of P
b is 50% width of E
Sfortunatamente questo funziona solo per la centratura orizzontale poiché il calcolo della percentuale di margine è sempre relativo alla larghezza. Cioè non solo margin-left
e margin-right
, ma anche margin-top
e margin-bottom
sono calcolati rispetto alla larghezza.
La compatibilità del browser non dovrebbe essere un problema:
https://caniuse.com/#feat=transforms2d