To jest stara Q, ale nowoczesne rozwiązanie bez flexboksa lub absolutnej pozycji działa w ten sposób.
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>
Więc dlaczego to działa?
Na pierwszy rzut oka wydaje się, że przesuwamy się o 50% w prawo, a następnie ponownie o 50% w lewo. To spowodowałoby zerowe przesunięcie, więc co z tego?
Ale te 50% to nie to samo, ponieważ ważny jest kontekst. Jeśli użyjesz jednostek względnych, margines zostanie obliczony jako procent szerokości elementu nadrzędnego , podczas gdy transformacja będzie wynosić 50% w stosunku do tego samego elementu.
Mamy taką sytuację, zanim dodamy CSS
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E |
+-----------------------------------------------------------+
| |
+-------------------------------------------+
Z dodatkowym stylem, margin-left: 50%który mamy
+-------------------------------------------+
| Parent element P of E |
| |
| +-----------------------------------------------------------+
| | Element E |
| +-----------------------------------------------------------+
| | |
+---------------------|---------------------+
|========= a ========>|
a is 50% width of P
I transform: translateX(-50%)przesuwa się z powrotem w lewo
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E | |
+-----------------------------------------------------------+
|<============ b ===========| |
| | |
+--------------------|----------------------+
|========= a =======>|
a is 50% width of P
b is 50% width of E
Niestety działa to tylko w przypadku wyśrodkowania w poziomie, ponieważ obliczenie procentu marginesu jest zawsze odniesione do szerokości. To znaczy nie tylko margin-lefti margin-right, ale także margin-topi margin-bottomsą obliczane w odniesieniu do szerokości.
Zgodność z przeglądarkami nie powinna stanowić problemu:
https://caniuse.com/#feat=transforms2d