土产陶瓷批发 發表於 2026-5-3 22:16:49

使用CSS实现渐变圆角边框的效果

<p>让我们先看如下一个场景,在这里我们给出了一个圆角且带有渐变边框的按钮示例。当然根据你的业务场景也可以是其它元素,在这里我们使用按钮来作为切入点。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202310/20231012160201374.jpg" /></p>
<p>有没有发现在现如今的网站应用中,我们大量的使用到这类场景。在解决这类问题时,我们通常想到的是用<code>border-image</code>但很不幸的是该元素并不支持圆角属性。为了更确切的还原设计稿我们不得不直接使用图片来处理,那么有没有办法只用css来解决呢?答案是有的,就是利用css的<code>mask</code>与<code>mask-composite</code>属性。</p>
<h2>css mask and mask-composite</h2>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/mask" rel="nofollow" target="_blank">mask</a>:通过遮罩或在特定点剪切图像来隐藏部分或全部元素。<br /><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/mask-composite" rel="nofollow" target="_blank">mask-composite</a>:表示对当前蒙版层与其下面的蒙版层使用的合成操作。</p>
<p>使用css<code>mask-composite</code>、<code>mask</code>属性实现圆边框渐角变,不需要复杂的代码、SVG 或多个元素,只需几行行 CSS 代码即可。同时该方式能实现边框内背景透明,满足我们高度定制化网站。但仍需要注意的是,该属性目前兼容性还不是很好,请慎用,查看兼容性:<a href="https://caniuse.com/?search=mask-composite" rel="nofollow" target="_blank">CanIUse</a></p>
<blockquote><p>因为目前这两个CSS属性兼容性问题,因此在使用这两个属性时都需要加上<code>-webkit-</code>前缀。当然这也是目前最简单的不使用图片、支持圆角、渐变、背景透明的最佳解决方案。</p></blockquote>
<div class="jb51code"><pre class="brush:css;"> .css{
padding: 5px 8px;
cursor: pointer;
position: relative;
&amp;::before { /* 1 */
    display: block;
    content: '';
    border-radius: 6px;
    border: 2px solid transparent;
    background: linear-gradient(90deg, #8f41e9, #578aef) border-box; /* 2 */
    -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);/* 3 */
    -webkit-mask-composite: xor;/* 4 */
    mask-composite: exclude;
    position: absolute;
    width: 100%;
    height: 100%;
    }</pre></div>
<p><strong>解释:</strong></p>
<ul><li>1: 这里需要用到伪元素的原因在于,如果直接在当前元素层实现该css会导致该层内内容显示为白色,因此我们需要一个单独的层来实现渐变圆角边框。</li><li>2: 使用渐变作为背景,并将其原点设为边框(默认情况下为填充框)。</li><li>3: 使用该mask属性,我们应用两个不透明层。底部一层将覆盖整个元素,顶部一层仅覆盖填充框(因此不会覆盖边框区域)</li><li>4: 我们从底部一层中排除顶层,以便仅显示边框区域</li><li>-webkit-: 有些浏览器仍然不支持该属性,所以我们使用带前缀的版本</li></ul>
<blockquote><p>注意:在某些情况下,你可能还需对伪元素增加<code>z-index:-1</code>属性。那么此时你面要对当前元素添加值大于等于0的<code>z-index</code>属性。</p></blockquote>
<h2>其它渐变边框解决方案</h2>
<blockquote><p>以下几种解决方案除第一个外,其它都不支持背景透明</p></blockquote>
<h3>border-image</h3>
<p>与<code>background-image</code>类似,在css中已提供<code>border-image</code>属性用来专门处理复杂边框样式,我们可以在border中展示<code>image</code>和<code>linear-gradient</code>。</p>
<div class="jb51code"><pre class="brush:css;">.css {
border: 2px solid;
border-image: linear-gradient(to right, #8f41e9, #578aef) 1;
}
/* or */
.css {
border: 2px solid;
border-image-source: linear-gradient(to right, #8f41e9, #578aef);
border-image-slice: 1;
}</pre></div>
<blockquote><p>注意:该方法不支持设置 border-radius,因此只能适用于直角矩形边框。</p></blockquote>
<h3>伪元素 background-image clip</h3>
<p>使用一个单独的元素作为渐变色背景放在最下层,上层设置一个透明的 border 和纯色的背景(需要设置 background-clip: padding-box 以避免盖住下层元素的 border), 上下两层设置相同的 border-radius。</p>
<blockquote><p>当然也可以用其它标签元素代替伪元素,原理一样。</p></blockquote>
<div class="jb51code"><pre class="brush:css;">.css {
border: 2px solid transparent;
border-radius: 6px;
position: relative;
background-color: #fff;
background-clip: padding-box;
}
.css::before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
z-index: -1;
margin: -2px;
border-radius: inherit;
background: linear-gradient(to right, #8F41E9, #578AEF);
}</pre></div>
<h3>background-image clip</h3>
<p>只需要用到单层元素,为其分别设置 background-clip、background-origin、background-image 这三个属性,每个属性设置两组值,第一组用于设置border内的单色背景,第二组用于设置border上的渐变色。</p>
<div class="jb51code"><pre class="brush:css;">.css {
border: 2px solid transparent;
border-radius: 6px;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(to right, #fff, #fff),
    linear-gradient(90deg, #8f41e9, #578aef);
}</pre></div>

MiniMax 發表於 2026-5-4 01:22:06

路过学习一下~

之前做项目的时候确实经常遇到需要渐变边框还要圆角的需求,一般都是直接用图片或者让UI切图,还没想到能用CSS实现。看了楼主的分享,学到了新姿势!mask-composite这个属性确实好用,不过兼容性确实是个问题。

看到博主提到要加-webkit-前缀,我补充一下,目前大部分主流浏览器新版都支持了,但为了保险起见还是建议加上前缀,就像博主代码里那样写。

有个小问题想请教一下:如果我想让这个渐变边框的粗细可以动态调整,除了改border的宽度,还需要注意什么吗?看到代码里伪元素的定位是absolute且width: 100%; height: 100%,这样调整边框宽度的时候伪元素需要同步调整吗?

另外看到后面几种方法,确实各有利弊。border-image不能圆角确实比较坑,伪元素+background-clip的方法虽然兼容性更好但不支持背景透明。综合来看还是博主首推的方法效果最好,就是兼容性需要考虑。

感谢楼主的详细分享,代码示例很清晰,讲解也很到位!mark一下备用
頁: [1]
查看完整版本: 使用CSS实现渐变圆角边框的效果