>  기사  >  웹 프론트엔드  >  CSS로 그래디언트 툴팁을 구현하는 방법

CSS로 그래디언트 툴팁을 구현하는 방법

青灯夜游
青灯夜游앞으로
2021-07-13 17:38:352412검색

이 글에서는 CSS를 사용하여 그라디언트를 지원하는 툴팁을 구현하는 방법을 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

CSS로 그래디언트 툴팁을 구현하는 방법

오늘은 매우 일반적인 상호 작용인 tooltips을 살펴보겠습니다. 일반적으로 프롬프트 상자는 아래와 같은 단색입니다

CSS로 그래디언트 툴팁을 구현하는 방법

이러한 유형의 레이아웃 구현은 복잡하지 않습니다. 둥근 직사각형과 작은 삼각형을 이어붙이고 동일한 색상을 설정하면 됩니다

CSS로 그래디언트 툴팁을 구현하는 방법

이 기사의 초점은 아닙니다. 관심이 있으시면 css-tips (codepen.io)를 방문하세요

https://codepen.io/xboxyan/pen/MLJjWQ

가끔, 제품의 기능을 강조하거나 디자인 트렌드를 따르기 위해 디자인에서는 lulu UI Edge 버전의 Tips 구성 요소와 같은 그라데이션 배경을 사용합니다

CSS로 그래디언트 툴팁을 구현하는 방법

아직 "접속" 방법을 사용하는 경우 , 불일치로 인한 문제가 필연적으로 있을 것이고, 명백한 문제가 있을 것입니다 "분리"느낌, 시각적 복원이 크게 감소할 것입니다

CSS로 그래디언트 툴팁을 구현하는 방법

그렇다면 어떻게 이런 효과를 얻을 수 있을까요? 함께 살펴보시죠

1. 클립 경로 자르기

clip-path는 많은 분들이 바로 떠올릴 수 있는 방법일 것입니다. 그러나 실제 작업에서는 여전히 많은 문제에 직면하게 됩니다

  • clip-path: path는 모든 모양을 지원할 수 있지만 적응형 너비와 높이를 구현할 수는 없습니다

  • clip-path:polygon은 가능합니다. 작은 크기의 날카로운 모서리를 얻을 수 있지만 둥근 모서리는 얻을 수 없습니다

  • clip-path: inset은 적응형 둥근 직사각형을 얻을 수 있지만 아래의 작고 날카로운 모서리는 얻을 수 없습니다

이 문제를 해결하는 방법은 무엇입니까? 실제로 2와 3을 결합하면 됩니다. 여기에는

::before

::after로 대체할 수 있는 동일한 크기의 두 개의 컨테이너가 필요합니다. 그런 다음 사용자 정의를 통해 정의할 수 있는 동일한 배경색을 설정합니다. 속성

