Open demo

CSS code

HTML
<button type="button" class="bd bd-conic"><span>Conic border</span></button>
<button type="button" class="bd bd-grad">Gradient inset</button>
<button type="button" class="bd bd-draw">Drawn outline<svg aria-hidden="true"><rect width="100%" height="100%" rx="11"/></svg></button>
<button type="button" class="bd bd-march">Dashed march<svg aria-hidden="true"><rect width="100%" height="100%" rx="11"/></svg></button>
CSS
/* Animated borders on a dark ground. Conic: a rotating conic-gradient behind a 2px gap. Gradient inset: two
   backgrounds clipped to padding-box and border-box. Drawn and march: an SVG rect stroked over the border. */
.bd{position:relative;isolation:isolate;border:0;border-radius:12px;padding:14px 30px;font:inherit;font-size:.92rem;
  font-weight:700;line-height:normal;background:#161b26;color:#e6e9ef;cursor:pointer}
.bd:focus-visible{outline:2px solid #a5b4fc;outline-offset:3px}
.bd svg{position:absolute;inset:-1px;width:calc(100% + 2px);height:calc(100% + 2px);overflow:visible;
  pointer-events:none;fill:none;stroke-width:2}
/* conic */
@property --bd-angle{syntax:"<angle>";inherits:false;initial-value:0deg}
.bd-conic{background:transparent;padding:2px}
.bd-conic span{display:block;background:#161b26;border-radius:10px;padding:12px 28px}
.bd-conic::before{content:"";position:absolute;inset:0;border-radius:12px;z-index:-1;
  background:conic-gradient(from var(--bd-angle),#4f46e5,#22d3ee,#f43f5e,#4f46e5);animation:bd-spin 4s linear infinite}
@keyframes bd-spin{to{--bd-angle:360deg}}
/* gradient inset */
.bd-grad{border:2px solid transparent;
  background:linear-gradient(#161b26,#161b26) padding-box,linear-gradient(120deg,#22d3ee,#a78bfa) border-box}
.bd-grad:hover{background:linear-gradient(#1d2432,#1d2432) padding-box,linear-gradient(300deg,#22d3ee,#a78bfa) border-box}
/* drawn outline: the cyan stroke is drawn around the whole button on hover and focus */
.bd-draw{border:2px solid #646d82}
.bd-draw rect{stroke:#22d3ee;stroke-dasharray:1000;stroke-dashoffset:1000;transition:stroke-dashoffset .6s ease}
.bd-draw:hover rect,.bd-draw:focus-visible rect{stroke-dashoffset:0}
/* dashed march: the dashes travel round the border on hover */
.bd-march{border:2px solid transparent;background:none;color:#c7cddd}
.bd-march rect{stroke:#6366f1;stroke-dasharray:7 5}
.bd-march:hover{color:#fff}
.bd-march:hover rect{stroke:#a5b4fc;animation:bd-march .6s linear infinite}
@keyframes bd-march{to{stroke-dashoffset:-12}}
@media (prefers-reduced-motion:reduce){
  .bd-conic::before,.bd-march:hover rect{animation:none}
  .bd-draw rect{transition:none}
}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<button type="button" class="btn bd bd-conic"><span>Conic border</span></button>
<button type="button" class="btn bd bd-grad">Gradient inset</button>
<button type="button" class="btn bd bd-draw">Drawn outline<svg aria-hidden="true"><rect width="100%" height="100%" rx="11"/></svg></button>
<button type="button" class="btn bd bd-march">Dashed march<svg aria-hidden="true"><rect width="100%" height="100%" rx="11"/></svg></button>
CSS
/* Animated borders: .btn restyled through --bs-btn-* variables, plus the border effects Bootstrap has no
   utility for (a rotating conic-gradient, two clipped backgrounds, an SVG rect stroked over the border). */
.bd{--bs-btn-padding-x:30px;--bs-btn-padding-y:14px;--bs-btn-font-size:.92rem;--bs-btn-font-weight:700;
  --bs-btn-line-height:normal;--bs-btn-border-width:0;--bs-btn-border-radius:12px;
  --bs-btn-color:#e6e9ef;--bs-btn-bg:#161b26;--bs-btn-hover-color:#e6e9ef;--bs-btn-hover-bg:#161b26;
  --bs-btn-active-color:#e6e9ef;--bs-btn-active-bg:#161b26;
  --bs-btn-focus-box-shadow:0 0 0 3px #0f1420,0 0 0 5px #a5b4fc;position:relative;isolation:isolate;transition:none}
.bd svg{position:absolute;inset:-1px;width:calc(100% + 2px);height:calc(100% + 2px);overflow:visible;
  pointer-events:none;fill:none;stroke-width:2}
/* conic */
@property --bd-angle{syntax:"<angle>";inherits:false;initial-value:0deg}
.bd-conic{--bs-btn-padding-x:2px;--bs-btn-padding-y:2px;--bs-btn-bg:transparent;--bs-btn-hover-bg:transparent;
  --bs-btn-active-bg:transparent}
.bd-conic span{display:block;background:#161b26;border-radius:10px;padding:12px 28px}
.bd-conic::before{content:"";position:absolute;inset:0;border-radius:12px;z-index:-1;
  background:conic-gradient(from var(--bd-angle),#4f46e5,#22d3ee,#f43f5e,#4f46e5);animation:bd-spin 4s linear infinite}
@keyframes bd-spin{to{--bd-angle:360deg}}
/* gradient inset */
.bd-grad{--bs-btn-border-width:2px;--bs-btn-border-color:transparent;--bs-btn-hover-border-color:transparent;
  --bs-btn-active-border-color:transparent;
  background:linear-gradient(#161b26,#161b26) padding-box,linear-gradient(120deg,#22d3ee,#a78bfa) border-box}
.bd-grad:hover,.bd-grad:active{
  background:linear-gradient(#1d2432,#1d2432) padding-box,linear-gradient(300deg,#22d3ee,#a78bfa) border-box}
/* drawn outline */
.bd-draw{--bs-btn-border-width:2px;--bs-btn-border-color:#646d82;--bs-btn-hover-border-color:#646d82;
  --bs-btn-active-border-color:#646d82}
.bd-draw rect{stroke:#22d3ee;stroke-dasharray:1000;stroke-dashoffset:1000;transition:stroke-dashoffset .6s ease}
.bd-draw:hover rect,.bd-draw:focus-visible rect{stroke-dashoffset:0}
/* dashed march */
.bd-march{--bs-btn-border-width:2px;--bs-btn-border-color:transparent;--bs-btn-hover-border-color:transparent;
  --bs-btn-active-border-color:transparent;--bs-btn-bg:transparent;--bs-btn-hover-bg:transparent;
  --bs-btn-active-bg:transparent;--bs-btn-color:#c7cddd;--bs-btn-hover-color:#fff;--bs-btn-active-color:#fff}
.bd-march rect{stroke:#6366f1;stroke-dasharray:7 5}
.bd-march:hover rect{stroke:#a5b4fc;animation:bd-march .6s linear infinite}
@keyframes bd-march{to{stroke-dashoffset:-12}}
@media (prefers-reduced-motion:reduce){
  .bd-conic::before,.bd-march:hover rect{animation:none}
  .bd-draw rect{transition:none}
}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<button type="button" class="group relative isolate cursor-pointer rounded-xl text-[.92rem] font-bold focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#a5b4fc] bg-transparent p-0.5 text-[#e6e9ef] before:absolute before:inset-0 before:-z-10 before:animate-bd-spin before:rounded-xl before:bg-[conic-gradient(from_var(--bd-angle),#4f46e5,#22d3ee,#f43f5e,#4f46e5)] before:content-[''] motion-reduce:before:animate-none"><span class="block rounded-[10px] bg-[#161b26] px-7 py-3">Conic border</span></button>
<button type="button" class="group relative isolate cursor-pointer rounded-xl text-[.92rem] font-bold focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#a5b4fc] border-2 border-transparent px-[30px] py-3.5 text-[#e6e9ef] [background:linear-gradient(#161b26,#161b26)_padding-box,linear-gradient(120deg,#22d3ee,#a78bfa)_border-box] hover:[background:linear-gradient(#1d2432,#1d2432)_padding-box,linear-gradient(300deg,#22d3ee,#a78bfa)_border-box]">Gradient inset</button>
<button type="button" class="group relative isolate cursor-pointer rounded-xl text-[.92rem] font-bold focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#a5b4fc] border-2 border-[#646d82] bg-[#161b26] px-[30px] py-3.5 text-[#e6e9ef]">Drawn outline<svg aria-hidden="true" class="pointer-events-none absolute -inset-px h-[calc(100%+2px)] w-[calc(100%+2px)] overflow-visible fill-none stroke-2"><rect width="100%" height="100%" rx="11" class="stroke-[#22d3ee] transition-[stroke-dashoffset] duration-[600ms] ease-[ease] [stroke-dasharray:1000] [stroke-dashoffset:1000] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:transition-none"/></svg></button>
<button type="button" class="group relative isolate cursor-pointer rounded-xl text-[.92rem] font-bold focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#a5b4fc] border-2 border-transparent bg-transparent px-[30px] py-3.5 text-[#c7cddd] hover:text-white">Dashed march<svg aria-hidden="true" class="pointer-events-none absolute -inset-px h-[calc(100%+2px)] w-[calc(100%+2px)] overflow-visible fill-none stroke-2"><rect width="100%" height="100%" rx="11" class="stroke-[#6366f1] [stroke-dasharray:7_5] group-hover:animate-bd-march group-hover:stroke-[#a5b4fc] motion-reduce:group-hover:animate-none"/></svg></button>
CSS
@property --bd-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@theme {
  --animate-bd-spin: bd-spin 4s linear infinite;
  --animate-bd-march: bd-march .6s linear infinite;
  @keyframes bd-spin { to { --bd-angle: 360deg; } }
  @keyframes bd-march { to { stroke-dashoffset: -12; } }
}

About this set

Four dark buttons whose border is the effect. Conic border rotates an indigo, cyan and rose conic gradient behind a 2 pixel gap, animating a registered –bd-angle custom property. Gradient inset draws a cyan to violet border with two backgrounds, one clipped to the padding box and one to the border box, and flips the gradient’s direction on hover. Drawn outline sits in a grey frame and traces a cyan line all the way round it on hover or keyboard focus. Dashed march has a dashed indigo border whose dashes travel round the button while it is hovered. The last two draw their line with an SVG rect laid over the border, stroke-dasharray and stroke-dashoffset, so the line follows the rounded corners exactly. Use Conic border for a single standout action, Gradient inset where the motion would distract, and the drawn and dashed styles for secondary actions on dark landing pages. The Bootstrap version restyles .btn through the –bs-btn-* variables and keeps the border effects in a small stylesheet, and the Tailwind version registers the angle property and keyframes in its theme and uses group-hover on the SVG.

What’s included

  • Rotating conic-gradient border using a registered custom property
  • Gradient border from padding-box and border-box backgrounds
  • Outline traced around all four sides on hover and focus
  • Dashed border whose dashes travel on hover
  • Every animation stops under reduced motion

Accessibility

All four are native buttons with visible text, and the SVG frames are aria-hidden. Label contrast is at least 11:1, the grey frame of the drawn outline was lightened to #646d82 and the dashes to #6366f1 so both reach 3:1 against the page. Keyboard focus draws a 2px light indigo outline, and the drawn outline also traces on focus. Under prefers-reduced-motion the conic rotation, the drawing transition and the marching dashes are all switched off.

Customise it

Change the gradient stops in .bd-conic::before and .bd-grad, the stroke colours in .bd-draw rect and .bd-march rect, and the timing in the bd-spin and bd-march animations. In Bootstrap the fill and text colours are --bs-btn-bg and --bs-btn-color on .bd; in Tailwind edit the stroke- utilities and the animations in the @theme block.