蜂巢布局,顾名思义,就是模仿蜜蜂蜂巢的六边形排列方式,将页面元素像蜂巢一样紧密排列。它不仅美观,还能最大化利用空间,让你的页面瞬间高级起来。

# 直接上效果

img

# 主要实现原理

# 1. 这里用了 CSS 的魔法: clip-path

.hex {
    clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
}

clip-path 的 polygon 是 CSS 中一个非常强大的函数,用于裁剪元素,让它们呈现出各种多边形的形状。 这行代码就像一把神奇的剪刀,把我们的方形图片剪成了完美的六边形。 这里简单介绍下

clip-path: polygon(x1 y1, x2 y2, x3 y3, ...);
- 每一对 `x y` 表示多边形的一个顶点。
- 坐标可以用百分比(相对于元素自身尺寸)或像素(不常用)表示。
- 顶点顺序很重要,最后一个点会自动与第一个点闭合。

除了多边形;还可以利用 clip-path 裁剪很多形状; 这里推荐下在线工具:https://tools.jb51.net/code/css3path 可视化生成 clip-path 代码,拖拖拽拽,轻松搞定!

img

但是只裁剪不行;只裁剪是这样的

img

所以还需要下面两招

# 2. 错落有致的布局技巧

.line:nth-child(2n) {
    transform: translateX(-5%);
}

这行代码是整个蜂巢效果的灵魂所在!它让偶数行的六边形向左偏移,创造出真正的蜂巢交错效果。

# 3. 微妙的重叠

.line:nth-child(n+2) {
    margin-top: -2%;
}

这个小技巧让每一行都稍微 "咬合" 在一起,就像真正的蜂巢细胞那样紧密相连。如果没有这个负边距,我们的蜂巢就会看起来像是被拉伸的!

# 完整代码

完整代码如下

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>蜂巢图片布局 Demo</title>
    <style>
        /* 页面整体背景与字体设置 */
        body {
            background: #000; /* 黑色背景,更突出图片 */
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Arial, sans-serif;
        }
        /* 外层容器,撑满整个视口高度 */
        .container {
            min-height: 100vh;
            width: 100%;
        }
        /* 蜂巢布局的主容器,负责包裹所有图片行 */
        .honeycomb {
            width: 100%;
            height: 100%;
            overflow: hidden; /* 防止溢出 */
        }
        /* 每一行图片的容器,使用flex横向排列 */
        .line {
            display: flex;
            flex-wrap: nowrap;
            align-items: center;
        }
        /* 偶数行向左错位,实现蜂巢交错效果 */
        .line:nth-child(2n) {
            transform: translateX(-5%);
        }
        /* 除第一行外,其余行顶部有微小重叠,增强蜂巢感 */
        .line:nth-child(n+2) {
            margin-top: -2%;
        }
        /* 单个六边形图片格子的样式 */
        .hex {
            position: relative;
            width: 10%; /* 响应式宽度,每行11个 */
            aspect-ratio: 1/1; /* 保持正六边形比例 */
            flex-shrink: 0;
            background: #fff;
            /* 六边形裁剪,polygon实现蜂巢形状 */
            clip-path: polygon(50% 0%,
                    95% 25%,
                    95% 75%,
                    50% 100%,
                    5% 75%,
                    5% 25%);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); /* 轻微阴影 */
            overflow: hidden;
            transition: transform 0.2s;
        }
        /* 图片自适应填充六边形格子 */
        .hex img {
            width: 100%;
            height: 100%;
            object-fit: cover; /* 保证图片不变形填满 */
            display: block;
            transition: transform 0.3s;
        }
        /* 鼠标悬停时六边形放大,提升交互感 */
        .hex:hover {
            transform: scale(1.08);
            z-index: 2;
        }
        /* 悬停时图片也略微放大 */
        .hex:hover img {
            transform: scale(1.1);
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="honeycomb">
            <!-- 图片行将由JS动态插入 -->
        </div>
    </div>
</body>
<script>
    // 图片资源列表,按顺序排列
     let imgList = [
            'img/g (1).png', 'img/g (2).png', 'img/g (3).png', 'img/g (4).png', 'img/g (5).png', 'img/g (6).png', 'img/g (7).png', 'img/g (8).png', 'img/g (9).png', 'img/g (10).png',
            'img/g (11).png', 'img/g (12).png', 'img/g (13).png', 'img/g (14).png', 'img/g (15).png', 'img/g (16).png', 'img/g (17).png', 'img/g (18).png', 'img/g (19).png', 'img/g (20).png',
            'img/g (21).png', 'img/g (22).png', 'img/g (23).png', 'img/g (24).png', 'img/g (25).png', 'img/g (26).png', 'img/g (27).png', 'img/g (28).png', 'img/g (29).png', 'img/g (30).png',
            'img/g (31).png', 'img/g (32).png', 'img/g (33).png', 'img/g (34).png', 'img/g (35).png', 'img/g (36).png', 'img/g (37).png', 'img/g (38).png', 'img/g (39).png', 'img/g (40).png',
            'img/g (41).png', 'img/g (42).png', 'img/g (43).png', 'img/g (44).png', 'img/g (45).png', 'img/g (46).png', 'img/g (47).png', 'img/g (48).png', 'img/g (49).png', 'img/g (50).png',
            'img/g (51).png', 'img/g (52).png', 'img/g (53).png', 'img/g (54).png', 'img/g (55).png', 'img/g (56).png', 'img/g (57).png', 'img/g (58).png', 'img/g (59).png', 'img/g (60).png',
            'img/g (61).png', 'img/g (62).png', 'img/g (63).png', 'img/g (64).png', 'img/g (65).png', 'img/g (66).png', 'img/g (67).png', 'img/g (68).png', 'img/g (69).png', 'img/g (70).png',
            'img/g (71).png', 'img/g (72).png', 'img/g (73).png', 'img/g (74).png', 'img/g (75).png', 'img/g (76).png'];
    // 获取蜂巢主容器
    const honeycomb = document.querySelector('.honeycomb');
    // 每行显示11个图片,分多行渲染
    for (let i = 0; i < imgList.length; i += 11) {
        const row = document.createElement('div'); // 创建一行
        row.classList.add('line');
        // 本行内依次插入图片
        for (let j = i; j < i + 11 && j < imgList.length; j++) {
            const hex = document.createElement('div'); // 六边形格子
            hex.classList.add('hex');
            const img = document.createElement('img'); // 图片元素
            img.src = imgList[j];
            hex.appendChild(img); // 图片放入六边形
            row.appendChild(hex); // 六边形放入行
        }
        honeycomb.appendChild(row); // 行放入蜂巢容器
    }
</script>
</html>