.tips{
   position: relative;
   --bg: linear-gradient(45deg, #ff3c41, #ff9800);
}
.tips::before,.tips::after{
  content:'';
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background: var(--bg);/*完全相同的背景*/
  z-index: -1;
}

왜 같은 크기의 용기 두 개를 사용하나요?

자를 때 그라데이션 배경이 완벽하게 일치하는지 확인하기 위한 것입니다

CSS로 그래디언트 툴팁을 구현하는 방법 그런 다음 그 중 하나를 둥근 직사각형으로 자르고 다른 하나를 작은 삼각형으로 자른 다음

overlap

하면 완료

.tips::before{
  clip-path: inset(0 0 5px 0 round 5px);
  /*round 可以设置圆角*/
}
.tips::after{
  clip-path: polygon(calc(50% - 5px) calc(100% - 5px), calc(50% + 5px) calc(100% - 5px), 50% 100%);
  /* 实现小三角,只需要3个点的坐标就可以了 */
}
를 볼 수 있습니다 프롬프트 상자는 완전히 적응 가능하며 실시간 효과는 다음과 같습니다

CSS로 그래디언트 툴팁을 구현하는 방법

전체 코드는 tooltips-clip-path (codepen.io)

https://codepen.io/xboxyan/에 액세스할 수 있습니다. pen/ExWLyKR

2. 마스크 Mask

clip-path

외에 mask도 아이디어입니다. mask에 대해 잘 모르신다면 이 글을 참고해주세요

Wonderful CSS MASK (juejin.im)

https://juejin.cn/post/6846687594693001223

원리는 다음과 같습니다

CSS로 그래디언트 툴팁을 구현하는 방법

mask

을 사용하면 이제 질문은 다음과 같습니다. CSS를 통해 이러한 그래픽을 그리는 방법은 무엇입니까?

CSS로 그래디언트 툴팁을 구현하는 방법1. 만능 그래디언트

CSS 그래디언트

로 그릴 수 없는 그래픽은 없으며 이것도 예외는 아닙니다. 먼저 이 그래픽을 둥근 직사각형삼각형으로 나눌 수 있습니다. 삼각형이 더 쉽습니다. 원추형 그라데이션 또는 선형 그라데이션을 통해 그릴 수 있습니다. 약간 번거롭지만 여전히 분해할 수 있습니다. 다음과 같이

CSS로 그래디언트 툴팁을 구현하는 방법 4개의 방사형 그래디언트와 2개의 선형 그래디언트로 합성할 수 있으며 코드에서의 구현은

tips{
  -webkit-mask-image: 
    /*4个径向渐变和2个线性渐变*/
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    linear-gradient(red,red),
    linear-gradient(blue,blue);
  -webkit-mask-size:
    10px 10px,
      10px 10px,
    10px 10px,
    10px 10px,
    100% calc(100% - 15px),
    calc(100% - 10px) calc(100% - 5px)
  -webkit-mask-position:
    left top,
    right top,
    left 0 bottom 5px,
    right 0 bottom 5px,
    left 5px,
    5px top;
  -webkit-mask-repeat: no-repeat
}

입니다. , 원활하게 쓰시면 됩니다

하지만...CSS로 그래디언트 툴팁을 구현하는 방법

太长了,有很多重复的(4个radial-gradient),非常啰嗦,有没有什么办法优化呢?这里有一个技巧,碰到重复有规律的东西,可以多想想 repeat,利用背景的平铺特性,合理设置背景尺寸就可以了,如下

CSS로 그래디언트 툴팁을 구현하는 방법

可以看到,背景尺寸设置成 calc(100% - 10px) 就可以达到平铺效果,代码实现就是

tips{
  -webkit-mask-image: 
    /*只需要一个径向渐变即可*/
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    linear-gradient(red,red),
    linear-gradient(blue,blue);
  -webkit-mask-size:
    calc(100% - 10px) calc(100% - 15px),/*圆角的尺寸,高度由于还需要减去三角形尺寸,所以多了5px*/
    100% calc(100% - 15px),
    calc(100% - 10px) calc(100% - 5px);
  -webkit-mask-position:
    left top,
    left 5px,
    5px top;
  -webkit-mask-repeat: repeat,no-repeat,no-repeat;
}

是不是精简了许多?然后再把三角形的合过来就行了,可以得到如下效果

1CSS로 그래디언트 툴팁을 구현하는 방법

完整代码可访问 tooltips-mask-gradient (codepen.io)

https://codepen.io/xboxyan/pen/KKWRWOj

2. 自适应的svg

尽管做了一些优化,上面的代码量仍然非常可观,有没有更加简便的方式呢?

想到了 svg...

一般情况下,svg 路径是固定尺寸的,只能 等比缩放 ,无法做到自适应。不过基本图形是支持自适应的,可以设置百分比尺寸,比如 <rect></rect>

<svg xmlns=&#39;http://www.w3.org/2000/svg&#39; width=&#39;100%&#39; height=&#39;100%&#39;>
   <rect rx="5" width=&#39;100%&#39; height=&#39;100%&#39;/>
</svg>

rx 可以设置矩形的圆角,当不设置 ry 时,默认与 rx  相同

这样一个 svg 是可以自适应的,在改变尺寸的情况下不会变形(注意观察圆角),如下

1CSS로 그래디언트 툴팁을 구현하는 방법

三角形就很容易了,可以用 <polygon></polygon> 实现

<svg xmlns=&#39;http://www.w3.org/2000/svg&#39;>
  <polygon points=&#39;0 0,10 0,5 5&#39; />
</svg>

然后,把两段 svg 直接用作遮罩背景就行了,可以用 mask-size 和 mask-position 分别设置 尺寸位置

tips{
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns=&#39;http://www.w3.org/2000/svg&#39;><polygon points=&#39;0 0,10 0,5 5&#39; /></svg>"),url("data:image/svg+xml,<svg xmlns=&#39;http://www.w3.org/2000/svg&#39;><rect rx=&#39;6&#39; width=&#39;100%&#39; height=&#39;100%&#39;/></svg>");
  -webkit-mask-size: 10px 5px, 100% calc(100% - 5px);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center bottom, 0 0;
}

svg 用作背景需要在前面添加 data:image/svg+xml ,并且内容需要转义,详细可参考这篇文章: 

学习了,CSS中内联SVG图片有比Base64更好的形式

https://www.zhangxinxu.com/wordpress/2018/08/css-svg-background-image-base64-encode/

还是挺不错的,代码量也不多,也比较容易理解,实时效果如下

1CSS로 그래디언트 툴팁을 구현하는 방법

完整代码可访问 tooltips-mask-svg (codepen.io)

https://codepen.io/xboxyan/pen/poeVrqB

三、paint 绘制

再来介绍一种未来的解决方式, CSS paint 。关于 CSS paint,又称 “CSS 界的绘图板”,简单来说,就是用 canvas 绘图的方式来绘制背景,canvas 几乎什么都能绘制吧,所以这是一种更为通用的解决方案。想快速了解  CSS paint 的可以参考这一篇入门文章:

CSS届的绘图板CSS Paint API简介

https://www.zhangxinxu.com/wordpress/2018/11/css-paint-api-canvas/

不过目前仅支持 Chrome,兼容性如下

CSS로 그래디언트 툴팁을 구현하는 방법

不过并不影响我们的学习,毕竟是未来的解决方案,先看看大致的语法,如下

1、首先,JS 注册模块 registerPaint

// paint-tips.js
registerPaint(&#39;tips-bg&#39;, class {
    paint(ctx, size, properties) {
       // 在这里绘制背景,语法和canvas类似
    }
});

