如何使行内块元素填充行的其余部分?


186

使用CSS和两个内联块(或其他)DIV标签而不是使用表,是否有可能这样做?

表格版本是这样的(添加了边框,您可以看到它):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<table style="width:100%;">
<tr>
<td style="border:1px solid black;width:100px;height:10px;"></td>
<td style="border:1px solid black;height:10px;"></td>
</tr>
</table>
</body>
</html>

它会产生带有固定宽度(而不是百分比宽度)的左列,并且右列会扩展以填充行上的剩余空间。听起来很简单,对吧?此外,由于没有任何东西“浮动”,因此父容器的高度会适当扩展以包含内容的高度。

--BEGIN RANT--
我已经看到了带有固定宽度的边栏的多列布局的“清晰修复”和“圣杯”实现,它们很烂而且很复杂。他们颠倒了元素的顺序,使用了百分比宽度,或者使用了浮点数,负边距,并且“ left”,“ right”和“ margin”属性之间的关系很复杂。此外,布局是亚像素敏感的,因此即使添加边框,填充或边距的单个像素也将破坏整个布局,并将整列换行发送到下一行。例如,即使您尝试做一些简单的事情(例如,将4个元素放在一行上,每个元素的宽度都设置为25%),舍入误差也是一个问题。
-结束兰特-

我曾尝试使用“ inline-block”和“ white-space:nowrap;”,但问题是我无法获取第二个元素来填充行中的剩余空间。在某些情况下,可以将宽度设置为“ width:100%-(LeftColumWidth)px”,但是实际上不支持在width属性中执行计算。


1
我认为除了将其转换为可以使用的display: table-*构造之外,没有其他明智的方法,但也不是“更具语义”(这是一个糟糕的例子div)并且破坏了IE6兼容性。我个人会坚持使用<table>,除非有人设法提出一个没有这个天才的简单想法
Pekka

51
是的 从CSS时代开始,我就不断遇到所有这些“避免表”参数,如果您仍然使用表进行布局,那么它们的用语会让您听起来像是一个无能的懒惰白痴。快进十年了,这仍然是理想主义的梦想。事实是,流布局语义SUCK用于固定但灵活的布局,例如用户界面和表单。事实是,聪明的人会在方便的地方使用表,因为他们已经用尽了所有可能的CSS解决方案,并且意识到它们不仅不完美,而且比仅使用表复杂得多。
Triynko 2011年

4
浮空?请向我展示有效的代码,其中行尾元素不会意外地换行,并且边框和边距不会破坏布局。那是他们的错。另外,自动调整大小的父容器是否可以正确扩展以包含浮动元素,而不会出现“明确修复”漏洞?我不这么认为。
Triynko 2011年

如果您的父容器中至少有一个非浮动元素,那么清除浮动并不是真正的“黑客”,是吗?请记住,CSS起源于打印-请参见css-tricks.com/containers-dont-clear-floats,以获取有关为什么不进行自动清除的很好的讨论。
Chowlett 2011年

3
@Triynko:这是我之前所做的:jsfiddle.net/thirtydot/qx32C-我认为这对您来说很重要。我会听到您对我所做的演示的评论,然后尝试对其进行修复。
2011年

Answers:


169

请参阅: http //jsfiddle.net/qx32C/36/

.lineContainer {
    overflow: hidden; /* clear the float */
    border: 1px solid #000
}
.lineContainer div {
    height: 20px
} 
.left {
    width: 100px;
    float: left;
    border-right: 1px solid #000
}
.right {
    overflow: hidden;
    background: #ccc
}
<div class="lineContainer">
    <div class="left">left</div>
    <div class="right">right</div>
</div>


为什么我margin-left: 100pxoverflow: hiddenon 代替.right

编辑:这是上述(死)链接的两个镜像:


60
如果您称自己为Web开发人员,则需要单击该链接。我做到了,我感觉就像茉莉花在魔毯上一样。
克里斯·喊

2
@ChrisShouts,这可能是描述此问题的最佳方法。这种方法没有任何意义,但是再说一遍...对于您应该能够明确执行的操作而言,这是一个极好的解决方法。
mjvotaw 2011年

