【问题标题】:How can I hide flex items when it overflows the flex parent?当弹性项目溢出弹性父项时,如何隐藏弹性项目?
【发布时间】:2014-08-09 13:31:28
【问题描述】:

假设我有一个 flexbox 容器,其中的内容可能会溢出父容器。我想要的是,如果任何物品比容器大任何数量,它就会被隐藏。如果我设置overflow: hidden,它只会隐藏该项目的溢出部分,而不是整个项目。

考虑以下几点:

<nav id="top-nav">
    <div id="main-nav-container">
        <div class="menu">
            <ul>
                <li><a href="/">Item 1</a></li>
                <li><a href="/">Item 2</a></li>
                <li><a href="/">Item 3</a></li>
                <li><a href="/">Item 4</a></li>
            </ul>
        </div>
        <div class="menu">
            <ul>
                <li><a href="/">Other 1</a></li>
                <li><a href="/">Other 2</a></li>
            </ul>
        </div>
    </div>
</nav>

CSS:

#top-nav, #top-nav div.menu ul li {
  background-color: #444;
}

#main-nav-container {
  margin: 0 auto;
  max-width: 1200px;
  padding: 0 40px;
  display: -webkit-inline-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: justify;
  -moz-justify-content: -moz-space-between;
  -ms-justify-content: -ms-space-between;
  justify-content: space-between;
}

#top-nav div.menu {
  -webkit-flex: 1;
  display: -webkit-inline-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

#top-nav div.menu:last-child {
  display: -webkit-inline-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-justify-content: flex-end;
  -webkit-flex-direction: row;
  flex-direction: row;
  justify-content: flex-end;
}

#top-nav div.menu,
#top-nav div.menu ul {
  text-align: left;
  alignment-baseline: baseline;
  margin: 0;
  padding: 0;
}
#top-nav div.menu ul {
  list-style: none;
}
#top-nav div.menu > ul {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  white-space: nowrap;
}
#top-nav div.menu li {
  -webkit-flex-shrink: 0;
  -moz-flex-shrink: 0;
  -ms-flex-shrink: 0;
  flex-shrink: 0;
  margin: 0
  position: relative;
  font-size: 1.1em;
  cursor: pointer;
}
#top-nav div.menu ul li a {
  color: #E6E6E6;
  text-decoration: none;
  display: block;
  padding: 7px;
}

如果窗口缩小,我希望“项目 4”在它开始被“其他 1”重叠时隐藏。

一旦我实现了这一点,我还需要一个可以针对隐藏的选择器。

jsfiddle setup here

【问题讨论】:

  • 您不太可能只针对溢出的弹性项目 - 无论如何不能直接定位。没有用于此目的的选择器。
  • 对不起,不应该是直接用CSS定位,我可以用jQuery定位它们,即$("div.menu ul li:hidden"),最重要的是我想要一种隐藏整个元素的方法,而不仅仅是隐藏内容溢出。
  • 啊,确实有道理。

标签: html css flexbox


【解决方案1】:

这不是解决确切问题的答案,但标题与我的(稍微)不同的问题相匹配,我通过谷歌搜索该术语到达这里。

如果你知道哪个元素会换行并且你不需要显示它(在我的例子中是一个“聪明”的间隔),你可以将它的高度设置为 0。它会换行,但不会增加任何高度。

