CSS Grid 与图片共存时的布局问题

本文最后更新于:2021年1月27日 上午

场景

在生产中遇到的一个 css 问题,css 不正交的问题一直有人吐槽,吾辈今天总算也是遇到了,实在是不吐不快。

CSS 为什么这么难学?

如下一个简单的二维横向图片列表

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .rows {
    height: 500px;
    display: grid;
    grid-template-rows: repeat(5, 1fr);
  }
  .cols {
    height: 100%;
    display: flex;
  }
  .item {
    height: 100%;
  }
  .item img {
    max-height: 100%;
  }
</style>
<main class="rows">
  <div v-for="items of list" class="cols">
    <div v-for="item of items" class="item">
      <img :src="item.url" />
    </div>
  </div>
</main>

<!-- 下面是生成一些测试数据,不需要关心 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/faker.js"></script>
<script>
  new Vue({
    el: ".rows",
    data: {
      list: Array(5)
        .fill(0)
        .map(() =>
          Array(faker.random.number({ min: 10, max: 20 }))
            .fill(0)
            .map(() => {
              const getNumber = () =>
                faker.random.number({ min: 200, max: 300 });
              return [getNumber(), getNumber()];
            })
            .map(([x, y]) => ({
              width: x,
              height: y,
              url: `https://picsum.photos/seed/picsum/${x}/${y}`,
            }))
        ),
    },
  });
</script>

但显示的效果却并非预想中那样五等份,而是会超过最大高度 – 被图片撑高了。

1611716016173.png

而在经过一番摸索和讨论后,吾辈找到了这个规范:https://drafts.csswg.org/css-grid/#algo-terms

grid 的 fr 单位实际上是个弹性值,如果内容过大,则会撑开。。。而图片的默认大小就是过大的内容。如果显式声明了最小值,就不受图片尺寸的影响了。

修改 grid-template-rows: repeat(5, 1fr); => grid-template-rows: repeat(5, minmax(0, 1fr)); 就好了。

效果

1611716716541.png

吐槽

发明 CSS 的人就是一个智障,这么多不正交的规则纯靠经验真的太恶心了(不是每个人都了解或者说希望了解那些奇奇怪怪的规范)。