flexbox 可以检测 flex 项目何时换行吗?
Posted
技术标签:
【中文标题】flexbox 可以检测 flex 项目何时换行吗?【英文标题】:Can flexbox detect when a flex item wraps? 【发布时间】: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>
【问题讨论】:
【参考方案1】:flexbox 可以检测 flex 项目何时换行吗?
没有。
在 CSS 中,一旦浏览器在初始级联上呈现页面,它就不会在元素换行时重排文档。结果,父元素不知道它们的子元素何时换行。
这就是容器在包装后不会收缩以适应其内容的原因。
这就是您需要媒体查询或 javascript 的原因。
这里有更多细节:
Make container shrink-to-fit child elements as they wrap How to center a flex container but left-align flex items【讨论】:
【参考方案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,因此移动到三个的末尾。
【讨论】:
以上是关于flexbox 可以检测 flex 项目何时换行吗?的主要内容,如果未能解决你的问题,请参考以下文章
Flexbox/IE11:flex-wrap:换行不换行(里面有图片 + Codepen)