Для чего нужен перевод (-50%) для центрирования элемента, который находится сверху: 50%?
Я вижу, что этот код работает, чтобы выровнять div по вертикали внутри его родительского элемента:
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
Вопрос в том, почему? Моя первая мысль заключалась в том, что родительский элемент охватывает больше, чем область просмотра. Я сделал родительскую высоту просмотра равным 100vh
и ширину 100%
. Это не сработало. Мне все еще нужен перевод или отрицательное смещение. Зачем мне нужно отрицательное смещение, если для родительского элемента установлено значение margin: 0;
? Это из-за вычисленной разницы, которую я не учитываю?
Ответы
Ответ 1
top: 0 (по умолчанию)
По умолчанию ваш элемент находится в верхней части страницы, а верхняя часть элемента равна 0:
--------Top of Page--------
{element}
------Middle of Page------
------Bottom of Page------
верх: 50%
Когда вы перемещаете его на 50% высоты (50% от всей страницы), верхняя часть элемента находится на отметке 50%, то есть элемент начинается с 50% и не центрируется.
--------Top of Page--------
------Middle of Page------
{element}
------Bottom of Page------
верх: 50%; преобразования: translateY (-50%);
Когда вершина элемента находится на полпути, мы можем переместить элемент на половину своей высоты, чтобы сосредоточить его на всей странице. То, что делает transform:translateY(-50%);
:
--------Top of Page--------
{element}-Middle of Page---
------Bottom of Page------
Но почему мы не можем просто сказать top: 25%
или что-то в этом роде? Я сделал быстрый фрагмент, чтобы показать вам разницу с этой реализацией:
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 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>
Ответ 2
В то время как другие ответили, что -50 перемещает внутренний элемент на половину собственной высоты, я подумал, что эта небольшая анимация, показывающая движение до top: 50%;
, а затем transform: translateY(-50%);
second, может помочь.
@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>
Ответ 3
position: relative;
top: 50%;
... перемещает элемент на расстояние, равное половине высоты родителя.
Поскольку позиция по умолчанию помещает верхнюю часть внутреннего элемента в верхнюю часть внешнего элемента, это помещает верхнюю часть внутреннего элемента в середину внешнего элемента.
transform: translateY(-50%);
Это перемещает внутренний элемент обратно на половину высоты внутреннего элемента.
Сочетание их ставит середину внутреннего элемента в середину родительского элемента.
Ответ 4
Почему для 50% -ного значения требуется сдвиг перевода -50%?
Вместо того, чтобы напрямую отвечать на этот вопрос, я собираюсь ответить на более общий вопрос:
Как работает привязка позиции в CSS?
Надеюсь, что, отвечая на вопрос в целом, вы поймете те части, которые применимы к вашему конкретному случаю.
Что вы подразумеваете под "фиксацией позиции"?
Закрепление позиций - это когда DOM node позиционируется таким образом, что он привязан к его родительскому элементу в данном измерении. Если левая верхняя часть node привязана к верхнему левому краю своего родителя, узлы останутся выровненными в верхнем левом углу независимо от размера любого элемента.
Как выглядит привязка позиции?
Я собираюсь использовать шаблон для всех дальнейших примеров, поэтому важно понять базовый пример.
.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>