【问题标题】:Border Gradient with Border Radius具有边界半径的边界梯度
【发布时间】:2026-02-03 22:00:01
【问题描述】:

我有以下 CSS:

a.btn.white-grad {
    background: $lgrey;
    color: #313149 !important;
    border: 1px solid #000;
    border-image-source: linear-gradient(to right, #9c20aa, #fb3570);
    border-image-slice: 20;
    float: left;
    @include font-size(26);
    margin: 75px 0;
}

添加border-radius: 5px 似乎没有任何作用。我想这是因为我正在使用边框渐变......有没有办法让我达到所需的 5px 边框半径?

【问题讨论】:

    标签: css border linear-gradients


    【解决方案1】:

    2021:我推荐使用 CSS 掩码方法,因为现在支持很好


    您不能将border-radius 与渐变一起使用。这是另一个想法,您可以依靠多个背景并调整background-clip

    .white-grad {
      background: 
        linear-gradient(#ccc 0 0) padding-box, /*this is your grey background*/
        linear-gradient(to right, #9c20aa, #fb3570) border-box;
      color: #313149;
      padding: 10px;
      border: 5px solid transparent;
      border-radius: 15px;
      display: inline-block;
      margin: 75px 0;
    }
    <div class="white-grad"> Some text here</div>
    
    <div class="white-grad"> Some long long long text here</div>
    
    <div class="white-grad"> Some long long <br>long text here</div>

    SVG 方法

    如果你想要透明度,你可以考虑像下面这样的 SVG:

    svg {
      width:200px;
      height:100px;
      margin:10px;
    }
    <svg xmlns="http://www.w3.org/2000/svg">
    <defs>
          <linearGradient id="Gradient" x1="0" x2="100" y1="0" y2="0" gradientUnits="userSpaceOnUse">
             <stop stop-color="#9c20aa" offset="0"/>
             <stop stop-color="#fb3570" offset="1"/>
          </linearGradient>
       </defs>
      <rect x="5" y="5" height="100%" width="100%" style="width:calc(100% - 10px);height:calc(100% - 10px)" rx="20" ry="20" stroke-width="10" fill="transparent" stroke="url(#Gradient)"/>
    </svg>

    你可以作为背景应用:

    .white-grad {
        background:url('data:image/svg+xml;utf8,<svg   xmlns="http://www.w3.org/2000/svg" ><defs><linearGradient id="Gradient" x1="0" x2="100" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="%239c20aa" offset="0"/><stop stop-color="%23fb3570" offset="1"/></linearGradient></defs><rect x="5" y="5" width="100%" height="100%" style="height:calc(100% - 10px);width:calc(100% - 10px)" rx="20" ry="20" stroke-width="10" fill="transparent" stroke="url(%23Gradient)"/></svg>');
        color: #313149;
        padding:25px;
        border-radius:15px;
        display:inline-block;
        margin: 75px 0;
    }
    
    body {
      background:yellow;
    }
    <div class="white-grad"> Some text here</div>
    
    <div class="white-grad"> text very loooooooooooong here</div>

    mask 一样,您可以在 SVG 之外获得渐变:

    .white-grad {
      color: #313149;
      padding: 25px;
      border-radius: 15px;
      display: inline-block;
      margin: 75px 0;
      background-size: 0 0;
      position: relative;
      z-index: 0;
    }
    
    .white-grad::before {
      content: "";
      position: absolute;
      z-index: -1;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-image: inherit;
      background-size: auto;
      --mask: url('data:image/svg+xml;utf8,<svg  xmlns="http://www.w3.org/2000/svg" ><rect x="5" y="5" width="100%" height="100%" style="height:calc(100% - 10px);width:calc(100% - 10px)" rx="20" ry="20" stroke-width="10" fill="transparent" stroke="white"/></svg>');
      -webkit-mask: var(--mask);
              mask: var(--mask);
    }
    
    body {
      background: yellow;
    }
    <div class="white-grad" style="background-image:linear-gradient(to right,blue,red)"> Some text here</div>
    
    <div class="white-grad" style="background-image:linear-gradient(black,lightblue,green)"> text very loooooooooooong here</div>
    
    <div class="white-grad" style="background-image:radial-gradient(blue,pink)"> text very<br> loooooooooooong here</div>


    您也可以将其用作公共元素,并考虑将position:absolute 放在文本周围:

    .white-grad {
      color: #313149;
      padding: 25px;
      border-radius: 15px;
      display: inline-block;
      margin: 75px 0;
      position:relative;
      z-index:0;
    }
    .white-grad > svg {
      position:absolute;
      top:0;
      left:0;
      height:100%;
      width:100%;
      z-index:-1;
    }
    
    body {
      background: yellow;
    }
    
    .hide {
     height:0;
     width:0;
    }
    <svg class="hide" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="Gradient" x1="0" x2="100" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#9c20aa" offset="0"/><stop stop-color="#fb3570" offset="1"/></linearGradient></defs><rect x="5" y="5" width="100%" height="100%" id="border" style="height:calc(100% - 10px);width:calc(100% - 10px)" rx="20" ry="20" stroke-width="10" fill="transparent" stroke="url(#Gradient)"/></svg>
    
    
    <div class="white-grad"> 
    <svg xmlns="http://www.w3.org/2000/svg">
      <use href="#border" />
    </svg>
    Some text here</div>
    
    <div class="white-grad"> 
    <svg xmlns="http://www.w3.org/2000/svg">
      <use href="#border" />
    </svg>
    text very loooooooooooong here</div>

    CSS 掩码方法

    这是一个使用 mask 的 CSS 的不同想法,您将拥有透明度并且它也将是响应式的:

    .white-grad {
      color: #313149;
      padding: 10px;
      display: inline-block;
      margin: 75px 0;
      position: relative;
      z-index: 0;
    }
    .white-grad:before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      padding: 5px;
      border-radius: 15px;
      background: linear-gradient(to right, #9c20aa, #fb3570);
      -webkit-mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
              mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    
    }
    <div class="white-grad"> Some text here</div>
    
    <div class="white-grad"> Some long long long text here</div>
    
    <div class="white-grad"> Some long long <br>long text here</div>

    借助 CSS 变量,我们可以轻松调整:

    .white-grad {
      --b:5px;  /* border width*/
      --r:15px; /* the radius */
    
      color: #313149;
      padding: calc(var(--b) + 5px);
      display: inline-block;
      margin: 75px 0;
      position:relative;
      z-index:0;
    }
    .white-grad:before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      padding: var(--b);
      border-radius: var(--r);
      background: var(--c,linear-gradient(to right, #9c20aa, #fb3570)); 
      -webkit-mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
              mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    }
    
    body {
      background:#f2f2f2;
    }
    <div class="white-grad"> Some text here</div>
    
    <div class="white-grad" style="--r:20px;--b:10px;--c:linear-gradient(140deg,red,yellow,green)"> Some long long long text here</div>
    
    <div class="white-grad"  style="--r:30px;--b:8px;--c:linear-gradient(-40deg,black 50%,blue 0)"> Some long long <br>long text here</div>
    
    <div class="white-grad"  style="--r:40px;--b:20px;--c:conic-gradient(black,orange,purple)"> Some long long <br>long text here<br> more and more more and more</div>

    获得不同效果的相关问题:How do you apply a gradient from outer to inner, only to borders, in CSS?


    上面的例子也涵盖了圆形:

    .white-grad {
      --b:5px;  /* border width*/
    
      color: #313149;
      display: inline-block;
      margin: 10px;
      width: 150px;
      aspect-ratio: 1;
      position: relative;
      z-index: 0;
    }
    
    .white-grad:before {
      content:"";
      position:absolute;
      z-index:-1;
      inset: 0;
      background: var(--c,linear-gradient(to right, #9c20aa, #fb3570));
      padding: var(--b);
      border-radius: 50%;
      -webkit-mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
              mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    }
    
    body {
      background:#f2f2f2;
    }
    <div class="white-grad"></div>
    
    <div class="white-grad" style="--b:10px;--c:linear-gradient(140deg,red,yellow,green)"></div>
    
    <div class="white-grad"  style="--b:8px;--c:linear-gradient(-40deg,black 50%,blue 0)"></div>
    
    <div class="white-grad"  style="--b:20px;--c:conic-gradient(black,orange,purple)"></div>

    如果您想将动画应用于边框,相关问题:Button with transparent background and rotating gradient border


    还有不同的半径形状:

    .white-grad {
      --b:5px;  /* border width*/
    
      color: #313149;
      display: inline-block;
      margin: 10px;
      width: 150px;
      aspect-ratio: 1;
      position: relative;
      z-index: 0;
    }
    
    .white-grad:before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      background: var(--c,linear-gradient(to right, #9c20aa, #fb3570));
      padding: var(--b);
      border-radius: var(--r,50%);
      -webkit-mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
             mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    }
    
    body {
      background:#f2f2f2;
    }
    <div class="white-grad" style="--r:50% 0 50% 50%;"></div>
    
    <div class="white-grad" style="--b:10px;--r:50% 0;--c:linear-gradient(140deg,red,yellow,green)"></div>
    
    <div class="white-grad"  style="--b:8px;--r:50% 0 0;--c:linear-gradient(-40deg,black 50%,blue 0)"></div>
    
    <div class="white-grad"  style="--b:20px;--r:50% 50% 0 0;--c:conic-gradient(black,orange,purple)"></div>

    和不同的边框粗细:

    .white-grad {
      --b:5px;  /* border width*/
    
      color: #313149;
      display: inline-block;
      margin: 10px;
      width: 150px;
      aspect-ratio: 1;
      position: relative;
      z-index: 0;
    }
    .white-grad:before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      background: var(--c,linear-gradient(#9c20aa, #fb3570));
      padding: var(--b);
      border-radius:var(--r,50%);
      -webkit-mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
              mask: 
         linear-gradient(#fff 0 0) content-box, 
         linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    }
    
    body {
      background:#f2f2f2;
    }
    <div class="white-grad" style="--b:0 0 20px 20px;--r:50% 0 50% 50%;"></div>
    
    <div class="white-grad" style="--b:10px 0 10px 0;--r:50% 0;--c:linear-gradient(140deg,red,yellow,green)"></div>
    
    <div class="white-grad"  style="--b:8px 0px 0px 8px;--r:50% 0 0;--c:linear-gradient(40deg,black 50%,blue 0)"></div>
    
    <div class="white-grad"  style="--b:20px 20px 0 20px;--r:50% 50% 0 0;--c:conic-gradient(pink,orange,red,pink)"></div>

    【讨论】:

    • 如何使用您的解决方案获得透明背景?谢谢!
    • 我爱你。 @NoéVIRICEL 如果您将第一个线性渐变中的 #ccc 值更改为透明,那应该可以工作
    • @mikespitz_8 第一个不适用于透明度,您需要考虑其他透明度解决方案(SVG 或蒙版)
    • 这个确实很酷,但是好像box背景和页面背景颜色不同的话,页面背景方角会从边框后面凸出来。
    • --b--r--c 属性是什么?它们看起来像一个速记,但我在任何地方都找不到它的参考。感谢您的精彩回答。
    【解决方案2】:

    您需要将按钮包装在一个 div 中,并在该父 div 上设置 border-radius。为了工作,您还必须将 overflow:hidden 设置为该父 div。像这样:

    .btn-wrap {
        border-radius: 5px;
        overflow: hidden;
        margin: 20px;
        width: 60px;
    }
    a.btn.white-grad {
        background: #eee;
        color: #313149 !important;
        border: 20px solid #000;
        border-image-source: linear-gradient(to right, #9c20aa, #fb3570);
        border-image-slice: 20;
        line-height: 2;
    }
    	<div class="btn-wrap">
    		<a href="#" class="btn white-grad">link</a>
    	</div>

    【讨论】: