【问题标题】:Can flexbox detect when a flex item wraps?flexbox 可以检测 flex 项目何时换行吗?
【发布时间】:2017-09-11 05:58:03
【问题描述】:

我希望摆脱媒体查询,只使用 flexbox 来解决我的问题,但我不确定这是否可能。随着窗口变小,我希望列缩小直到达到最小宽度。一旦他们击中了那个,中间的柱子就会跳下来换行。

我认为我的问题归结为这个——flexbox 可以检测到它何时换行吗?如果是这样,我可以提示它使用严格的 CSS 更改 wrap 上的项目的顺序吗?

这是我正在尝试使用媒体查询完成的codepen

.wrapper {
  display: flex;
  justify-content: center;
  margin: 5px;
  flex-wrap: wrap;
}

.red {
  background-color: red;
  height: 240px;
  margin: 5px;
  width: 500px;
  order: 0;
}

.yellow {
  background-color: yellow;
  margin: 5px;
  height: 240px;
  min-width: 240px;
  max-width: 400px;
  flex: 1;
  order: 1;
}

.blue {
  background-color: blue;
  height: 240px;
  margin: 5px;
  min-width: 350px;
  max-width: 400px;
  flex: 1;
  order: 2;
}

@media (max-width:1130px) {
  .yellow {
    order: 4;
  }
}
<div class="wrapper">
  <div class="red"></div>
  <div class="yellow"></div>
  <div class="blue"></div>
</div>

【问题讨论】:

    标签: html css flexbox media-queries


    【解决方案1】:

    flexbox 可以检测 flex 项目何时换行吗?

    没有。

    在 CSS 中,一旦浏览器在初始级联上呈现页面,它就不会在元素换行时重排文档。结果,父元素不知道它们的子元素何时换行。

    这就是容器在包装后不会收缩以适应其内容的原因。

    这就是您需要媒体查询或 JavaScript 的原因。

    这里有更多细节:

    【讨论】:

      【解决方案2】:

      我通过检查元素偏移量是否大于 0 来解决这个问题,因为包装的项目在下面会“弯曲”。这是我的功能:

      isHidden(id) {
          let el = document.getElementById(id);
          return (el.offsetTop > 0)
      }
      

      【讨论】:

        【解决方案3】:

        除了Citizens anwser,您可以使用偏移量并将其与其他元素进行比较:

        window.onresize = function (event) {
            let blu= document.getElementById("blue");
            let yel= document.getElementById("yellow");
            if (blu.offsetTop > yel.offsetTop) {
                // do something;
            } else {
                // do something;
            }
        }
        

        【讨论】:

          【解决方案4】:

          我注意到元素通常会相对于第一个元素进行换行。将每个元素的偏移顶部与第一个元素进行比较是一种更简单的方法。这适用于换行和换行。 (如果元素使用弹性顺序,可能不会起作用)

          var wrappers = $('.flex[class*="flex-wrap"]'); //select flex wrap and wrap-reverse elements
          
          if (wrappers.length) { //don't add listener if no flex elements
              $(window)
                  .on('resize', function() {
                      wrappers.each(function() {
                          var prnt = $(this),
                              chldrn = prnt.children(':not(:first-child)'), //select flex items
                              frst = prnt.children().first();
          
                          chldrn.each(function(i, e) { $(e).toggleClass('flex-wrapped', $(e).offset().top != frst.offset().top); }); //element has wrapped
                          prnt.toggleClass('flex-wrapping', !!frst.find('.flex-wrapped').length); //wrapping has started
                          frst.toggleClass('flex-wrapped', !!!chldrn.filter(':not(.flex-wrapped)').length); //all are wrapped
                     });
                  })
                  .trigger('resize'); //lazy way to initially call the above
          }
          .flex {
              display: flex;
          }
          
          .flex.flex-wrap {
              flex-wrap: wrap;
          }
          
          .flex.flex-wrap-reverse {
              flex-wrap: wrap-reverse;
          }
          
          .flex.flex-1 > * { /*make items equal width*/
              flex: 1;
          }
          
          .flex > * {
              flex-grow: 1;
          }
          
          .cc-min-width-200 > * { /*child combinator*/
              min-width: 200px;
          }
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          
          <div class="flex flex-1 flex-wrap-reverse cc-min-width-200">
              <div>Hello</div>
              <div>There</div>
              <div>World</div>
          </div>

          【讨论】:

            【解决方案5】:

            当我需要这样做时,我使用下面的 JS 来检测标题是否比预期的大,并为其添加一个类。

            <script>
                function handleflexwrap() {
                    if ($("#header").height() > 120) {
                        $("#header").addClass("wrapped");
                    } else {
                        $("#header").removeClass("wrapped");
                    }
                }
                //Check on load
                handleflexwrap();    
            
                //Check again on resize
                $(window).on('resize', function() {
                    handleflexwrap();
                });
            </script>
            

            然后我的 CSS 可以重新排序包装 div:

            #header.wrapped #navigation{
                order: 4;
            }
            

            #navigation 原本是“order: 2”,在三个元素的中间。换行时,它被设置为 4,因此移动到三个的末尾。

            【讨论】:

              猜你喜欢
              • 2014-03-31
              • 2020-03-22
              • 1970-01-01
              • 1970-01-01
              • 2016-03-21
              • 2020-07-19
              • 2022-11-15
              • 1970-01-01
              • 2018-12-23
              相关资源
              最近更新 更多