2、接着,JS 添加模块 CSS.paintWorklet.addModule

if (window.CSS) {
    CSS.paintWorklet.addModule(&#39;paint-tips.js&#39;);
}

3、最后,CSS 中使用 paint(tips-bg)

tips{
  -webkit-mask-image: paint(tips-bg); /*这里作为遮罩背景使用*/
}

下面就来绘制提示框了,如果仍然借助 mask ,那么问题就变成了:如何通过 canvas 绘制这样一个图形?

1CSS로 그래디언트 툴팁을 구현하는 방법

在 canvas 中,相对于 CSS 来说, 这类图形简直就是小儿科,只需要使用 lineToarc 两个指令就可以绘制了。最关键的一点是,这里的尺寸是实时渲染的,可以通过 size 来获取

关于 canvas 学习,这里推荐一下张鑫旭老师的 Canvas API中文文档,api 和 案例比 mdn 文档清晰太多

https://www.canvasapi.cn/

绘制代码如下(下面就是很普通的 canvas 代码了,其实就是几段线段连接起来,然后填充纯色)

registerPaint(&#39;tips-bg&#39;, class {
    paint(ctx, size) { // ctx为绘制上下文,size为容器尺寸
      const { width,height } = size; // 容器尺寸
      const radius = 5; // 圆角大小
      const deg = Math.PI / 2;
      const edge = 5; // 三角形大小
      const pos = width / 2; // 三角形位置
      ctx.beginPath();
      ctx.moveTo(radius,0);
      ctx.lineTo(width-2*radius,0);
      ctx.arc(width-radius,radius,radius,-deg,0);
      ctx.lineTo(width,height-2*radius-edge);
      ctx.arc(width-radius,height-radius-edge,radius,0,deg);
      ctx.lineTo(pos+edge,height-edge);
      ctx.lineTo(pos,height);
      ctx.lineTo(pos-edge,height-edge);
      ctx.lineTo(radius,height-edge);
      ctx.arc(radius,height-radius-edge,radius,deg,2*deg);
      ctx.lineTo(0,radius-edge);
      ctx.arc(radius,radius,radius,-2*deg,-deg);
      ctx.closePath();
      ctx.fillStyle = &#39;#000&#39;;
      ctx.fill();
   }
});

实时效果如下

1CSS로 그래디언트 툴팁을 구현하는 방법

完整代码可访问 tooltips-mask-paint (codepen.io)

https://codepen.io/xboxyan/pen/JjWvxEN

另外,也可以通过 CSS 变量进行自定义,比如定义一个--r为圆角大小,--t为三角形大小

