Это старый Q, но современное решение без flexbox или абсолютного положения работает следующим образом.
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>
Так почему же это работает?
На первый взгляд кажется, что мы сдвигаемся на 50% вправо, а затем снова на 50% влево. Это приведет к смещению нуля, и что?
Но 50% - это не одно и то же, потому что важен контекст. Если вы используете относительные единицы измерения, поле будет рассчитываться в процентах от ширины родительского элемента, а преобразование будет на 50% относительно того же элемента.
У нас есть такая ситуация, прежде чем мы добавим CSS
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E |
+-----------------------------------------------------------+
| |
+-------------------------------------------+
С добавленным стилем margin-left: 50%
мы имеем
+-------------------------------------------+
| Parent element P of E |
| |
| +-----------------------------------------------------------+
| | Element E |
| +-----------------------------------------------------------+
| | |
+---------------------|---------------------+
|========= a ========>|
a is 50% width of P
И transform: translateX(-50%)
сдвиг назад влево
+-------------------------------------------+
| Parent element P of E |
| |
+-----------------------------------------------------------+
| Element E | |
+-----------------------------------------------------------+
|<============ b ===========| |
| | |
+--------------------|----------------------+
|========= a =======>|
a is 50% width of P
b is 50% width of E
К сожалению, это работает только для горизонтального центрирования, так как процентное соотношение маржи всегда зависит от ширины. Т.е. не только margin-left
и margin-right
, но также margin-top
и margin-bottom
рассчитываются по ширине.
Совместимость браузера не должна быть проблемой:
https://caniuse.com/#feat=transforms2d