为什么translateY(-50%)需要居中顶部的元素:50%?

我可以看到这段代码在父元素中垂直alignment一个div:

.element { position: relative; top: 50%; transform: translateY(-50%); } 

问题是为什么? 我首先想到的是,父元素不仅仅包含视口。 我使我的父视口高度等于100vh和宽度100% 。 这没有用。 我仍然需要翻译或负边距抵消。 为什么当父元素设置为margin: 0;时需要负偏移量margin: 0; ? 这是因为我没有考虑到计算的保证金吗?

顶部: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%; 变换:平移Y(-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's 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> 

而其他人提供的答案是,-50将内部元素移回了一半,这是自己的高度,我认为这个小animation显示了移动到top: 50%; 首先是transform: translateY(-50%); 其次,可能会有帮助。

 @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> 
 position: relative; top: 50%; 

…将元素向下移动一个等于父元素高度一半的距离。

由于默认位置将内部元素的顶部放在外部元素的顶部 ,因此将内部元素的顶部放在外部元素的中间

 transform: translateY(-50%); 

这将内部元素移回内部元素高度的一半。

将它们组合起来将内部元素的中间放在父元素的中间

为什么最高的50%需要一个-50%的转换抵消?

我不是直接回答这个问题,而是回答更一般的问题:

在CSS中如何定位锚定工作?

希望在回答这个问题时,你会明白适用于你的具体情况的部分。


你是什​​么意思“位置锚定”?

位置锚定是指DOM节点以某种方式定位,以便在给定维度中将其“锚定”到其父项。 如果节点的左上angular锚定在其父元素的左上angular,则无论元素的大小如何,节点都将保持其左上angularalignment。

什么位置锚定看起来像?

我将为所有其他示例使用模板,因此了解基本示例很重要。

 .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>