如何将宽度未知的绝对定位内容居中?

32

在有人问我为什么要这样做之前,让我告诉你原因。这样你们中的聪明人可以告诉我更好的方法...

我正在制作一个绘画浏览器,应该可以拉伸以填满页面,确切地说是屏幕高度的90%。我想淡入淡出地呈现绘画,并希望将它们居中在屏幕中间。

为了实现绘画的淡入淡出,我需要将其定位为“absolute”以防止它们叠加。这就产生了问题。自从我将它们设置为absolute后,我使用的每种居中包含div的方法都无效。

问题的一部分是我没有为绘画设置任何宽度,因为我希望它们动态调整大小以填充用户屏幕的90%。

我找到了数百种居中绝对内容的方法,并认为我可能需要缩小包含div的范围。然而,目前为止我还没有成功。

HTML-

<div id="viewer_div">
    <img src="" id="first" />
    <img id="second" class="hidden"/>
</div>
#viewer_div {
        width:1264px;
}


img {
    height:90%;
    display:block;
    margin-left: auto;
    margin-right:auto;
}

上述代码能够达到我想要的效果,但是无法让我对图片进行绝对定位。有没有人能够提供一种让我居中显示图片并且还能叠加淡入淡出的方法?


这真是一场磨难。我相信你知道如何使用固定宽度和绝对定位来完成它,对吧? - Purag
经过一些摸索,我可以保证你不能仅使用纯CSS和(x)HTML来完成这个任务。你需要JavaScript。这很不幸,因为这纯粹是关于显示的,而这正是CSS所用之处...如果你愿意,你可以fork我的fiddle http://jsfiddle.net/dekket/58BjM/。这就是我所能做到的,所以并没有太大的进展 :/ - InanisAtheos
感谢您的输入。Greg在下面展示了一种更简洁的方法来解决我的问题。 - goose
请看这里,已经有答案了 https://dev59.com/-GQn5IYBdhLWcg3wIkMF?answertab=active#tab-top - Shelby Carter
这是针对百分比宽度的情况,例如width: 90%;。而这种情况适用于未知或自动宽度,例如width: auto;,但不幸的是,除非设置了宽度(包括百分比),否则链接的回答会将其视为width: 100%。当然,您可以通过添加一个width: 100%的包装 div 并将这个内容居中放置在其中来解决这个问题... - user56reinstatemonica8
5个回答

66

对于浏览器支持,看起来这个在除了IE8和Opera Mini之外的所有浏览器中都可以工作:http://caniuse.com/#feat=transforms2d - user56reinstatemonica8
嗯...在iOS上它给我带来了麻烦。 - Costa Michailidis
这是你发现的另一个开发人员精心设计的令人满意的事情。谢谢! - Tadas V.

50
要么使用JavaScript来计算它的宽度并移动它,要么使用CSS hack将元素向右和向左移动50%,或者不要绝对定位它。
这个答案非常简短,但是言简意赅。如果您需要将某些内容居中(也就是说,您希望浏览器确定中心点并将其定位在那里),那么您不能使用绝对定位——因为这会使浏览器失去控制。
为了使绘画互相淡入淡出,我需要将它们定位为“absolute”,以防止它们堆叠在一起。
这就是你的问题所在。你错误地认为你需要绝对定位。
如果你遇到了在元素上方放置其他元素的问题,将图像包装在一个绝对定位的容器中,该容器的宽度为100%,并具有text-align: center
如果您确实需要使用绝对定位,可以使用以下技巧来实现所需的结果:
div {
    position: absolute;
    /* move the element half way across the screen */
    left: 50%;
    /* allow the width to be calculated dynamically */
    width: auto;
    /* then move the element back again using a transform */
    transform: translateX(-50%);
}

显然上面的代码味道很糟糕,但它可以在某些浏览器上工作。请注意:这个hack对其他开发者或其他浏览器(特别是IE或移动设备)可能不明显。


1
谢谢Greg,这个很有效。我觉得它一定比我想象的简单。 - goose
我选择了“这篇文章有帮助”,这是你的意思吗? - goose
啊,明白了。再次感谢,你不知道它给我带来了多少烦恼。 - goose
1
非常好的答案,这个方法非常有效。在我的代码中,我还给子元素(在这个问题中是图片)添加了“position: relative”和比它所覆盖的元素更高的z-index。这使得子元素(而不是其全宽的父元素)位于被定位元素的前面。 - Liran H
这个答案有用且有帮助,但最终是不正确的。较新的答案是正确的。 - Sauce
@Sauce 同意。自2012年以来,网络发生了很多变化。由于SO的投票,这不应该成为问题。 - Greg

7

作为对Samec答案的补充,你也可以使用下面的方法来使绝对定位元素在未知尺寸情况下垂直水平居中:

#viewer_div {
  position: relative;
}
#viewer_div img {
  position: absolute;
  left: 50%;
  top: 0%;
  transform: translate(-50%, 50%);
}

1

使用position: absolutewidth: unknown来居中div:

HTML:

<div class="center">
  <span></span>

  <div>
    content...
  </div>

</div>

CSS:

.center{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: auto auto;

  /* if you need the overflow */
  overflow: auto;
}

即使内容比屏幕宽,您也可以使用此解决方案,无需使用transform: translate(可能会模糊元素)。

工作原理:

Grid会在第一个auto前插入一个span,在第二个auto前插入一个div,最终得到:

span(0px) - auto - div(...px) - auto

auto的宽度将会相等。


同样适用于垂直居中,只需将 grid-template-columns 替换为 grid-template-rows 即可。

1

2021

使用网格插入的现代绝对居中内容方法

插入 CSS 属性是一个简写,对应于顶部、右侧、底部和/或左侧。MDN

#viewer_div {
  display: grid;
  place-items: center;
  position: absolute;
  inset: auto 0;
}

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

body {
  width: 100vw;
  height: 100vh;
  background-color: hsl(201, 27%, 10%);
  position: relative;
}

#viewer_div {
  display: grid;
  place-items: center;
  position: absolute;
  inset: auto 0;
  background-color: hsl(197, 7%, 21%);
  color: white;
}
<div id="viewer_div">
  <h1>Title 2021</h1>
  <img src="https://via.placeholder.com/180x100.png/09f/fff" id="first" />
</div>


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