前言
最近做需求,遇到一个要实现一个蜂窝布局的ui
,特此记录一下实现过程。
最终效果如下
实现思路
- 用
clip-path
将一个四边形裁切成一个六边形
画一个六边形
用cli-path
属性画一个六边形
.item{
position: relative;
width: 60px;
height: 60px;
background: goldenrod ;
clip-path: polygon(
0 25%,
50% 0,
100% 25%,
100% 75%,
50% 100%,
0 75%
);
line-height: 60px;
text-align: center;
color:#fff;
}
画出来的效果如下,尺寸可以自由调整
布局
<div class="container">
<div class="hive"></div>
</div>
.row{
display: flex;
gap: 8px;
}
const layout = document.querySelector('.hive')
const items = new Array(120).fill('')
const rows = items.reduce((acc, curr, index) => {
if (index % 12 === 0) acc.push([])
acc[Math.floor(index / 24)].push(index)
return acc
}, [])
// 创建元素
rows.forEach((list, index) => {
const row = `<div class="row" ${index % 2 === 0 ? 'style="transform: translateX(-30px);"' : ""}>
${list.map(item => `<div class="item">${item}</div>`)
}
</div>`.replaceAll(',', '')
layout.insertAdjacentHTML('beforeend', row)
})
这边我用js
动态生成元素,以每行24个六边形,画了5行。
行都是用flex
布局进行排列
这时候还不像蜂窝,还需要对偶数行进行缩进
const layout = document.querySelector('.hive')
const items = new Array(120).fill('')
const rows = items.reduce((acc, curr, index) => {
if (index % 12 === 0) acc.push([])
acc[Math.floor(index / 24)].push(index)
return acc
}, [])
// 创建元素
rows.forEach((list, index) => {
const row = `<div class="row" ${index % 2 === 0 ? 'style="transform: translateX(-30px);"' : ""}>
${list.map(item => `<div class="item">${item}</div>`)
}
</div>`.replaceAll(',', '')
layout.insertAdjacentHTML('beforeend', row)
})
这边我对每一个偶数行用transform
向右移动六边形宽度的1/2,也就是-30px
。
这个位移的值一定是你的六边形宽度的一半
这样一个蜂窝布局就实现了。