CSS 为什么“left: 50%, transform: translateX(-50%)”水平居中一个元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25982135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:36:45  来源:igfitidea点击:

Why does "left: 50%, transform: translateX(-50%)" horizontally center an element?

css

提问by Sean Anderson

I recently refactored some of my CSS and was pleasantly surprised to find an easier way to horizontally align my absolutely positioned element:

我最近重构了我的一些 CSS,并惊喜地发现了一种更简单的方法来水平对齐我的绝对定位元素:

.prompt-panel {
    left: 50%;
    transform: translateX(-50%);
}

This works great! Even if my element's width is auto. However, I do not understand what's going on to make this actually work. My assumption was that translateX was just a modern, more performant means of moving an element around, but that does not appear to be the case.

这很好用!即使我的元素的宽度是自动的。但是,我不明白是怎么回事才能使它真正起作用。我的假设是 translateX 只是一种现代的、更高效的移动元素的方法,但事实并非如此。

Shouldn't these two values cancel each other out? Furthermore, why does

这两个值不应该相互抵消吗?此外,为什么

.prompt-panel {
    left: -50%;
    transform: translateX(50%);
}

not show the same result as the first code snippet?

不显示与第一个代码片段相同的结果?

回答by Dark Falcon

The CSS leftproperty is based on the size of the parent element. The transformproperty is based on the size of the target element.

CSSleft属性基于父元素的大小。该transform属性基于目标元素的大小。

Name: transform

Percentages: refer to the size of bounding box [of the element to which the style is applied]

名称:变换

百分比:指的是[应用样式的元素的]边界框的大小

http://www.w3.org/TR/css3-transforms/#transform-property

http://www.w3.org/TR/css3-transforms/#transform-property

'top'

Percentages: refer to height of containing block

'最佳'

百分比:指包含块的高度

http://www.w3.org/TR/CSS2/visuren.html#position-props

http://www.w3.org/TR/CSS2/visuren.html#position-props

If the parent is 1000px wide and the child is 100px, The browser would interpret the rules in your question as:

如果父级宽度为 1000 像素,子级宽度为 100 像素,则浏览器会将您问题中的规则解释为:

Example 1:

示例 1:

.prompt-panel {
    left: 500px;
    transform: translateX(-50px);
}

Example 2:

示例 2:

.prompt-panel {
    left: -500px;
    transform: translateX(50px);
}

回答by Giannis Grivas

left 50%will move the element exactly at the center of the main container where this element belongs! BUT translateX(50%)will move the element right exactly to 50% of its width,and NOTat the center of the whole Container element!

left 50%将元素准确地移动到该元素所属的主容器的中心!但是translateX(50%)会将元素准确地移动到其宽度的 50%,而 不是整个 Container 元素的中心!

Thats the main difference between them and thats why this example has differences!

这就是它们之间的主要区别,这就是为什么这个例子有不同之处!

A general example to clear this out: (fiddle here):

清除此问题的一般示例:(此处小提琴)

#pos
{
    border:1px solid black;
    position:absolute;
    width:200px;
    height:150px;
}
#pos-2
{
    border:1px solid black;
    position:absolute;
    width:auto;
    height:150px;
}
.prompt-panel {
 position:absolute;
}

.prompt-panel1 {
    position:absolute;
    left: 50%;
}
.prompt-panel2 {
    position:absolute;
    left: -50%;   
}
.prompt-panel3 {  
     position:absolute;
     transform: translateX(-50%);
}

.prompt-panel4 {  
     position:absolute;
     transform: translateX(50%);
}
.prompt-panel5 {  
     position:absolute;
     left: 50%;
     transform: translateX(-50%);
}
.prompt-panel6 {  
     left: -50%;
      transform: translateX(50%);
}
#pos-auto
{
    position:absolute;
}
<div><b> With fixed width 200px</b></div>
<br/>
<div id="pos">
<div class="prompt-panel">panel</div>
<br/>
<div class="prompt-panel1">panel1</div>
<br/>
<div class="prompt-panel2">panel2</div>
<br/>
<div class="prompt-panel3">panel3</div>
<br/>
<div class="prompt-panel4">panel4</div>
<br/>
<div class="prompt-panel5">panel5</div>
<br/>
<div class="prompt-panel6">panel6</div>
</div>
<br/><br/><br/> <br/><br/><br/><br/><br/><br/>
<div><b> With fixed width auto</b></div>
<br/>
<div id="pos-2">
<div class="prompt-panel">panel</div>
<br/>
<div class="prompt-panel1">panel1</div>
<br/>
<div class="prompt-panel2">panel2</div>
<br/>
<div class="prompt-panel3">panel3</div>
<br/>
<div class="prompt-panel4">panel4</div>
<br/>
<div class="prompt-panel5">panel5</div>
<br/>
<div class="prompt-panel6">panel6</div>
</div>