使用 CSS 将元素的宽度分配给子 div 元素

25

我有一些数量不确定的inline-block divs,希望它们一起占用父元素的100%。这可以在不使用JavaScript的情况下完成吗?我唯一想到的方法是使用表格,但仅出于布局目的而使用表格当然是不好的做法。

|----------------------|
|{  div 1  }{  div 2  }|
           or
|{div 1}{div  2}{div 3}|
|----------------------|

我也尝试过 { display:block; float:left; },但似乎没有什么区别。


你想在不设置百分比的显式“宽度”的情况下完成这个吗? - thirtydot
1
是的 - 你想要表格列的显示模式 - 但这并不意味着你需要在HTML中添加一个表格。请看我的答案... - Ben Hull
4个回答

32

你可以在内部的div上使用display:table-cell来实现这一点。为了使内部的div表现得像表单元格,浏览器还需要两层包含元素:一个充当表格的元素,另一个充当表格行的元素。

对于这样的结构:

   <div class="outer">
       <div class="middle">
          <div class="inner">Item 1</div> 
          <div class="inner">Item 2</div> 
          <div class="inner">Item 3</div> 
          <div class="inner">Item 4</div> 
       </div>
   </div>

使用以下CSS:

div.outer {display:table;}
div.middle {display:table-row;}
div.inner {display:table-cell;}

一个好用的结构是将 UL 放在 DIV 里面:DIV 充当表格,UL 充当行,LI 充当单元格。

这种技术在旧浏览器中支持不好 - 对于 IE8 之前的浏览器,你将完全没有运气。

如果需要更多示例代码,请告诉我!


6
不要在具有"display: table-cell"属性的div上设置任何宽度,而是在具有"display: table"属性的div上设置"table-layout: fixed"。请注意保持原意不变,使翻译更加通俗易懂。 - thirtydot
这个能用在 liul 上吗?我有一个菜单是一个带项目符号的列表,我想让每个 li 占据整个空间,根据元素数量平均分配。我尝试将 ul 设置为 display:table,将 li 设置为 display: table-cell,但没有成功。有什么解决方法可以保持它作为带项目符号的列表吗? - Shimmy Weitzhandler
1
是的,@Shimmy,你需要将列表包装在另一个元素中:包装器是display:table;,ul是display:table-row,li是display:table-cell。我已经编辑了我的答案,以使当前信息更清晰。 - Ben Hull
据我所知,这并不是很干净的解决方案——正如您所知道的那样,元素确实像表格单元格一样行事,会根据内容进行自适应。唯一可以保证表格单元格具有相同宽度的时间是它们具有相同的内容(或没有内容)。也许您可以利用每个单元格内部的绝对定位(将内容从布局流中取出),但这时居中内容就变得棘手了... - Ben Hull
@Beejamin 我想我还是会坚持使用JavaScript :( - Shimmy Weitzhandler
显示剩余5条评论

9

接受的答案漏掉了一个重要的CSS属性,这个属性是必需的:

table-layout: fixed;

这是正确的答案:

HTML:

<div class="outer">
    <div class="middle">
        <div class="inner">Item 1</div> 
            <div class="inner">Item 2</div> 
            <div class="inner">Item 3</div> 
            <div class="inner">Item 4</div> 
        </div>
    </div>
</div>

CSS:

div.outer {display:table; table-layout: fixed;}
div.middle {display:table-row;}
div.inner {display:table-cell;}

9
您可以在此处使用css3的优势。我也遇到了这个问题,现在我已经使用以下示例代码进行了修复。

.parent-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row wrap;
  justify-content: space-around;
  -webkit-justify-content: space-around;
  flex-wrap: nowrap;
  -webkit-flex-wrap: nowrap;
}
.child-item {
  margin: 5px;
  text-align: center;
  padding: 10px;
  background-color: red;
  color: #fff;
}
<ul class="parent-container">
  <li class="child-item">1</li>
  <li class="child-item">2</li>
  <li class="child-item">3</li>
  <li class="child-item">4</li>
  <li class="child-item">5</li>
  <li class="child-item">6</li>
  <li class="child-item">7</li>
</ul>

感谢您的来信,致以问候, Lingeshram


你能解释一下,到底需要什么才能使这个工作起来,而不只是放一些代码吗? - anon

3

我想对@lingeshram的回答进行阐述。Flexbox已经发展到了现在可以说是最好的方法了。如果你需要支持旧的浏览器,请务必先检查caniuse

.container {
  display: flex; /* or inline-flex */
}

.col {
  flex-grow: 1;
  border: 1px solid #000;
}

.col2x {
  flex-grow: 2;
  border: 1px solid #000;
}
Evenly split three children
<div class='container'>
  <span class='col'>Inner 1</span>
  <span class='col'>Inner 2</span>
  <span class='col'>Inner 3</span>
</div>

<br>
Evenly split two children
<div class='container'>
  <span class='col'>Inner 1</span>
  <span class='col'>Inner 2</span>
</div>

<br>
Split three children, but the middle is twice the size of the others
<div class='container'>
  <span class='col'>Inner 1</span>
  <span class='col2x'>Inner 2</span>
  <span class='col'>Inner 3</span>
</div>

以下是一个相当不错的 指南,介绍了使用 flexbox 的不同方式。


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