CSS:如何在不指定高度的情况下将两个元素彼此重叠放置?


96

我有两个DIV,我需要将它们精确地放在彼此的顶部。但是,当我这样做时,格式就搞砸了,因为包含的DIV的行为就像没有高度。我认为这是预期的行为,position:absolute但我需要找到一种方法来将这两个元素彼此重叠放置,并使容器随着内容的延伸而伸展:

的左上边缘.layer2应与的左上边缘完全对齐layer1

<!-- HTML -->
<div class="container_row">
    <div class="layer1">
        Lorem ipsum...
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>

/* CSS */
.container_row {}

.layer1 {
    position:absolute;
    z-index: 1;
}

.layer2 {
    position:absolute;
    z-index: 2;
}

1
position: absolute当时使用的样式不太正确。
BoltClock

是的,position:absolute感觉不对。什么是正确的风格?
安德鲁

做的.layer1.layer2元素具有已知大小?
亩太短了,

不,它们的尺寸也未知。
安德鲁

Answers:


81

首先,您确实应该将位置包含在绝对定位的元素上,否则您将遇到奇怪而令人困惑的行为;您可能想将top: 0; left: 0两个绝对定位的元素都添加到CSS中。你也想拥有position: relative.container_row,如果你想绝对定位的元素被定位相对于他们的父母,而不是文档的身体

如果元素具有“位置:绝对”,则包含块由最接近的祖先建立,其“位置”为“绝对”,“相对”或“固定” ...

您的问题是position: absolute从正常流程删除了元素

它从正常流中完全删除(它对以后的同级没有影响)。绝对定位的框为正常流子和绝对(但不固定)定位的后代建立了一个新的容纳块。但是,绝对定位的元素的内容不会在其他任何框周围流动。

这意味着绝对定位的元素不会对其父元素的大小产生任何影响,并且第一个元素的<div class="container_row">高度将为零。

因此,除非您知道它们的高度(或者等效地,您可以指定它们的高度),否则您无法对绝对定位的元素进行处理。如果您可以指定高度,则可以在上放置相同的高度,.container_row然后所有内容都会对齐;您也可以放margin-top第二个.container_row为绝对定位的元素留出空间。例如:

http://jsfiddle.net/ambiguous/zVBDc/


好答案,谢谢!我想我可能需要使用javascript动态找出高度。我只是希望不必这么做。= [
安德鲁(Andrew)

@Andrew:是的,欢迎使用CSS的垂直大小/位置/对齐系统:如果您不知道具体的尺寸,通常就不走运了。水平的东西更容易处理,但是大多数仍然闻起来像是由“固定版面印刷人员”而不是“动态版面印刷人员”设计的。
亩太短了,

1
没有position: absolute必要的。请检查:stackoverflow.com/a/51949049/1736186
而不是

63

实际上,这可以在没有位置absolute且没有指定任何高度的情况下进行。您需要做的只是display: grid在父元素上使用并将子代放置在同一行和同一列中。

请根据您的HTML查看以下示例。我只添加了<span>一些颜色,所以您可以看到结果。

您还可以轻松地更改z-index每个后代元素,以操纵其可见性(应将其放在顶部)。

.container_row{
  display: grid;
}

.layer1, .layer2{
  grid-column: 1;
  grid-row: 1;
}

.layer1 span{
  color: #fff;
  background: #000cf6;
}

.layer2{
  background: rgba(255, 0, 0, 0.4);
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...<br>Test test</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


11
真好 但是,公平地说,display: grid七年前不存在:)
mu太短了

下面还有另一个答案,由@Cornelius编写。他使用flex,如今具有更好的浏览器支持。
Oleg Cherr

20

很好的答案,“亩太短了”。我一直在寻找完全相同的东西,在阅读您的帖子后,我找到了适合我的问题的解决方案。

我当时有两个大小完全相同的元素,想要堆叠它们。因为每个都有相同的尺寸,所以我能做的就是

position: absolute;
top: 0px;
left: 0px;

仅在最后一个元素上。这样,第一个元素正确插入,“推”父母的高度,第二个元素放置在顶部。

希望这有助于其他人尝试堆叠高度相同(未知)的2个以上元素。


1
注意:使用这种方法,您仍然需要知道哪个元素是较高的元素,以便您可以position: aboslute选择另一个
Alec

10

这是另一个使用display:flex而不是position:absolute或display:grid的解决方案。

.container_row{
  display: flex;
}

.layer1 {
  width: 100%;
  background-color: rgba(255,0,0,0.5);  // red
}

.layer2{
  width: 100%;
  margin-left: -100%;
  background-color: rgba(0,0,255,0.5);  // blue
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


很好的解决方案。谢谢!
Oleg Cherr

5

我必须设定

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

.ElementOne, .Container ,.ElementTwo{
    width: 283px;
    height: 71px;
}

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

Use可以使用z-index来设置哪个位于最前面。


4

这是一些可重用的css,它将不使用而保留每个元素的高度position: absolute

.stack {
    display: grid;
}
.stack > * {
    grid-row: 1;
    grid-column: 1;
}

您的第一个元素stack是背景,第二个元素是前景。


2

由于绝对定位,因此从文档流送位置移除元素:绝对不是适合此工作的工具。根据您要创建的确切布局,您可以使用负边距,position:relative甚至transform:translation来成功。向我们展示您想做什么的样本,我们可以为您提供更好的帮助。


1

当然,问题只在于恢复身高。但是如果您不提前知道身高怎么办?好吧,如果您知道要为容器提供什么宽高比(并使其保持响应),则可以通过向容器的另一个子项中添加填充(以百分比表示)来恢复身高。

您甚至可以div向容器中添加一个虚拟对象,并进行一些设置,例如padding-top: 56.25%,使虚拟元素的高度与容器的宽度成比例。这将推出容器并赋予其长宽比,在这种情况下为16:9(56.25%)。

填充和边距使用宽度的百分比,这实际上是诀窍。


0

经过大量测试,我已经证实原来的问题已经正确;缺少几个设置:

  • container_row必须有position: relative;
  • 孩子们(...),必须有 position: absolute; left:0;
  • 为确保子项(...)彼此完全对齐, container_row应具有其他样式:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; 也可以提供帮助。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.