Градиент закругленного бордюра кнопки

143
27 мая 2019, 20:00

Как сделать градиент закругленного бордюра кнопки с прозрачным содержимым?

К примеру, в простом варианте — нет возможности задать градиент для border-bottom, border-top

<html> 
   <head> 
      <style> 
         .box 
         { 
         margin:50px auto; 
         width:250px; 
         height:300px; 
         border-top:1px solid #3ACFD5; 
         border-bottom:1px solid #3a4ed5; 
         border-radius:7px; 
         -webkit-box-sizing:border-box; 
         -moz-box-sizing:border-box; 
         box-sizing:border-box; 
         background-position:0 0,100% 0; 
         background-repeat:no-repeat; 
         -webkit-background-size:20px 100%; 
         -moz-background-size:20px 100%; 
         background-size:1px 100%; 
         background-image:-webkit-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%),-webkit-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%); 
         background-image:-moz-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%),-moz-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%); 
         background-image:-o-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%),-o-linear-gradient(top,#3acfd5 0%,#3a4ed5 100%); 
         background-image:linear-gradient(to bottom,#3acfd5 0%,#3a4ed5 100%),linear-gradient(to bottom,#3acfd5 0%,#3a4ed5 100%) 
         } 
      </style> 
   </head> 
   <body> 
      <div class="box"></div> 
   </body> 
</html>

Идеальный вариант, теоретически можно с помощью clip-path осуществить заливку середины маской с прозрачностью и выставить отступы от краев, но на данный момент — код работает наоборот и нужно инвертировать маску.

<!DOCTYPE html> 
<html> 
<head> 
  <meta charset="utf-8"> 
  <style type="text/less"> 
.border-test { 
  margin: 2em; 
  height: 100px; 
  width: 450px; 
  background-color: purple; 
  .border-squircle(10%; 50%); 
} 
 
.border-squircle(@radius-x; @radius-y) { 
  .loop(@radius-x; @radius-y; 359; 100% 0); 
} 
 
.loop(@radius-x; @radius-y; @counter; @list) when (@counter >= 0) { 
  @cos-x: cos(unit(@counter, deg)); 
  @x: pow(abs(@cos-x), unit(@radius-x) / 100) * 50 * abs(@cos-x + 0.0000000001) / (@cos-x + 0.0000000001) + 50; 
   
  @sin-y: sin(unit(@counter, deg)); 
  @y: pow(abs(@sin-y), unit(@radius-y) / 100) * 50 * abs(@sin-y + 0.0000000001) / (@sin-y + 0.0000000001) + 50; 
   
  @percent-x: percentage(round(@x, 1) / 100); 
  @percent-y: percentage(round(@y, 1) / 100); 
   
  @new-list: @percent-x @percent-y, @list; 
  .loop(@radius-x; @radius-y; (@counter - 1); @new-list); 
} 
 
.loop(@radius-x; @radius-y; @counter; @list) when (@counter < 0) { 
  clip-path: polygon(@list); 
} 
  </style> 
</head> 
<body> 
  <div class="border-test"></div> 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" ></script> 
</body> 
</html>

Пробовал вариант с SVG - он растягивается сильно, даже при применение атрибута non-scaling-stroke и preserveAspectRatio

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

Answer 1

В вашем примере я не увидел реализацию на svg а хотелось бы увидеть что не получилось

Так же в вашем примере есть clip-path который поддерживается но не везде, от пример реализации прямоугольника с закруглёнными углами и с градиентной заливкой stroke

<svg version="1.1" viewBox="0 0 237 113" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
 <defs> 
  <linearGradient id="linearGradient" x1="-36" x2="200" y1="148" y2="148" gradientUnits="userSpaceOnUse"> 
   <stop style="stop-color:violet" offset="0"/> 
   <stop style="stop-color:blue" offset="0.5"/> 
   <stop style="stop-color:orange" offset="1"/> 
  </linearGradient> 
 </defs> 
 <g transform="translate(36 -91)"> 
  <rect x="-35" y="93" width="234" height="110" ry="18" style="fill:none;stroke-width:1;stroke:url(#linearGradient)"/> 
 </g> 
</svg>

Answer 2

Добавление анимации

Берется соседний цвет градиента по точкам offset

values="violet;blue;violet"   

Анимируется атрибут линейного градиента stop-color

<linearGradient id="linearGradient" x1="-36" x2="200" y1="148" y2="148" gradientUnits="userSpaceOnUse"> <stop style="stop-color:violet" offset="0"> <animate attributeName="stop-color" dur="0.5s" values="violet;blue;violet" begin="rec.click" repeatCount="2" /> </stop>

и так для каждой точки offset

.container { 
  width: 50%; 
  height: 50%; 
}
<div class="container"> 
  <svg version="1.1" viewBox="0 0 237 113" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
 <defs> 
  <linearGradient id="linearGradient" x1="-36" x2="200" y1="148" y2="148" gradientUnits="userSpaceOnUse"> 
   <stop style="stop-color:violet" offset="0"> 
   <animate attributeName="stop-color" dur="0.5s" values="violet;blue;violet" begin="rec.click" repeatCount="2" /> 
   </stop> 
   <stop style="stop-color:blue" offset="0.5"> 
    <animate attributeName="stop-color" dur="1.0s" values="blue;orange;blue" begin="rec.click" repeatCount="2" /> 
   </stop> 
   <stop style="stop-color:orange" offset="1"> 
    <animate attributeName="stop-color" dur="1.5s" values="orange;violet;orange" begin="rec.click" repeatCount="2" /> 
   </stop> 
   
  </linearGradient> 
 </defs> 
 <g id="rec" transform="translate(36 -91)"> 
  <rect  x="-35" y="93" width="230" height="106" ry="18" style="fill:transparent;stroke-width:3;stroke:url(#linearGradient)"/> 
   <text x="0" y="158" font-size="48" fill="gray" >Click me</text> 
 </g> 
</svg> 
</div>

Добавим анимацию для текста кнопки.

Для этого просто используем уже созданный градиент с анимацией к тексту

<text x="0" y="158" font-size="48" fill="url(#linearGradient)" >Click me</text>  

.container { 
  width: 50%; 
  height: 50%; 
}
<div class="container"> 
  <svg version="1.1" viewBox="0 0 237 113" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
 <defs> 
  <linearGradient id="linearGradient" x1="-36" x2="200" y1="148" y2="148" gradientUnits="userSpaceOnUse"> 
   <stop style="stop-color:violet" offset="0"> 
   <animate attributeName="stop-color" dur="0.8s" values="violet;blue;violet" begin="rec.click" repeatCount="2" /> 
   </stop> 
   <stop style="stop-color:blue" offset="0.8"> 
    <animate attributeName="stop-color" dur="1.0s" values="blue;orange;blue" begin="rec.click" repeatCount="2" /> 
   </stop> 
   <stop style="stop-color:orange" offset="1"> 
    <animate attributeName="stop-color" dur="1.5s" values="orange;violet;orange" begin="rec.click" repeatCount="2" /> 
   </stop> 
   
  </linearGradient> 
 </defs> 
 <g id="rec" transform="translate(36 -91)"> 
  <rect  x="-35" y="93" width="234" height="110" ry="18" style="fill:transparent;stroke-width:2;stroke:url(#linearGradient)"/> 
   <text x="0" y="158" font-size="48" fill="url(#linearGradient)" >Click me</text> 
 </g> 
</svg> 
</div>

READ ALSO
Некоторые SVG не воспроизводят анимацию

Некоторые SVG не воспроизводят анимацию

На сайте есть карусель Owl-carouselНаписал скрипт, что если переключать слайдеры карусели, то SVG картинка должна воспроизводиться заново

159
Поменять значение Input при выборе select

Поменять значение Input при выборе select

Всем привет есть такой input:

141
Помогите не работает код jQuery!

Помогите не работает код jQuery!

Помогите пожалуйста с кодом,при нажатии на кнопку должен выводиться текст но такого не происходит вот код :

153