如何将绝对定位的元素居中对齐?

145

我正在尝试将两个画布叠在一起,并将它们创建成一个双层画布。

我在这里看到了一个示例:

<div style="position: relative;">
 <canvas id="layer1" width="100" height="100" 
   style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
 <canvas id="layer2" width="100" height="100" 
   style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>

但我希望将这两个画布都设置在屏幕的中央。如果我将 left 的值设为一个常量,当我改变屏幕方向时(比如在 iPad 上进行应用程序开发),画布就不会像在竖屏模式下一样始终处于屏幕中央。

<div align="center">

有人可以帮忙吗?

8个回答

298

如果同时将左和右设置为0,将左和右的margin设置为auto,则可以使绝对定位的元素居中。

position:absolute;
left:0;
right:0;
margin-left:auto;
margin-right:auto;

1
你不也需要给元素一个宽度吗? - Gabriel Florit
3
在这种情况下,我认为这并不必要。 - Andrew
唯一的问题是,如果没有固定的宽度,left:0;right:0;将使其填充容器而不是保持内容的宽度。 - user56reinstatemonica8
17
注意:仅当样式化元素具有给定的宽度(以像素或百分比表示)时才有效。 - Johnny Wong
1
@JohnnyWong 在段落元素上不指定宽度也可以正常工作。 - Pound Hash
显示剩余6条评论

148

如果您想要居中对齐一个元素,而不知道其宽度和高度,请使用以下方法:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

例子:

*{
  margin:0;
  padding:0;
}
section{
  background:red;
  height: 100vh;
  width: 100vw;
}
div{  
  width: 80vw;
  height: 80vh;
  background: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<section>
  <div>
    <h1>Popup</h1>
  </div>
</section>


1
这是一个好的技巧,但是你的方法有一个小细节需要注意。如果元素的宽度未设置,但它包含的内联内容超过了父元素宽度的50%,那么从left偏移的额外50%将推断出父元素的宽度,以避免溢出而将内容中断到下一行。但是通过在元素中设置 white-space 属性为 nowrap ,可以使用此方法使内容保持内联。在 此JSFiddle 中尝试一下。 - Felypp Oliveira

31

尝试这个方法,对我来说运行良好。

position: absolute;
left: 50%;
transform: translateX(-50%); 

23

要对具有已知宽度和高度的元素进行对齐,请使用以下解决方案:

position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;

对于宽度和高度未知的元素,请使用以下解决方案:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

18

你尝试使用了吗?:

left:50%;
top:50%;
margin-left:-[half the width] /* As pointed out on the comments by Chetan Sastry */

不确定它是否有效,但值得一试...

小修改:根据Chetan在评论中指出的,添加了margin-left部分...


是的,我已经尝试过了,但画布从中间“开始”,而不是在屏幕中间“放置”。有没有办法设置left:50%并再次将画布向左移动? - PaulLing
2
@PaulLing margin-left: <负宽度的一半> - Chetan S
1
Chetan 说的...比我快一步 :P 我会编辑我的回复,留给后人参考... - Deleteman
当iPad处于不同的方向时,屏幕的宽度会发生变化。 - PaulLing
他的意思是你画布元素宽度的一半,这将使其margin-left:-50px; - Deleteman

9

您只需确保父级<div>具有position:relative,并为要居中的元素设置高度和宽度即可。使用以下CSS:

.layer {
    width: 600px; height: 500px;
    display: block;
    position:absolute;
    top:0;
    left: 0;
    right:0;
    bottom: 0;
    margin:auto;
}

https://output.jsbin.com/aXEZUgEJ/1/


2
仅有的解决方案是使父元素设置为弹性布局,包括 flex-grow 和 overflow 属性。如果子元素图片比父元素大,则子元素的定位超出了父元素所在的框架范围。它似乎没有意识到父元素的宽度。现在已经修复了,非常感谢! - Kai

0
将父级 div 移动到中间
left: 50%;
top: 50%;
margin-left: -50px;

使用编程将第二层移动到另一层上方

position: relative;
left: -100px;

0

我想分享另一种方法,如果你从头开始构建东西可能会有用。

我曾经遇到过同样的问题,但当我使用上述方法时,它并没有起作用,因为每个标签都有一个类,在滚动时更改背景。

我在Javascript中创建了一个方法来计算元素和视口的大小,以便在视口大小更改时正确定位。

function setOnCenter(element) {
  let elm = $("#" + element);
  let currentlyViewportWidth = $(window).width();
  let unitWidthViewport = currentlyViewportWidth / 100;
  let pxSizeText = elm.outerWidth();
  let percentSizeText = pxSizeText / unitWidthViewport;
  let halfPercentSizeText = percentSizeText / 2;
  let result = 50 - halfPercentSizeText;

  elm.css({ width: pxSizeText + 'px', left: result + '%'});
}

window.addEventListener("resize", function (event) {
  setOnCenter('stuff_text');
})

当然,setOnCenter方法必须在文档准备就绪时执行。如果有需要改进的地方,我很乐意阅读它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接