【讨论】:

    【解决方案2】:

    我制作了一个多部分代码笔来展示上述答案(例如,使用溢出隐藏和高度)以及如何展开/折叠溢出的项目

    示例 1:https://codepen.io/Kagerjay/pen/rraKLB(使用其他人提到的答案的真实简单示例)

    示例 2:https://codepen.io/Kagerjay/pen/LBErJL(单个事件处理程序在溢出项目上显示更多/不显示)

    示例 3:https://codepen.io/Kagerjay/pen/MBYBoJ(多个事件处理程序显示更多/显示更少溢出项目)

    我也附上了下面的示例 3,我使用 Jade/Pug,所以下面的详细示例

    // Overflow boolean checker
    function isOverflown(element){
      return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
    }
    
    // Jquery Toggle Text Plugin
    $.fn.toggleText = function(t1, t2){
      if (this.text() == t1) this.text(t2);
      else                   this.text(t1);
      return this;
    };
    
    // Toggle Overflow
    function toggleOverflow(e){
      e.target.parentElement.classList.toggle("grid-parent--showall");
      $(e.target).toggleText("Show More", "Show LESS");
    }
    
    // Where stuff happens
    var parents = document.querySelectorAll(".grid-parent");
    
    parents.forEach(parent => {
      if(isOverflown(parent)){
        parent.lastElementChild.classList.add("btn-show");
        parent.lastElementChild.addEventListener('click', toggleOverflow);
      }
    })
    body {
      background-color: #EEF0ED;
      margin-bottom: 300px;
    }
    
    .grid-parent {
      margin: 20px;
      width: 250px;
      background-color: lightgrey;
      display: flex;
      flex-wrap: wrap;
      overflow: hidden;
      max-height: 100px;
      position: relative;
    }
    .grid-parent--showall {
      max-height: none;
    }
    
    .grid-item {
      background-color: blue;
      width: 50px;
      height: 50px;
      box-sizing: border-box;
      border: 1px solid red;
    }
    .grid-item:nth-of-type(even) {
      background-color: lightblue;
    }
    
    .btn-expand {
      display: none;
      z-index: 3;
      position: absolute;
      right: 0px;
      bottom: 0px;
      padding: 3px;
      background-color: red;
      color: white;
    }
    
    .btn-show {
      display: block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <section>
      <p>Any grid-parent over 10 child items has a "SHOW MORE" button to expand</p>
      <p>Click "SHOW MORE" to see the results</p>
    </section>
    <radio></radio>
    <div class="wrapper">
      <h3>5 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
      <h3>8 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
      <h3>10 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
      <h3>13 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
      <h3>16 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
      <h3>19 child elements</h3>
      <div class="grid-parent">
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="grid-item"></div>
        <div class="btn-expand">Show More</div>
      </div>
    </div>

    【讨论】:

      【解决方案3】:

      这是一个使用 flexbox 的实现;

      * {
        box-sizing: border-box;
      }
      
      ul {
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        height: 400px;
        width: 300px;
        overflow: hidden;
        border: solid 1px red;
        margin: 0;
        padding: 0;
        list-style: none;
      }
      
      ul li {
        height: auto;
        padding: 15px;
        width: 100%;
        border: solid 1px #000;
        flex: 0 0 auto;
      }
      <ul>
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
        <li>F</li>
        <li>G<br />klajlka</li>
        <li>H</li>
      </ul>

      【讨论】:

        【解决方案4】:

        我希望有一个 CSS 解决方案,尽管我刚刚实现了一个 javascript 实现。我在这里用过 jQuery,虽然没必要。

        $(function() {
          $(window).resize(function() {
            var max = $("#top-nav div.menu:last-child>ul>li:first-child").position().left;
            $("#top-nav div.menu:first-child > ul").children("li").each(function() {
              // We have to show first so we can get position/size
              var $this = $(this).show();
              if ($this.position().left + $this.width() > max) {
                $this.nextAll().andSelf().hide();
                return false;
              }
            });
          });
          $(window).resize();
        });
        

        在其他地方获取隐藏节点可以通过$("#top-nav div.menu:first-child&gt;ul&gt;li:hidden");来实现。我也可以为此添加一个可以单独定位的类,例如通过提供一个按钮来显示隐藏的项目。

        【讨论】:

          【解决方案5】:

          解决您的问题的方法是添加以下 CSS 代码:

          #top-nav div.menu > ul {
            flex-wrap: wrap;
            height: 34px;
            overflow: hidden;
          }
          

          如果你想知道哪些元素被隐藏了,你应该使用 Javascript/jQuery 来解决你的问题,因为你无法知道使用 CSS。

          【讨论】:

          • 我喜欢这里的想法,虽然我更愿意避免输入高度。我认为我对需要针对隐藏对象的注释提出了混淆,但我确实添加了一条评论来解释这一点。
          • 我认为你应该考虑不隐藏元素;而是使用flex-wrap: wrap。这样可以避免输入高度。
          • 在网络浏览器中,使用键盘上的 TAB,您仍然可以导航到这些项目并显示它们。这个解决方案对我不起作用。
          • 这是解决方案,其中弹性盒本身不是决定高度的因素。如果它包含在它所基于的父级中(以百分比表示的高度),则效果很好。
          猜你喜欢
          • 2017-06-21
          • 1970-01-01
          • 2019-09-27
          • 2018-10-08
          • 2021-01-23
          • 2018-08-20
          • 2016-07-13
          • 2020-04-20
          相关资源
          最近更新 更多