使 div 充满父元素剩余空间

13

我需要一些帮助来定位div。HTML结构如下:

<div class="container">
    <div class="item">
        <div class="left">
            lorem lorem
        </div>
        <div class="right">
            <p>right</p>
            <p class="bottom">bottom</p>
        </div>
    </div>
</div>

并且我有以下的CSS:

.container {
    float: left;
    padding: 15px;
    width: 600px;
}
.item {
    float: left;
    padding: 15px;
    width: 570px;
}
.left {
    float: left;
    padding: 40px 20px;
    margin-right: 10px;
}
.right {
    position: relative;
    float: left;
}
.bottom {
    position: absolute;
    bottom: 0;
}

左侧div的宽度和高度是动态的。

我想要实现的目标是:

  1. 使右侧div的高度等于左侧div的高度。
  2. 使右侧div的宽度填满具有类名为item的div的其余部分。
  3. 具有类名为bottom的段落应该在右侧div的底部。

这里是一个简单的图片,表示我的目标: enter image description here

以及连接到JSFiddle演示的链接。


你是在寻找纯CSS解决方案还是可以接受JavaScript? - j08691
如果在纯CSS中不可能实现,我会接受JavaScript解决方案,但CSS会更好。 - user1292810
这在纯CSS中在IE8+中是可能的。 - FelipeAls
4个回答

10

在跨浏览器的CSS解决方案中,获取.bottom的正确位置和宽度似乎是最大的障碍。

选项

1. 浮动

正如@joeellis所示,仅对左侧列进行浮动,并将overflow:hidden应用于右侧列,可以实现灵活的宽度。

在任何浏览器中都无法实现.bottom的位置。对于具有相等,可变高度的浮动列,没有CSS解决方案。一个绝对定位的.bottom元素必须在右列div内部,以便100%的宽度会给它正确的大小。但由于右侧列不一定与左侧列一样高,使用bottom:0来定位.bottom不一定会将其放置在容器底部。

2. HTML表格和CSS表格

通过将左侧单元格的宽度设置为1px,并不指定右侧单元格的宽度,可以实现灵活的宽度。两个单元格都将增长以适应内容。任何额外的空间将仅添加到右侧单元格。

如果 .bottom 在右侧表格单元格内部,Firefox 无法实现该位置。相对定位在 Firefox 中在表格单元格中没有效果;绝对定位和100%宽度也不会相对于右侧表格单元格。
如果 .bottom 被视为右列中的单独表格单元格,则除 Firefox 外,任何浏览器都无法实现正确的右侧和底部表格单元格高度。表格单元格在高度上的灵活性与宽度不同(除 Firefox 外)。
CSS3 弹性盒子和 CSS3 网格是未来有前途的布局工具。但是,IE9 或更早版本不支持弹性盒子,而除 IE10 之外的任何浏览器都不支持网格。尚未测试它们是否可以实现此布局,但浏览器支持可能防止它们成为当前的选项。
总结
  • 浮动不提供任何浏览器的解决方案。
  • HTML表格和CSS表格不提供跨浏览器的解决方案。
  • Flexbox不提供潜在解决方案给IE9或更早版本(并且可能或可能不提供其他浏览器的解决方案)。
  • Grids只提供潜在解决方案给IE10(并且可能或可能不提供那里的解决方案)。

结论

目前似乎没有足够的CSS解决方案,除了flexbox(如果不需要支持IE9及更早版本)外,在足够相关的浏览器中工作。

jQuery

这里有两个使用jQuery强制使列具有相同高度的修改演示。两个演示的CSS和jQuery代码是相同的,HTML只因左右列中内容的多少而不同。两个演示在所有浏览器中都测试通过。相同的基本方法可以用于纯JavaScript。 为了保持简单,我将左右div的内部填充移动到一个子元素(.content)。

