为什么Chrome无法正确处理jQuery添加的flexbox项目?

j08*_*691 3 html jquery css3 flexbox

我正在研究一些基本的flexbox代码,当我发现当我添加flex项目并且容器的方向设置为column或时,Chrome显示奇怪的行为column-reverse.这是一个简单的flexbox示例,它可以正常工作,方向设置为列并包装:

#flexbox_container {
    border: 8px solid #ccc;
    padding: 10px;
    height: 200px;
    display: flex;
    flex-direction:column;
    flex-wrap: wrap;
}
.flex_item {
    background: #eee;
    margin: 4px;
    padding: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<div id="flexbox_container">
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
    <div class="flex_item">Item</div>
</div>
Run Code Online (Sandbox Code Playgroud)

正如所料,当列数过大而不适合容器时,会创建第二列,每个项具有相等的宽度.

现在这是问题的一个例子.如果我们从一列的儿童弹性项开始,并使用jQuery继续添加更多,而不是像上面那样均匀划分,第一列占据整个宽度,新项目向侧面推出:

$('button').click(function() {
  $('#flexbox_container').append('<div class="flex_item">Item</div>');
})
Run Code Online (Sandbox Code Playgroud)
#flexbox_container {
  border: 8px solid #ccc;
  padding: 10px;
  height: 200px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
.flex_item {
  background: #eee;
  margin: 4px;
  padding: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="flexbox_container">
  <div class="flex_item">Item</div>
</div>
<button>button</button>
Run Code Online (Sandbox Code Playgroud)

然后让我感到困惑的是,如果我摆弄几乎任何CSS属性,我可以让Chrome排成一行并按照我的预期显示弹性项目(几乎就像重绘或重新计算布局一样).例如,这里我在插入新项目后快速更改flex项目的位置:

$('button').click(function() {
  $('#flexbox_container').append('<div class="flex_item">Item</div>');
  $('.flex_item').css('position', 'absolute')
  setTimeout(function() {
    $('.flex_item').css('position', 'relative')
  }, 0)
})
Run Code Online (Sandbox Code Playgroud)
#flexbox_container {
  border: 8px solid #ccc;
  padding: 10px;
  height: 200px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
.flex_item {
  background: #eee;
  margin: 4px;
  padding: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="flexbox_container">
  <div class="flex_item">Item</div>
</div>
<button>button</button>
Run Code Online (Sandbox Code Playgroud)

现在,这显然是一种解决问题的黑客方式,每次添加新项目时都会导致丑陋的闪烁.

那么为什么Chrome在使用jQuery插入时不能正确显示flex项目,而不必诉诸类似于对CSS属性的快速修改?

请注意,Firefox和Edge都没有此问题并按预期工作,添加-webkit-前缀不会更改结果.此外,这似乎只在flex-direction设置为column或时发生column-reverse.当它设置为rowrow-reverse它工作正常.

Ric*_*ock 5

有趣.您可以通过添加以下样式来解决问题:

#flexbox_container {
  overflow: auto;
}

#flexbox_container::-webkit-scrollbar {
  height: 0;
}
Run Code Online (Sandbox Code Playgroud)

花了一段时间才弄清楚滚动条的高度需要为0.

overflow单独使用,Chrome似乎执行以下操作:

  1. 添加元素.
  2. 如果需要,添加滚动条.
  3. 意识到这是一个flexbox,它不需要滚动条.
  4. 将列中的最后一个元素错误地定位到下一列的顶部.

删除滚动条CSS以查看我在说什么.

$('button').click(function() {
  $('#flexbox_container').append('<div class="flex_item">Item</div>');
})
Run Code Online (Sandbox Code Playgroud)
#flexbox_container {
  border: 8px solid #ccc;
  padding: 10px;
  height: 200px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  overflow: auto;
}
#flexbox_container::-webkit-scrollbar {
  height: 0;
}
.flex_item {
  background: #eee;
  margin: 4px;
  padding: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="flexbox_container">
  <div class="flex_item">Item</div>
</div>
<button>button</button>
Run Code Online (Sandbox Code Playgroud)