如何使 inline-block 元素填充行的其余部分?

Posted

技术标签:

【中文标题】如何使 inline-block 元素填充行的其余部分?【英文标题】:How to make an inline-block element fill the remainder of the line? 【发布时间】:2011-07-29 06:28:01 【问题描述】:

是否可以使用 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>

它产生一个具有 FIXED WIDTH(不是百分比宽度)的左列,以及一个扩展以填充行上的 THE REMAINING SPACE 的右列。听起来很简单,对吧?此外,由于没有任何东西是“浮动的”,因此父容器的高度会适当地扩展以包含内容的高度。

--开始咆哮-- 我已经看到了具有固定宽度侧列的多列布局的“明确修复”和“圣杯”实现,它们很糟糕而且很复杂。它们颠倒了元素的顺序,它们使用百分比宽度,或者它们使用浮点数、负边距,并且“left”、“right”和“margin”属性之间的关系很复杂。此外,布局是亚像素敏感的,因此即使添加单个像素的边框、填充或边距也会破坏整个布局,并将整个列发送到下一行。例如,即使您尝试做一些简单的事情,例如将 4 个元素放在一条线上,每个元素的宽度都设置为 25%,舍入错误也是一个问题。--END RANT--

我尝试过使用“inline-block”和“white-space:nowrap;”,但问题是我无法让第二个元素填充 remaining 空间线。在某些情况下,将宽度设置为“width:100%-(LeftColumWidth)px”会起作用,但实际上并不支持在宽度属性中执行计算。

【问题讨论】:

我不认为有一种理智的方法可以做到这一点,除非把它变成一个可以工作的display: table-* 构造,但也不是真正“更语义化”(这是一个可怕的例子divsoup)并破坏了 IE6 兼容性。我个人会坚持使用&lt;table&gt;,除非有人设法想出一个天才的简单想法,而无需 是的。从 CSS 时代的曙光开始,我一直遇到所有这些“避免使用表格”的论点,如果你仍然使用表格进行布局,它们的措辞会让你听起来像一个无能的懒惰白痴。快进十年,它仍然是一个理想主义的白日梦。事实是,流布局语义对于用户界面和表单等固定但灵活的布局来说很糟糕。事实上,聪明的人会在方便的时候使用表格,因为他们已经用尽了所有可能的 CSS 解决方案,并意识到它们都不完美,而且比仅仅使用表格要复杂得多。 浮动?向我展示工作代码,其中行尾元素不会意外换行,边框和边距不会破坏布局。这就是他们的问题。此外,自动调整大小的父容器是否正确扩展以包含浮动元素而没有“清除修复”黑客?我不这么认为。 如果您的父容器中至少有一个非浮动元素,那么清除浮动元素并不是真正的“黑客”,是吗?请记住,CSS 起源于打印 - 请参阅 css-tricks.com/containers-dont-clear-floats 以获得关于为什么您没有获得自动清除功能的精彩讨论。 @Triynko:这就是我之前所做的:jsfiddle.net/thirtydot/qx32C - 我认为它符合你的大部分观点。我会听到你对我所做的演示的批评,然后尝试修复它。 【参考方案1】:

见: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>

Why did I replace margin-left: 100px with overflow: hidden on .right?

【讨论】:

如果第二个 div 元素是一个输入文本字段,你能让它工作吗? @tribalvibes:喜欢this?或者this? 溢出隐藏不是解决方案。假设您不希望隐藏右侧容器的溢出。这不会使右容器的大小填满行上的剩余空间。这是一个两年前的问题示例,我还没有标记答案,因为仍然没有令人满意的答案。 Triynko:即使您使用的是 'overflow:hidden',通常也不会隐藏任何内容(至少如果您在其中只有文本)。 div 中的文本/元素将被排列,以便它们适合 div(当然,除非您有一个大于 div 的元素)。 @RMorrisey:可能只需要在divs 上添加一些box-sizing: border-box。只是猜测,因为您没有提供演示您描述的行为的演示。话虽如此,the display: table-based solution is usually better。这是一个非常古老的问题,但由于 OP 的行为,我想我试图避免与此问题中的表格有关。【参考方案2】:

使用 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/

【讨论】:

显示 flex 和 width 100% .. 必须记住 在使用 flex 时,为什么不用flex: 1 而不是width: 100% 呢? 对于flexbox 的新手:flex: 1flex-grow: 1 的简写。这是一个组合属性:flex: &lt;grow&gt; &lt;shrink&gt; &lt;basis&gt;. 请注意,在 IE @EricShields 这不应该阻止任何人使用 Flexbox。现在我们有flexbugs 你知道的。【参考方案3】:

兼容常见的现代浏览器(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>

【讨论】:

反对使用表格的论点与其表现特征无关。它与难以管理的标记、样式/文档混乱和不正确的语义有关。这些论点均不适用于display:table 这没有回答如何使inline-block 填充该行的其余部分。 @TranslucentCloud 我同意我的回答并没有完全回答问题标题,但它提供了一种使用 div 填充可用宽度的方法,如问题正文中所述。 我非常喜欢这个解决方案。您不必强制使用隐藏的 CSS 逻辑产生的一些奇怪的样式(例如溢出隐藏)。【参考方案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/

【讨论】:

【参考方案5】:

我使用flex-grow 属性来实现这个目标。您必须为父容器设置display: flex,然后您需要为要填充剩余空间的块设置flex-grow: 1,或者只需将flex: 1设置为cmets中提到的tanius。

【讨论】:

【参考方案6】:

如果你不能使用overflow: hidden(因为你不想要overflow: hidden)或者你不喜欢CSS hacks/workarounds,你可以改用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/

【讨论】:

【参考方案7】:

当你放弃内联块时

.post-container 
    border: 5px solid #333;
    overflow:auto;

.post-thumb 
    float: left;
    display:block;
    background:#ccc;
    width:200px;
    height:200px;

.post-content
    display:block;
    overflow:hidden;

http://jsfiddle.net/RXrvZ/3731/

(来自CSS Float: Floating an image to the left of the text)

【讨论】:

以上是关于如何使 inline-block 元素填充行的其余部分?的主要内容,如果未能解决你的问题,请参考以下文章

填充行的其余部分/避免违反空约束

Flexbox:如何让 div 在不换行的情况下填充 100% 的容器宽度?

使用display: inline-block;遇到的问题及解决

如何使画布元素根据鼠标位置填充和重新填充

如何使 flexbox 元素填充剩余空间并滚动?

block inline 和 inline-block