使弹性项目伸展全高,并垂直居中其内容 [英] Make flex items stretch full height and vertically center their content

查看:159
本文介绍了使弹性项目伸展全高,并垂直居中其内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个水平的弹性框(即 flex-direction:row ,即并排)和几个项目。每个项目可以是一行文本,也可以有多行。我想垂直对齐每个Flex项目的内容。

如果每个项目都有一个透明的背景,我可以很容易地使用 align-items:中心。然而,我希望每个项目都垂直拉伸,因为我想设置一个背景(或者可能是边框,或者可能是一个可点击的区域)到整个可用的高度。



<到目前为止,我知道:




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

  • 拉伸和对齐: / li>


演示可在和问题23442692 问题27729619 问题25311541 问本质上相同的东西,但是他们要么有一个单一的元素,弹性项目。只要我们有混合的内容,可能与多个元素,这些解决方案不起作用。



  • 解决问题19026884 是不相关的,问题是有错误的标记。方案

    不幸的是,在使用问题中发布的确切标记时,不可能达到预期效果。 解决方案包括:




    • < li>上设置 display:flex;

    • < li> 内容包装到另一个元素中。


      • 因为< li> 现在是flex容器,所以我们需要另一个元素以防止实际内容变成弹性项目。
      • 在此解决方案中,我引入了< div> 元素,但它可以

    • 现在< li> 是一个flex容器,它只包含一个孩子,我们可以使用 align-items 和/或 justify-content 来对齐这个


    DOM树看起来像这样:

     < ul> flex-parent,direction = row 
    ├< li> flex-item&& flex-parent&&背景&& JavaScript可点击区域
    │└< div> flex-item作为一个透明元素
    │├实际内容
    │└实际内容
    ├...

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



    / *新代码:这是解决方案。 * / ul> li {display:flex; flex-direction:column; justify-content:center; align-items:center;} / *下面的旧代码。 * / 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;} / *视觉样式,忽略。 * / html,body {font-family:sans-serif; font-size:25px; } ul,li {list-style:none;保证金:0;填充:0; } ul {background:#CCF;宽度:25em; } button:focus + ul {font-size:14px; width:auto;}

    < button>点击这里设置< code> width:auto< / code>并减少字体大小。< / button><! - 新代码:有一个< div>在每个< li>和他们的内容。 - >< UL> <李>< DIV>样品< / DIV>< /锂> <李>< DIV><跨度>跨度< /跨度>< / DIV>< /锂> <李>< DIV><跨度>多< /跨度> <跨度>跨度< /跨度>< / DIV>< /锂> < li>< div>文字< span> span< / span>< / div>< / li> <李>< DIV>多<峰; br>线474; / DIV>< /立GT;< / UL>


    I have a horizontal flex box (i.e. flex-direction: row, i.e. side-by-side) with a few items. Each item can be a single line of text, or can have multiple lines. I want to vertically-align the contents of each flex item.

    If each item had a transparent background, I could easily use align-items: center. However, I want each item to be stretched vertically, because I want to set a background (or maybe borders, or maybe it is a clickable region) to the entire available height.

    So far, I know:

    • Stretching: align-items: stretch
    • Aligning: align-items: center
    • Stretching and aligning: ???

    Demo available at 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; }

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


    Similar questions:

    解决方案

    Unfortunately, it is impossible to achieve the desired effect while using the exact markup posted in the question.

    The solution involves:

    • Setting display: flex; on <li>.
    • Wrapping the <li> contents into another element.
      • This is required because <li> is now a flex container, so we need another element to prevent the actual contents from becoming flex items.
      • In this solution, I introduced a <div> element, but it could have been other element.
    • Now that <li> is a flex container and it contains only a single child, we can use align-items and/or justify-content to align this new and only child.

    The DOM tree looks like this:

    <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
     ├ …
    

    Note: The solution in this answer uses 2 nested flex boxes. The solution by Michael_B uses 3 nested flex boxes, because it has the added challenge of expanding the <a> element to fill the entire <li>. Which one is preferred depends on each case. If I could, I would accept both answers.

    /* 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;
    }

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

    这篇关于使弹性项目伸展全高,并垂直居中其内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