Flex-box 项目无法在 chrome 上正确重新渲染
Posted
技术标签:
【中文标题】Flex-box 项目无法在 chrome 上正确重新渲染【英文标题】:Flex-box items don't re-render correctly on chrome 【发布时间】:2018-03-13 07:17:45 【问题描述】:在以编程方式更改尺寸或弹性框项目的位置属性时,我遇到了不同的浏览器行为。布局不会在 Chrome 上恢复到其原始状态。
在这个pen 中,当用户单击图像时,我将项目位置更改为绝对位置并修改其宽度和高度(实际上它可能是影响布局的任何东西,例如填充)。当用户再次单击时,我会回滚更改,因此我希望布局会相应地重置。
一个 js 解决方法是通过快速来回更改项目填充 1px 来强制重新渲染布局,但我想知道:
为什么会发生这种情况?是否有仅使用 css 的解决方法?
铬
当用户再次单击并重置 flex 项目样式时,不再考虑 flex-basis 并且布局被破坏。
火狐
当用户再次单击并重置 flex 项目样式时,所有项目都会正确呈现。
new Vue(
el: '#app',
data()
return
activeImageIndex: null,
images: [
url: 'https://unsplash.it/600',
style:
flexBasis: '50%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '50%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
]
,
methods:
onClick(index)
this.activeImageIndex = this.activeImageIndex === index ? null : index
,
)
#app
width: 800px;
.ig-container
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin: 0 -5px;
position: relative;
height: 500px;
.ig-item
flex: 1 1;
padding: 10px;
box-sizing: border-box;
.ig-item:hover>div
border-color: green;
.ig-item.active
position: absolute;
z-index: 3;
width: 100%;
height: 100%;
.ig-item.active img:hover
cursor: zoom-out;
.ig-item>div
height: 100%;
width: 100%;
background-color: blue;
position: relative;
border: 5px solid gainsboro;
overflow: hidden;
.ig-item .ig-overlay
position: absolute;
height: 100%;
width: 100%;
z-index: 3;
background-color: rgba(0, 0, 0, 0.4);
color: #fff;
font-size: 3rem;
display: flex;
align-items: center;
text-align: center;
.ig-item .ig-overlay span
width: 100%;
.ig-item img
height: 100%;
width: 100%;
object-fit: cover;
position: absolute;
z-index: 2;
transition: transform .3s;
.ig-item img:hover
cursor: zoom-in;
.ig-item .loading-overlay.ig-loading
position: absolute;
z-index: 1;
.ig-item .loading-overlay.ig-loading .loading-icon:after
top: -2.5em;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<div class="ig-container">
<div class="ig-item" :class="active: activeImageIndex === index" :style="image.style" v-for="(image, index) in images">
<div>
<img @click="onClick(index)" title="" :src="image.url">
</div>
</div>
</div>
</div>
【问题讨论】:
【参考方案1】:这个问题看起来不寻常,但修复相当简单。将min-height: 0
添加到.ig-item
。
问题可能在于浏览器如何显示弹性项目的 min-height
属性默认为 auto。
请看下面的演示:
new Vue(
el: '#app',
data()
return
activeImageIndex: null,
images: [
url: 'https://unsplash.it/600',
style:
flexBasis: '50%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '50%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
url: 'https://unsplash.it/600',
style:
flexBasis: '30%'
,
]
,
methods:
onClick(index)
this.activeImageIndex = this.activeImageIndex === index ? null : index
,
)
#app
width: 800px;
.ig-container
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin: 0 -5px;
position: relative;
height: 500px;
.ig-item
flex: 1 1;
padding: 10px;
box-sizing: border-box;
min-height: 0; /* ADDED */
.ig-item:hover>div
border-color: green;
.ig-item.active
position: absolute;
z-index: 3;
width: 100%;
height: 100%;
.ig-item.active img:hover
cursor: zoom-out;
.ig-item>div
height: 100%;
width: 100%;
background-color: blue;
position: relative;
border: 5px solid gainsboro;
overflow: hidden;
.ig-item .ig-overlay
position: absolute;
height: 100%;
width: 100%;
z-index: 3;
background-color: rgba(0, 0, 0, 0.4);
color: #fff;
font-size: 3rem;
display: flex;
align-items: center;
text-align: center;
.ig-item .ig-overlay span
width: 100%;
.ig-item img
height: 100%;
width: 100%;
object-fit: cover;
position: absolute;
z-index: 2;
transition: transform .3s;
.ig-item img:hover
cursor: zoom-in;
.ig-item .loading-overlay.ig-loading
position: absolute;
z-index: 1;
.ig-item .loading-overlay.ig-loading .loading-icon:after
top: -2.5em;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<div class="ig-container">
<div class="ig-item" :class="active: activeImageIndex === index" :style="image.style" v-for="(image, index) in images">
<div>
<img @click="onClick(index)" title="" :src="image.url">
</div>
</div>
</div>
</div>
【讨论】:
以上是关于Flex-box 项目无法在 chrome 上正确重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 flex-box 和 styled-components 水平排列项目列表
检测css“flex-box”和“flex-wrap”支持的正确方法是啥?
CSS flex-box:尽管 justify-content 和 align-items 设置正确,但文本并不完全居中