Почему верхние 50% нуждаются в смещении смещения на 50%?
Вместо того, чтобы напрямую отвечать на этот вопрос, я собираюсь ответить на более общий вопрос:
Как работает привязка позиции в CSS?
Надеюсь, отвечая на вопрос в целом, вы поймете, что относится к вашему конкретному случаю.
Что вы подразумеваете под «привязкой позиции»?
Привязка позиции - это когда узел DOM позиционируется таким образом, что он «привязан» к своему родительскому элементу в данном измерении. Если верхний левый угол узла привязан к верхнему левому углу его родителя, узлы будут оставаться выровненными по своему верхнему левому углу, независимо от размера любого элемента.
Как выглядит привязка позиции?
Я собираюсь использовать шаблон для всех дальнейших примеров, поэтому важно понимать базовый пример.
.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>
В этом примере показан родительский элемент .containerс темно-красным, темно-желтым, темно-зеленым и темно-синим квадрантами для облегчения просмотра выравнивания. Внутри он содержит .boxкрасный, желтый, зеленый и синий квадранты, чтобы показать контраст для выравнивания.
Во всех дальнейших примерах этот шаблон будет уменьшен, чтобы соответствующий код выделялся больше.
Обратите внимание, что по умолчанию левый верхний угол дочернего элемента привязан к левому верхнему углу родительского элемента.
Родительская привязка
Родитель анкеровки можно регулировать с помощью top, bottom, leftи rightсвойства на дочерний элемент.
верхний
Использование topсвойства привяжет верхний край дочернего элемента к верхнему краю родителя.
Предполагая, bottomчто не установлено, top: 0не будет отображаться иначе, чем значение по умолчаниюtop: auto
.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;}
.box {
top: 0;
}
<div class="container">
<div class="box"></div>
</div>
Использование процента выравнивает верхний край дочернего элемента на заданный процент от верха родительского элемента.
top: 50% это середина родителя:
.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;}
.box {
top: 50%;
}
<div class="container">
<div class="box"></div>
</div>
top: 100% это нижняя часть родителя:
.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;}
.box {
top: 100%;
}
<div class="container">
<div class="box"></div>
</div>
Нижнее крепление
Нижняя привязка привяжет нижний край дочернего элемента к нижнему краю родительского элемента:
.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;}
.box {
bottom: 0;
}
<div class="container">
<div class="box"></div>
</div>
bottom: 50%это середина родителя, а потомок выровнен напротив top: 50%:
.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;}
.box {
bottom: 50%;
}
<div class="container">
<div class="box"></div>
</div>
bottom: 100% является вершиной родителя:
.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;}
.box {
bottom: 100%;
}
<div class="container">
<div class="box"></div>
</div>
Левый якорь
leftСвойство будет закрепить левый край ребенка к левому краю родителя.
Предполагая, rightчто не установлено, left: 0не будет отображаться иначе, чем значение по умолчанию left: auto.
left: 50% это середина родителя:
.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;}
.box {
left: 50%;
}
<div class="container">
<div class="box"></div>
</div>
left: 100% оставляет ребенка свисающим с правой стороны от родителя.
Правое крепление
rightСвойство будет закрепить правый край ребенка до правого края родителя:
right: 50%это середина родителя, а потомок выровнен напротив left: 50%:
.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;}
.box {
right: 50%;
}
<div class="container">
<div class="box"></div>
</div>
right: 100% оставляет ребенка свисающим с левой стороны от родителя.
Детское закрепление
Дочернюю привязку можно настроить независимо от родительской привязки, используя transformсвойство. В частности translate, функции translateX, и translateYбудут использоваться для изменения дочернего блока, чтобы использовать другое выравнивание.
Причина это работает, потому что проценты в translateстоимости по сравнению с ребенком , в то время как проценты в top, bottom, leftи rightсвойства являются по отношению к родителю .
Вертикальное выравнивание
Используя transform: translateY(), выравнивание ребенка может быть неровным вверх или вниз.
transform: translateY(0) оставит ребенка там, где он есть, и, как правило, не очень полезен.
Когда дочерний элемент привязан к верхней части родительского элемента, transform: translateY(-50%)он выровняет дочерний элемент по его центру:
.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;}
.box {
top: 0;
transform: translateY(-50%);
}
<div class="container">
<div class="box"></div>
</div>
Точно так же, когда дочерний элемент привязан к нижней части родителя, transform: translate(50%)он выровняет дочерний элемент по его центру:
.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;}
.box {
bottom: 0;
transform: translateY(50%);
}
<div class="container">
<div class="box"></div>
</div>
Это также означает, что top: 100%это эквивалентно bottom: 0; transform: translateY(100%):
.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;}
.box {
bottom: 0;
transform: translateY(100%);
}
<div class="container">
<div class="box"></div>
</div>
Горизонтальное выравнивание
Используя transform: translateX(), выравнивание ребенка может быть сдвинуто влево или вправо.
transform: translateX(0) оставит ребенка там, где он находится по умолчанию.
Когда дочерний элемент закреплен слева от родителя, transform: translateX(-50%)он выровняет дочерний элемент по его центру:
.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;}
.box {
transform: translateX(-50%);
}
<div class="container">
<div class="box"></div>
</div>
Точно так же, когда дочерний элемент закреплен справа от родителя, transform: translateX(50%)дочерний элемент будет выровнен по его центру:
.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;}
.box {
right: 0;
transform: translateX(50%);
}
<div class="container">
<div class="box"></div>
</div>
left: 100%эквивалентно right: 0; transform: translateX(100%).
Центральное крепление
Центрирование - это просто выравнивание дочернего элемента по центру родительского элемента, а затем установка исходной точки дочернего элемента на место.
.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;}
.box {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
<div class="container">
<div class="box"></div>
</div>
Из-за симметрии вы также можете использовать:
bottom: 50%;
right: 50%;
transform: translate(50%, 50%);