14
隐藏的溢出不是解决方案。假设您不希望隐藏正确容器的溢出。这不会使正确的容器的大小填充该行的剩余空间。这是一个已有两年历史的问题的示例,我仍然没有将其标记为答案,因为仍然没有令人满意的答案。
Triynko

3
Triynko:即使您使用的是“ overflow:hidden”,通常也不会隐藏任何内容(至少在其中只有文本的情况下)。div内的文本/元素将进行排列,以使其适合div内(当然,除非您有一个大于div的元素)。
CpnCrunch

1
@RMorrisey:可能只需要一些box-sizing: border-box就可以了div。只是一个猜测,因为您没有提供演示您所描述行为的演示。话虽这么说,display: table基础的解决方案会更好一些,。这是一个非常老的问题,但是我认为由于OP的行为,我试图避免与此表中的表有关。
三十点

64

使用flexbox的现代解决方案:

.container {
    display: flex;
}
.container > div {
    border: 1px solid black;
    height: 10px;
}

.left {
   width: 100px;
}

.right {
    width: 100%;
    background-color:#ddd;
}
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
</div>

http://jsfiddle.net/m5Xz2/100/


4
显示弯曲度和宽度100%..必须记住
dreamerkumar

9
使用flex时,为什么不使用flex: 1代替width: 100%
Itai Bar-Haim

对于flexbox的新手flex: 1是的简写flex-grow: 1。这是一个组合属性:flex: <grow> <shrink> <basis>
tanius

1
只是快速记下显示:flex是在IE <11不支持的,并在11非常错误
埃里克·希尔兹

1
@EricShields不应阻止任何人使用Flexbox。如今我们flexbugs知道了。
神经递质

47

与常见的现代浏览器(IE 8+)兼容:http//jsfiddle.net/m5Xz2/3/

.lineContainer {
    display:table;
    border-collapse:collapse;
    width:100%;
}
.lineContainer div {
    display:table-cell;
    border:1px solid black;
    height:10px;
}
.left {
    width:100px;
}
 <div class="lineContainer">
    <div class="left">left</div>
    <div class="right">right</div>
</div>


9
反对使用表格的论点与其表现特征无关。它与难以管理的标记,样式/文档混乱以及不正确的语义有关。这些论点均不适用于display:table
Rich Remer

这没有回答如何inline-block填充行的其余部分。
神经递质

1
@TranslucentCloud我同意我的回答不能完全回答问题标题,但是它提供了一种使用div填充可用宽度的方法,如问题正文中所问。
Frosty Z '18

1
我非常喜欢这种解决方案。您不必强迫使用一些来自隐藏CSS逻辑的怪异样式(例如隐藏的溢出)。
Chaoste

4

您可以在流体元素上使用calc(100%-100px),同时对两个元素使用display:inline-block。

请注意,标记之间不应有任何空格,否则,您也必须在计算中考虑该空间。

.left{
    display:inline-block;
    width:100px;
}
.right{
    display:inline-block;
    width:calc(100% - 100px);
}


<div class=“left”></div><div class=“right”></div>

快速示例:http : //jsfiddle.net/dw689mt4/1/


1

我已经利用flex-grow财产来实现这一目标。你必须设置display: flex为父容器,那么你需要设置flex-grow: 1你要填写剩余空间,或者仅仅是块flex: 1作为tanius在评论中提到。


0

如果您不能使用overflow: hidden(因为不需要overflow: hidden)或不喜欢CSS hack /解决方法,则可以改用JavaScript。请注意,它可能不是很好,因为它是JavaScript。

var parent = document.getElementsByClassName("lineContainer")[0];
var left = document.getElementsByClassName("left")[0];
var right = document.getElementsByClassName("right")[0];
right.style.width = (parent.offsetWidth - left.offsetWidth) + "px";
window.onresize = function() {
  right.style.width = (parent.offsetWidth - left.offsetWidth) + "px";
}
.lineContainer {
  width: 100% border: 1px solid #000;
  font-size: 0px;
  /* You need to do this because inline block puts an invisible space between them and they won't fit on the same line */
}

.lineContainer div {
  height: 10px;
  display: inline-block;
}

.left {
  width: 100px;
  background: red
}

.right {
  background: blue
}
<div class="lineContainer">
  <div class="left"></div>
  <div class="right"></div>
</div>

http://jsfiddle.net/ys2eogxm/


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.