CSS 实现类似 Google Photos 的图片布局
· 阅读需 9 分钟
今天在 medium 看到一篇关于 Google Photos 的文章,里面详细的介绍了谷歌的一名工程师是如何设计 Google Photos 的布局的,文章地址:Building the Google Photos Web UI。
观察了一下 Google Photos 的布局,发现它的布局非常的有意思,有以下特点:
- 一行图片的宽度始终刚 好占满容器宽度
- 图片全部保持原始比例,不会被拉伸
- 图片的高度不一,但是每一行的高度是一样的
- 图片顺序不会被改变
感觉很神奇,但是那篇文章里的实现方法太过复杂,虽然性能非常好,但是我觉得可以用更简单的方法来实现,于是就有了这篇文章。
我所设想的实现需要满足:
- 一行图片的宽度始终刚好占满容器宽度
- 除非比例十分极端,图片保持原始比例,不会被拉伸
- 图片的高度不一,但是每一行的高度是一样的
- 图片顺序不会被改变
- 前端纯 CSS 实现,不需要 JS
- 性能可以一般,但代码必须简单
实现
首先我在网上搜索了一下,发现有人已经思考过这个问题。比如这篇文章:使用纯 CSS 实现 500px 照片列表布局。虽然文中的做法可以实现,但是我还是觉得有点复杂。
经过一段时间思考,我想到一个使用暴力实现的方法,虽然不够优雅,但是实现起来非常简单,而且性能也不错。
实现思路主要依靠两点:object-fit
属性和 Flex 布局的 flex-grow
。
step 1: 初步可行
首先定义一个图片的初始最小宽度,比如 200px
,根据图片宽高比进行调整:
const initWidth = 200 * image.width / image.height;
这里使用了 JavaScript 计算,但实际上这部分计算应该在服务端进行,所以用什么语言实现都是一样的。 也并没有违背前端纯 CSS 实现的要求,因为这部分计算可以在服务端生成 CSS 代码,然后直接返回给浏览器。 看到后面的例子就会明白。浏览器直接禁用 JavaScript 也不会影响布局。