CSS3 clip-path 属性的使用示例(平行四边形的 tab按钮 / 不规则八边形弹框边角效果 / ...)不支持 IE 哦


一. clip-path 介绍

  • clip-path 属性:使用裁剪方式创建元素的可显示区域,区域内的部分显示,区域外的隐藏。    —— MDN 文档

  • 一个 clip-path 在线生成的工具网站:http://tools.jb51.net/code/css3path

  • 用上面的图做例子,假设这个九边形 div 被我设置了 cursor: pointr 属性,那么九边形之外的区域鼠标滑过不会显示手势,而九边形之内的区域可以
  • 注意:clip-path 属性不支持 IE

二. clip-path 示例

2.1 平行四边形的 tab 按钮

  • 设计稿如上图,我最初构想的实现方案是:
  1. 通过叠加多个背景图片,实现两边固定,中间自适应增长的背景效果;
  2. 将 div 的 margin 值调整一下,实现减小 tab 按钮间距的效果;

  • 这种方案存在的问题:
  • 关于背景 bug:仔细看按钮背景图会发现,中间是固定的,那个小光点高光效果,不可以被拉伸,自适应势必无法很好的展现设计图效果
  • 关于点击 bug:即使背景改变成平行四边形的样子,给他们加点击事件就会暴露他是矩形的事实,修改间距会导致点击上图中的平行四边形角落,会触发别的平行四边形的事件,如下图所示,调整边距会导致 div 部分重合,进而导致点击事件混乱

  • 综上所述,把 div 的 默认形状 改成 平行四边形,是最好的解决方案
  • 我这用的是 Vue3 组件,按钮样式是传进去的,不要在意写法(…)
  • 逻辑:通过 clip-path 调整 div 形状,通过 margin 调整 div 间距,背景就放正常的整张图片,而不是拼接多张背景图片
      // 控制按钮大小、背景、位置的样式
      const tabItemStyle = {
        width: '1120px',
        height: '250px',
        // 这里 margin-left 负责调整按钮间距,如果按钮向右歪,就改成 margin-right
        marginRight: '-380px',
        // 这里是把按钮裁剪成平行四边形的形式,防止 div 重合影响点击事件
        WebkitClipPath: 'polygon(0% 95%, 0% 0%, 96% 0%, 95% 92%)',
        clipPath: 'polygon(0% 95%, 0% 0%, 96% 0%, 95% 92%)',
      };

            cStyle: {
              // 按钮容器样式
              tab: {
                // 默认状态
                default: {
                  ...tabItemStyle,
                  // 正常传入整张背景图片,不要拼接多张
                  background: 'url(./assets/tab-right-default.png) no-repeat',
                  backgroundSize: '100% 100%',
                },
                // 激活状态
                active: {
                  ...tabItemStyle,
                  background: 'url(./assets/tab-right-light.png) no-repeat',
                  backgroundSize: '100% 100%',
                },
              },
            },

2.2 不规则弹框边角效果

  • 设计稿如上图,我最初构想的实现方案是:UI 直接切个背景(…)
  • 先不说 图片啥的影响请求速度啥的了,公司 UI 比较忙,不敢没事找他【碎碎念】

  • 认识了新属性 clip-path 之后,我可以更优雅的实现这个效果了
  • 分析一下弹框边角本质:就是个八边形 
  • 其实写好了左上角之后,其他的边角直接 transform: rotate(); 即可

  • html 结构:外框 .dialog-outer,其内部包含了 弹框边角 及 内容区域
    <div class="dialog-outer">
      <div>内容</div>
      <!-- 弹框的背景角落部分 -->
      <i class="left-top-bg"></i>
      <i class="left-bottom-bg"></i>
      <i class="right-top-bg"></i>
      <i class="right-bottom-bg"></i>
    </div>

  • css 样式:
  1. 给 .dialog-outer 设置相对定位,一定要设置 border-radius: 40px; 防止边角盖不住
  2. 四个边角设置绝对定位,将左上角写好样式(宽高、渐变背景、形状)
  3. 依据左上的边角进行旋转 transform: rotateX(180deg) rotateY(180deg);
    /* 弹窗外层容器 */
    .dialog-outer {
      /* 外框相对定位 */
      position: relative;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
      width: 100%;
      height: auto;
      background: rgba(12, 28, 64, 0.8);
      border-radius: 40px;
      padding: 92px;
      /* 解决 padding的负面效果 */
      box-sizing: border-box;
    }

    /* 弹框背景 */
    .left-top-bg,
    .left-bottom-bg,
    .right-top-bg,
    .right-bottom-bg {
      /* 边角绝对定位 */
      position: absolute;
      width: 90px;
      height: 90px;
      /* 实现边角渐变效果 */
      background: linear-gradient(0deg, #D1A558, #F3DB86);
      /* 切割边角八边形形状 */
      clip-path: polygon(30% 0%, 70% 0%, 70% 6%, 32% 6%,
                 6% 33%, 6% 70%, 0% 70%, 0% 30%);
    }
    .left-top-bg {
      top: -3px;
      left: -2.5px;
    }
    .right-top-bg {
      top: -3px;
      right: -2.5px;
      /* 根据左上角的边角效果进行旋转 */
      transform: rotateY(180deg);
    }
    .left-bottom-bg {
      bottom: -3px;
      left: -2.5px;
      transform: rotateX(180deg);
    }
    .right-bottom-bg {
      bottom: -3px;
      right: -2.5px;
      transform: rotateX(180deg) rotateY(180deg);
    }

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值