Flex-box项目无法在chrome上正确重新呈现

时间:2017-10-02 08:12:54

标签: javascript html css google-chrome flexbox

当以编程方式更改尺寸或弹性框项目的位置属性时,我遇到了不同的浏览器行为。布局未在Chrome上恢复其原始状态。

在此pen中,当用户点击图片时,我将项目位置更改为绝对并修改其宽度和高度(实际上它可能是影响布局的任何内容,例如填充)。当用户再次单击时,我回滚了更改,因此我希望布局相应地重置。

一个js的解决方法是通过快速地将项目填充来回改变1px来强制布局重新渲染,但我想知道:

为什么会发生这种情况,是否只有css解决方法?

当用户再次单击并重置弹性项目样式时,不再考虑弹性基础并且布局中断。 Chrome

火狐

当用户再次单击并重置弹性项目样式时,将正确呈现所有项目。 Firefox

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 个答案:

答案 0 :(得分:3)

该问题看起来异常,但修复相当简单。将min-height: 0添加到.ig-item

可能问题似乎是浏览器如何表明默认情况下flex项目的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>