javascript - flex 盒元素无法在 Chrome 上正确重新呈现

标签 javascript html css google-chrome flexbox

在以编程方式更改 flexbox 元素的尺寸或位置属性时,我遇到了不同的浏览器行为。布局不会返回到其在 Chrome 上的原始状态。

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

一种 js 解决方法是通过快速来回更改元素填充 1px 来强制布局重新呈现,但我想知道:

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

Chrome

当用户再次点击并重置 flex 元素样式时,不再考虑 flex-basis 并且布局被破坏。 Chrome

火狐

当用户再次点击并重置 flex 元素样式时,所有元素都会正确呈现。 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>

最佳答案

这个问题看起来不寻常,但修复起来相当简单。将 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>

关于javascript - flex 盒元素无法在 Chrome 上正确重新呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46521776/

相关文章:

css - 这种形式的元素之间的边距是什么

javascript - Material UI 的 CardHeader 操作样式

php - 如何将嵌套的 php 数组放入 javascript 中?

javascript - CoffeeScript + Mocha + Blanket,怎么做?

javascript - 按计算尺寸订购的试剂组件

javascript - Vue 中测量溢出不正确

javascript - 使用外部 JS 文件将 JS 与 HTML 分离

css - 如何覆盖 react-tab 的默认焦点 css 样式?

javascript - 如何从网络服务器为 FF 和 IE 安装 SSL 客户端证书?

html - 如何使 ul 与父 li 大小相同?