@user1292810:我添加了一个简单的jQuery解决方案,并提供了几个演示。 - Matt Coughlin
感谢您详尽的回答。我必须支持IE7及以上版本。此外,该网站已经包含了jQuery,所以我会采用jQuery解决方案。 - user1292810
Flexbox在IE9及以下版本上的表现不如预期。由于规范的演变,它仍然需要三种不同的语法来实现,但是它确实可以工作。可以在http://knacss.com/builder/上找到已经包含所有前缀和语法的几个命名良好的类的可用样式(点击“Classic”,然后搜索flex)。 - FelipeAls

9
同一行且高度相同的兄弟元素可以通过将它们显示为“table-cell”,并将父元素设置为“display: table”来实现。
可工作的示例:http://jsfiddle.net/SgubR/2/(还展示了使用浮动元素创建列的overflow: hidden技术。后者需要清除浮动)。
CSS中的表格单元格(table-cell)可用于任何HTML元素(段落、div、span、li等),其语义与用于表格布局的、和
元素无关(除了其视觉效果相同,这正是我们想要的)。
  • 在父元素上设置display: table
  • 中间元素上可能会使用display: table-row,但如果不需要,那就没问题
  • 对每个子元素设置display: table-cell
  • 在这些“单元格”中设置宽度,浏览器将根据内容和设置的宽度来计算它们的宽度(以及父元素的总宽度)
  • table-layout: fixed将告诉浏览器切换到另一个表格布局算法,其中浏览器不关心内容的数量,只关心CSS设置的宽度
  • 大多数情况下都需要vertical-align: top(但您也可以设置其他值,这对于复杂的布局很有用)
  • 在“单元格”上不使用边距,仅使用填充。边距仅适用于表格本身。尽管如此,您仍然可以使用border-collapse: separate和/或border-spacing: 4px 6px来分隔“单元格”

兼容性:IE8+
如果需要,IE6/7的回退方法与inline-block完全相同

在先前的答案中有更详细的解释:这里那里,还有旧时好用的假列方法(您的设计必须考虑到这种技术)。


让所有子元素都适应父元素大小的好方法,其他的只谈论一个。 - Karthik T

2
只需在右栏添加 overflow 属性,不要对其进行浮动处理。
.right {
  position: relative;
  overflow: hidden;
}

这将使right填充剩余的宽度。

2
虽然这将在浮动元素旁创建一列,但这不会像OP所要求的那样“使右侧div的高度等于左侧div的高度”。 - FelipeAls

1

这样的东西可能有效:

http://jsfiddle.net/PCvy9/2/

你所寻找的主要关键点在于:
 .right {
   overflow: hidden;
   background-color: #C82927;
 }

这是由于所谓的“块级格式化上下文”引起的。关于其中原因和教程,请参考此链接:http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats 然而,它们的高度并不完全相互关联;在这个例子中,你左侧的块容器仍需要手动设置高度(因为它是一个浮动容器)。

虽然高度没有填满(原始JSFiddle中有一个错别字;“bottom”类未应用:http://jsfiddle.net/PCvy9/3/)。 - Alfred Xing
不,除非你在这两个元素上设置高度,或者在包裹容器上添加 min-height: 100% 并将其分配给这两个子容器,否则它们不会填充。这是因为 lorem ipsum 容器是浮动的。 - joeellis
+1聪明的解决方案,适用于灵活宽度部分的问题,即使它没有解决等高度的问题。在使用IETester测试时,在IE8或更早版本中没有成功,但不确定是否是由于IETester引起的。 - Matt Coughlin
1
@MattCoughlin 在我看来,IETester是一款糟糕的工具,因为它不可靠。这个bug是真实存在的还是由于测试工具的使用造成的?我的bugfix在IE上OK还是只在IETester上OK?我已经看到无数的时间因为这个工具而浪费了。最好使用来自http://modern.ie的虚拟机,这些至少是可靠的(较小的IE本身就足够不可靠,不需要再添加额外的层面...) - FelipeAls
我回去用Litmus进行了测试(而不是IETester),在IE7及更高版本中都没有问题。 - Matt Coughlin

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