使柔性物品伸展整个高度并垂直居中

Den*_*aia 13 css css3 flexbox

我有一个水平柔性盒(即flex-direction: row,并排)与几个项目.每个项目可以是单行文本,也可以有多行.我想垂直对齐每个flex项的内容.

如果每个项目都有透明背景,我可以轻松使用align-items: center.但是,我希望每个项目都垂直拉伸,因为我想将背景(或可能是边框,或者可能是可点击的区域)设置为整个可用高度.

到目前为止,我知道:

  • 拉伸: align-items: stretch
  • 对齐: align-items: center
  • 拉伸和对齐:???

可在http://codepen.io/denilsonsa/pen/bVBQNa上获得演示

演示的屏幕截图

ul {
  display: flex;
  flex-direction: row;
}
ul.first {
  align-items: stretch;
}
ul.second {
  align-items: center;
}
ul > li {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 5em;
  text-align: center;
}
ul > li:nth-child(2) {
  background: #CFC;
}

/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }
Run Code Online (Sandbox Code Playgroud)
<ul class="first">
  <li>Sample</li>
  <li><span>span</span></li>
  <li><span>multiple</span> <span>span</span></li>
  <li>text <span>span</span></li>
  <li>multi<br>line</li>
</ul>
<hr>
<ul class="second">
  <li>Sample</li>
  <li><span>span</span></li>
  <li><span>multiple</span> <span>span</span></li>
  <li>text <span>span</span></li>
  <li>multi<br>line</li>
</ul>
Run Code Online (Sandbox Code Playgroud)


类似的问题:

Den*_*aia 6

不幸的是,在使用问题中发布的确切标记时,不可能达到预期的效果.

解决方案包括:

  • 设置display: flex;<li>.
  • <li>内容包装到另一个元素中.
    • 这是必需的,因为<li>现在是一个flex容器,所以我们需要另一个元素来防止实际内容变成flex项.
    • 在这个解决方案中,我介绍了一个<div>元素,但它可能是其他元素.
  • 现在这<li>是一个flex容器并且它只包含一个子容器,我们可以使用align-items和/或justify-content对齐这个新的和唯一的子容器.

DOM树看起来像这样:

<ul> flex-parent, direction=row
 ? <li> flex-item && flex-parent && background && JavaScript clickable area
 ?  ? <div> flex-item as a single transparent element
 ?     ? Actual contents
 ?     ? Actual contents
 ? …
Run Code Online (Sandbox Code Playgroud)

注意:此答案中的解决方案使用2个嵌套的弹性框.Michael_B的解决方案使用3个嵌套的弹性框,因为它增加了扩展<a>元素以填充整个元素的挑战<li>.哪一个是优选的取决于每种情况.如果可以的话,我会接受这两个答案.

/* New code: this is the solution. */
ul > li {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

/* Old code below. */
ul {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
ul > li {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 5em;
  text-align: center;
}
ul > li:nth-child(2) {
  background: #CFC;
}

/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }

button:focus + ul {
    font-size: 14px;
    width: auto;
}
Run Code Online (Sandbox Code Playgroud)
<button>Click here to set <code>width: auto</code> and reduce the font size.</button>

<!-- New code: there is a single <div> between each <li> and their contents. -->
<ul>
  <li><div>Sample</div></li>
  <li><div><span>span</span></div></li>
  <li><div><span>multiple</span> <span>span</span></div></li>
  <li><div>text <span>span</span></div></li>
  <li><div>multi<br>line</div></li>
</ul>
Run Code Online (Sandbox Code Playgroud)


Mic*_*l_B 5

我希望每个项目都垂直拉伸,因为我想将背景(或者可能是边框,或者可能是可点击区域)设置为整个可用高度。

您可以在不更改 HTML 结构的情况下实现此布局。不需要额外的容器。

你已经有了一个主要的弹性容器和一组弹性项目。只需将这些 flex 项放入嵌套的 flex 容器中即可。这将使您能够将内容与 flex 属性对齐。

(因为你提到你可能需要可点击的区域,我从元素切换lia了。)

nav {
  display: flex;
  background: #CCF;
  width: 25em;
}

nav > a {
  flex: auto;  /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
  text-align: center;
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
nav > a:nth-child(2) {
  background: #CFC;
}

html, body {
  font-family: sans-serif;
  font-size: 25px;
}
Run Code Online (Sandbox Code Playgroud)
<nav>
  <a href="">Sample</a>
  <a href=""><span>span</span></a>
  <a href=""><span>multiple</span> <span>span</span></a>
  <a href="">text <span>span</span></a>
  <a href="">multi<br>line</a>
</nav>
Run Code Online (Sandbox Code Playgroud)

修订代码笔

请注意,直接放置在 flex 容器内的内容被包裹在一个匿名的 flex 项中

从规范:

4. 弹性项目

flex 容器的每个流入子元素都成为一个 flex 项,并且直接包含在 flex 容器内的每个连续文本都被包裹在一个匿名的 flex 项中。

因此,因为文本自动包裹在弹性项目中,您可以保持每个项目的全高(align-items: stretch从主容器)并垂直居中内容(align-items: center从嵌套容器)。