<tips style="--r:5;--t:5"></tips>
registerPaint(&#39;tips-bg&#39;, class {
  static get inputProperties() { // 定义允许的自定义属性
    return [
      &#39;--r&#39;,
      &#39;--t&#39;
    ]
  }
  paint(ctx, size, properties) { // properties为自定义属性
    const radius = Number(properties.get(&#39;--r&#39;));
    const edge = Number(properties.get(&#39;--t&#39;));
    // ...
  }
})

可以看到绘制是实时更新的(改变圆角),无需 JS 额外处理,实时效果如下

CSS로 그래디언트 툴팁을 구현하는 방법

完整代码可访问 tooltips-mask-paint-var (codepen.io)

https://codepen.io/xboxyan/pen/JjWvVMd

四、描边效果

有时候提示框可能还会有描边的效果,比如这样的

1CSS로 그래디언트 툴팁을 구현하는 방법

这类带描边的其实以上方式都不太适用,clip-pathmask 都无法实现描边,不过有一个边框生成方案可以参考:

有意思!不规则边框的生成方案 (juejin.cn)

https://juejin.cn/post/6944892753402822686

可惜效果不是特别完美(略微模糊)

如果尺寸固定,那么可以直接使用 svg 方式,参考这篇文章:

用SVG实现一个优雅的提示框 (juejin.cn)

https://juejin.cn/post/6926353919333531661

就目前而言,确实没有比较好的实现方案(有更好的实现方式欢迎补充,我暂时想不出来了),不过如果借助 CSS paint ,那一切就都有可能了!只需要在 paint 函数中绘制边框和背景就行了

绘制代码如下

registerPaint(&#39;tips-bg&#39;, class {
    paint(ctx, size) {
      const { width,height } = size; // 容器尺寸
      const radius = 5; // 圆角大小
      const deg = Math.PI / 2;
      const edge = 5; // 三角形大小
      const pos = width / 2; // 三角形位置
      const lineWidth = 2; // 描边宽度
      ctx.beginPath();
      ctx.moveTo(radius+lineWidth,lineWidth);
      ctx.lineTo(width-2*radius-lineWidth,lineWidth);
      ctx.arc(width-radius-lineWidth,radius+lineWidth,radius,-deg,0);
      ctx.lineTo(width-lineWidth,height-2*radius-edge-lineWidth);
      ctx.arc(width-radius-lineWidth,height-radius-edge-lineWidth,radius,0,deg);
      ctx.lineTo(pos+edge,height-edge-lineWidth);
      ctx.lineTo(pos,height-lineWidth);
      ctx.lineTo(pos-edge,height-edge-lineWidth);
      ctx.lineTo(radius+lineWidth,height-edge-lineWidth);
      ctx.arc(radius+lineWidth,height-radius-edge-lineWidth,radius,deg,2*deg);
      ctx.lineTo(lineWidth,radius+lineWidth);
      ctx.arc(radius+lineWidth,radius+lineWidth,radius,-2*deg,-deg);
      ctx.closePath();
      const gradient = ctx.createLinearGradient(0, 0, width, 0); // 渐变背景
      gradient.addColorStop(0, &#39;#F57853&#39;);
      gradient.addColorStop(1, &#39;#F8B578&#39;);
      ctx.fillStyle = gradient; 
      ctx.fill();
      ctx.strokeStyle = &#39;#FBF8F8&#39;; // 绘制边框
      ctx.lineWidth = lineWidth;
      ctx.lineCap = &#39;round&#39;;
      ctx.stroke();
   }
});
tips{
  /* -webkit-mask-image: paint(tips-bg); */
  background: paint(tips-bg); /*不再借助mask,纯js绘制背景,包括渐变*/
}

实时效果如下

1CSS로 그래디언트 툴팁을 구현하는 방법

完整代码可访问 tooltips-paint-stroke (codepen.io)

https://codepen.io/xboxyan/pen/QWpxdVp

五、总结和说明

以上针对 tooltips 布局共介绍了3种不同类型的实现方式,分别是 clip-pathmaskCSS paint。其中 mask 的实现重点其实是CSS图形的绘制,主要有 渐变svg 两种,虽然 渐变 的写法稍微复杂一点,但是最为通用,其他方式可能换一种布局就不适用了。现在总结一下要点:

  • 可以用多个容器重叠配合 clip-path 实现复杂的自适应效果

  • 在使用 CSS 渐变绘制图形时,相同的形状充分利用平铺特性

  • svg 基本形状支持百分比尺寸,用作背景同样有效,可以使用多张背景来组合

  • CSS paint 是未来的最佳解决方式,也能轻易的实现描边效果

  • CSS paint 唯一的缺陷是兼容性不够好(现仅支持 Chrome 65+ ),但是值得学习

当然,这些方式不仅仅是实现本文的布局而已,更多的是提供一种思路,下次碰到其他的“异形布局”也能马上联想出相应的解决方案,而不是选择“切图.png”

更多编程相关知识,请访问:编程教学!!

위 내용은 CSS로 그래디언트 툴팁을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제