如何使 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-*
构造,但也不是真正“更语义化”(这是一个可怕的例子div
soup)并破坏了 IE6 兼容性。我个人会坚持使用<table>
,除非有人设法想出一个天才的简单想法,而无需
是的。从 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:可能只需要在div
s 上添加一些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: 1
是flex-grow: 1
的简写。这是一个组合属性:flex: <grow> <shrink> <basis>
.
请注意,在 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% 的容器宽度?