深色底上铺着一整片蜂巢:十四张照片被裁成正六边形,行与行之间交错半格,边缘彼此咬合,中间没有一条多余的缝。照片默认是压暗的低饱和状态,像一堵安静的墙;鼠标移上去,这一块整体向上抬起、投影加深、灰度褪去、图片轻微放大,同时底部浮起一层渐变,标题与分类文字从下方滑进来。用键盘 Tab 走一遍,同样能触发,并且会出现一圈白色的六边形描边作为焦点提示。
整套效果没有一行 JavaScript。六边形的形状、行间的咬合、悬停的层次变化,全部由 CSS 完成,其中最关键的是——蜂巢的行距不是试出来的,而是用根号三算出来的。
这面蜂巢图片墙的四个关键设计
六边形用裁剪路径切出来。一个六点的多边形裁剪同时作用在图片容器和焦点描边上,形状统一;容器设了溢出隐藏,所以图片放大时不会越出六边形。
行距由几何关系推导。变量里定义了根号三的近似值,高度、水平外边距、垂直外边距都由宽度和间距推算,改宽度或间距时整片蜂巢自动保持咬合。
错行靠一条选择器完成。用 nth-child 按固定周期给某几个元素加上半格的左边距,就把矩形的换行排布变成了交错的蜂巢,不需要给每一行套容器。
投影打在形状上而不是盒子上。用的是 drop-shadow 滤镜而非普通阴影,所以影子是沿着六边形轮廓的,不会露出方形的角。
蜂巢布局里的那点数学
其一,高宽比是固定的。正六边形(尖角朝上)的高等于宽乘以二再除以根号三,样式里就是这么写的:
--hex-height: calc(var(--hex-width) * 2 / var(--sqrt3));
这一条保证了六个边等长,形状不会被压扁。裁剪路径里的 25% 和 75% 两个纵向节点也正是基于这个比例——若你只改高度不改比例,六边形会立刻变成不规则的六角形。
其二,垂直外边距是负的。相邻两行必须重叠四分之一个高度才能咬合,所以垂直外边距被算成一个负值,让下一行往上收。这也是为什么容器要加一个正向的内边距把首尾行“还”回来,否则整片蜂巢的上下会被裁掉一截。
其三,悬停时提层级很有必要。放大和抬起会让当前六边形超出自己的格子,如果不提高层叠顺序,它会被后面的兄弟元素压住一角。源码在悬停与焦点态都提了层级,这一步常被忽略,却是“为什么我的悬停放大有一块被切掉”的常见答案。
拿到源码后能改什么
尺寸只有两个变量:六边形宽度和间距。改宽度整片墙自动缩放,改间距会同时影响水平和垂直咬合——两者都由公式推导,不需要手动调数值。每行几个由容器宽度决定,容器宽度写成“宽度加间距”的整数倍,改这个倍数即可控制列数。
错行的周期写在那条 nth-child 规则里。当前设置对应的是一种交错节奏,若你把每行数量改了,这个周期需要相应调整,否则错行会落在错误的位置——这是改列数时唯一需要同步改的地方。
视觉风格方面:默认状态的灰度、亮度、对比度三个滤镜值决定“未选中”的质感,悬停态是另一组;六边形内部还叠了一层由中心向外压暗的径向渐变,悬停时淡出。想做浅色主题,把背景渐变和这层压暗一起改即可。文字用了衬线标题加无衬线小字的搭配,中文回退已经配好。
运行提示:效果依赖 clip-path 与 drop-shadow 滤镜,主流浏览器近年版本均已支持。字体从网络加载,离线时会退回系统字体,布局不受影响。页面可直接双击 index.html 打开,无需服务器。建议使用近两年版本的 Chrome、Edge、Firefox 或 Safari。详细运行方法请参见压缩包内的帮助文档。
关于六边形图片墙的常见问题
能不能改成平角朝上的六边形?
可以,把裁剪路径的六个点换成横向版本,并把高宽比公式反过来(高为宽乘根号三除二),同时错行改为纵向偏移。改动集中在变量与那条裁剪路径上。
手机上会怎么显示?
容器宽度是按固定倍数算的,窄屏下会溢出。建议加一条媒体查询,在小屏上把六边形宽度调小、列数减少,公式会自动处理其余部分。
点击能不能弹出大图?
元素已经带了按钮语义和可聚焦属性,接一个轻量灯箱只需要监听点击并读取图片地址。若不想引入脚本,也可以用原生的对话框元素配合锚点实现。
为什么我换了图片以后有的六边形空了一块?
多半是图片比例差异导致的。图片设了等比裁剪填充,但源图过窄时边缘可能不足;建议统一使用接近正方形的素材,或把图片的裁剪定位调整为居中偏上。
这面墙适合用在哪里
蜂巢排布天然适合“成员”“分类”“作品”这类同质内容:团队成员照片墙、摄影作品集、产品分类入口、赛事选手介绍、荣誉展示。因为纯 CSS 实现,接进任何技术栈都没有负担,也不受脚本加载失败影响。几何推导、错行规则与悬停层次的完整写法都在源码里,注释分节清晰,下载后可查看。