专业编程基础技术教程

网站首页 > 基础教程 正文

终极解决方案,再也不怕css绘制多边形了

ccvgpt 2024-07-28 12:32:12 基础教程 8 ℃

因为工作中遇到了需要绘制蜂巢效果的需求,所以我特地恶补了关于css绘制多边形的方案,目前找到的主流方案如下:

1.奇淫技巧:border模拟六边形拼接

虽然这种方法很讨巧,的事实上这种方法被广泛运用在前端实践中。

终极解决方案,再也不怕css绘制多边形了

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      display: grid;
      grid-template-columns: repeat(auto-fill, 100px);
      grid-gap: 5px;
      justify-content: center;
      padding: 20px;
      background-color: #f0f0f0;
    }

    .hexagon {
      position: relative;
      width: 100px;
      height: 57.74px;
      background-color: #ffd700;
      margin-bottom: -2px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* 添加阴影效果 */
    }

    .hexagon::before,
    .hexagon::after {
      content: '';
      position: absolute;
      width: 0;
      border-left: 50px solid transparent;
      border-right: 50px solid transparent;
    }

    .hexagon::before {
      top: -27.87px;
      border-bottom: 28.87px solid #ffd700;
    }

    .hexagon::after {
      bottom: -27.87px;
      border-top: 28.87px solid #ffd700;
    }
  </style>
  <title>Honeycomb Effect with Shadow</title>
</head>
<body>
    <div class="hexagon" style="position: relative;">
   
      </div>
      <div class="hexagon" style="position: relative;">
   
      </div>
  <!-- 添加更多蜂巢元素... -->
</body>
</html>


我们来看效果

看起来效果不错,但是因为我要给多变形状添加阴影,而上下的三角形是border模拟出的没办法添加,如果强行添加就会变成这样。

这显然不是我想要的效果,所以第一种方案pass

2.多重影分身:伪元素的魔法

事实正六边形可以抽象为3个长方形的旋转叠加,通过伪元素叠加就可以模拟出正六边形的效果。话不多说上代码

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.tailwindcss.com"></script>
    <title>Document</title>
    <style>
      .hexagon {           
           width: 104px;            
           height: 60px;            
           position: relative;            
           margin: 10px 40px;                  
        }        
        .hexagon__item {            
            width: 100%;            
            height: 100%;            
            background: blue;            
            position: absolute;            
            top: 30px;            
            left: 0;            
            visibility: hidden;            
            overflow: hidden;        
        }        
        .hexagon__item_left {            
            transform: rotate(-60deg);        
        }        
        .hexagon__item_right {            
            transform: rotate(60deg);        
        }        
        .hexagon__item:before {            
            position: absolute;            
            top: 0;            
            left: 0;            
            content: "";            
            height: 130px;            
            width: 100%;            
            visibility: visible;            
       
            background-color: #d9d32a;
                         background-size: cover;            
            transform-origin: 0 0;        
        }        
        .hexagon__item_left:before {            
            transform: rotate(60deg) 
             translateY(-70%);         
        }        
        .hexagon__item_right:before {            
            transform: rotate(-60deg) 
            translateX(-50%);        
        }        
        .hexagon__item_center:before {            
            transform: translateY(-25%);        
        }    
    </style>
  </head>

  <body>
    <div class="flex">
    <div class="hexagon">
      <div class="hexagon__item hexagon__item_left"></div>
      <div class="hexagon__item hexagon__item_center"></div>
      <div class="hexagon__item hexagon__item_right"></div>
    </div>
    <div class="hexagon">
        <div class="hexagon__item hexagon__item_left"></div>
        <div class="hexagon__item hexagon__item_center"></div>
        <div class="hexagon__item hexagon__item_right"></div>
      </div>
      <div class="hexagon">
        <div class="hexagon__item hexagon__item_left"></div>
        <div class="hexagon__item hexagon__item_center"></div>
        <div class="hexagon__item hexagon__item_right"></div>
      </div>
      <div class="hexagon">
        <div class="hexagon__item hexagon__item_left"></div>
        <div class="hexagon__item hexagon__item_center"></div>
        <div class="hexagon__item hexagon__item_right"></div>
      </div>
    </div>
  </body>

</html>


效果如下:

哇非常的完美,似乎我应该选择它了。BUT!!!当我将视口缩小,长方形div大小响应性变短。

糟了,因为该方案采用了复杂的拼接方式,所以如果我希望保持每个六边形的形状在响应性界面中,我必须通过js计算获得要最新的 长度 定位关系,而这显然过于复杂,也违背了css实现的初衷。

3.完美的化身:clip-path与 drop-shadow

前置介绍

clip-path 是一个用于裁剪元素形状的 CSS 属性,专门用来创造各种复杂的形状和效果。

drop-shadow 是 CSS 滤镜效果之一,用于为元素添加逼真的阴影效果。它使得开发者能够在元素的周围投射出模糊、透明的阴影,为页面元素增添立体感。

有了这两大神器,接下来就是秒杀时刻。上代码

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.tailwindcss.com"></script>
    <title>Document</title>
    <style>
      .btn-wrap {
   
    filter: drop-shadow(2px 4px 4px rgba(50, 50, 0, 0.39))
    drop-shadow(-1px -1px 0px rgba(242, 4, 4, 0.5));
}
.menu-cell {
    text-align: center;
    background: #ffffff;
    z-index: 1;
    -webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
    clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
    height: 17.5vw;
    /* line-height: 175px; */
    width: 15vw;
    margin: 6px;
    overflow: hidden; 
}
    </style>
  </head>

  <body>
    <div class="flex justify-start gap-x-3 ">
    <div class="btn-wrap">
   
      <div class="menu-cell">
      </div>
    </div>
    <div class="btn-wrap">
      
      <div class="menu-cell">
      </div>
    
    </div>
    <div class="btn-wrap">
    
      <div class="menu-cell">
      </div>
    
    </div>
  </body>

</html>


效果如下:

完美完成要求。且通过单位设置便可实现响应式大小。

总结:

最后虽然clip-path与 drop-shadow 可以带来巨大的方便以及编码的简洁,但是它们的兼容性是开发中要注意的问题。


作者:pancilandtao
链接:https://juejin.cn/post/7300779513910378507

Tags:

最近发表
标签列表