css实现六边形布局的两种方案

316 阅读2分钟

方案一

效果:

<ul>  
  <li>1</li>  
  <li>2</li>  
  <li>3</li>  
  <li>4</li>  
  <li>5</li>  
  <li>6</li>  
  <li>7</li>  
  <li>8</li>  
  <li>9</li>  
  <li>10</li>  
  <li>11</li>  
  <li>12</li>  
  <li>14</li>  
  <li>15</li>  
  <li>16</li>  
  <li>17</li>  
  <li>18</li>  
  <li>19</li>  
  <li>20</li>  
  <li>21</li>  
  <li>22</li>  
  <li>23</li>  
  <li>24</li>  
  <li>25</li>  
</ul>
ul{  
  width: 600px;  
  display: grid;  
  grid-template-columns: repeat(11, 1fr);  
  grid-gap: 10px;  
  padding: 0;  
}  
  
li {  
  display: flex;  
  align-items: center;  
  justify-content: center;  
  grid-column-end: span 2;  
  color: white;  
  cursor: pointer;  
  aspect-ratio: 1 / 1.1547;  
  clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);  
  background: deepskyblue;  
  transition: all .3s;  
}  
li:nth-child(10n-4){  
  grid-column-start: 2;  
}  
li:nth-child(n+6){  
  /*这里使用了一个近似值,不完全准确*/  
  margin-top: -30.25px;  
}  
li:hover{  
  transform: scale(1.1);  
}

关键点:

1、ul采用grid布局,如果一行要展示n个六边形,则一行分为2n+1列

2、每个六边形占两列的宽度,并使用aspect-ratioclip-path将每块裁剪成六边形

3、li:nth-child(10n-4){ grid-column-start: 2; }对偶数行的起始六边形向右偏移1列的距离

4、li:nth-child(n+6){ margin-top: -30.25px; } 对除第一行的六边形向上偏移一定距离,这个偏移值可以具体计算出来,这里使用了一个近似值

方案二

效果:

<ul>  
  <li>1</li>  
  <li>2</li>  
  <li>3</li>  
  <li>4</li>  
  <li>5</li>  
  <li>6</li>  
  <li>7</li>  
  <li>8</li>  
  <li>9</li>  
  <li>10</li>  
  <li>11</li>  
  <li>12</li>  
  <li>14</li>  
  <li>15</li>  
  <li>16</li>  
  <li>17</li>  
  <li>18</li>  
  <li>19</li>  
  <li>20</li>  
  <li>21</li>  
  <li>22</li>  
  <li>23</li>  
  <li>24</li>  
  <li>25</li>  
</ul>
ul {  
  list-style: none;  
  padding: 0;  
  max-width: 1000px;  
  left: 0;  
  right: 0;  
  margin: auto;  
  position: relative;  
  height: 1000px;  
  font-size: 0;  
}  
ul:before {  
  content: " ";  
  width: 65px;  
  float: left;  
  height: 120%;  
  --f: 186px;  
  shape-outside: repeating-linear-gradient(  
  transparent 0,  
  transparent var(--f),  
  black var(--f),  
  black calc(var(--f) + 2px),  
  transparent calc(var(--f) + 2px),  
  transparent 228px  
);  
background: repeating-linear-gradient(  
  transparent 0,  
  transparent var(--f),  
  black var(--f),  
  black calc(var(--f) + 2px),  
  transparent calc(var(--f) + 2px),  
  transparent 228px  
);  
}  
ul li {  
  display: inline-block;  
  width: 120px;  
  margin: 5px ;  
  margin-bottom: -30.6px;  
  aspect-ratio: 1 / 1.1547;  
  clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);  
  background: deepskyblue;  
  color: white;  
  transition: all .3s;  
}  
li:hover {  
  transform: scale(1.1);  
}

关键点:

1、ul确定了容器的大小,重要的是 height: 1000px;font-size: 0;确定了容器的高度和把字体设置为0

2、li采用inline-block的方式进行布局,并且使用 aspect-ratio: 1 / 1.1547; clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%); 裁剪成六边形

3、ul设置before的浮动元素,并且设置shape-outside,这个的具象形状的体现见background,它将偶数行的六边形向右推半个六边形的距离

4、li设置margin-bottom: -30.6px; 将除第一行的六边形往上移动,这里是近似值