<div class="content">

    <div>
        <h1>Gradient Borders</h1>
        (With transparent background and border radius)

    </div>
    <hr>
    <p>
        There are many ways to create <b>gradient borders</b> for an element.
        If you looked it up, you probably found Chris Coyier's great article about
        <a href="https://css-tricks.com/gradient-borders-in-css/">Gradient Borders in CSS</a>,
        where he describes how to create gradient borders with <code>pseudo-element</code>
        and <code>border-image</code>.
    </p>
    <p>
        The problem is that one method only supports opaque backgrounds,
        and the other is incompatible with <code>border-radius</code>. So what do you
        do when you need an element with gradient borders, and rounded corners, and a transparent
        background?! You can use <code>background-image</code> for that.
    </p>

    <div class="btns">
        <button class="btn">Lorem</button>
        <button class="btn">ipsum</button>
        <button class="btn">dolor</button>
        <button class="btn">sit amet</button>
        <button class="btn">consectetur</button>
        <button class="btn">adipisicing</button>
        <button class="btn">elit.</button>
        <button class="btn">Ex vero</button>
        <button class="btn">maiores</button>
        <button class="btn">itaque id</button>
        <button class="btn">aperiam</button>
        <button class="btn">sequi</button>
    </div>

    <p>
        It uses a very similar method as the one I've used in my
        <a href="https://codepen.io/amit_sheen/pen/xxZeyjO">Dashed Border Generator</a>,
        only with 8 background areas instead of 4, which allows for the rounded-corners effect.
    </p>

</div>

<div class="generator">

    
    <div class="sliders">
        <h2>Create your own gradient border</h2>
        <br>
        <label>Border-width</label>
        <input type="range" name="width" min="1" max="16" step="1" value="5" oninput="drawBtn();">
        <label>Border-radius</label>
        <input type="range" name="radius" min="1" max="32" step="1" value="20" oninput="drawBtn();">
    </div>
    <div class="resultBtn-wrepper">
        <div class="resultBtn">
            <input type="color" name="colorA" onchange="drawBtn();" value="#D50000">
            <input type="color" name="colorB" onchange="drawBtn();" value="#304FFE">
            <input type="color" name="colorC" onchange="drawBtn();" value="#00BFA5">
            <input type="color" name="colorD" onchange="drawBtn();" value="#FFD600">
            Result
        </div>
    </div>
</div>

<div class="output">
    <h3>Output code:</h3>
    <div class="output-code"></div>
</div>

<a href="https://twitter.com/amit_sheen" class="twitterLink" target="_blank">
   <img src="https://assets.codepen.io/1948355/twitterLogo2.png" />
</a>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@300;700&display=swap');

@mixin bordient($radius, $width, $color1, $color2, $color3: $color2, $color4: $color1) {
    
    background-image:
        radial-gradient(circle at 100% 100%, transparent #{$radius - $width}, $color1 #{$radius - $width}, $color1 #{$radius}, transparent #{$radius}),
        linear-gradient(to right, $color1, $color2),
        radial-gradient(circle at 0% 100%, transparent #{$radius - $width}, $color2 #{$radius - $width}, $color2 #{$radius}, transparent #{$radius}),
        linear-gradient(to bottom, $color2, $color3),
        radial-gradient(circle at 0% 0%, transparent #{$radius - $width}, $color3 #{$radius - $width}, $color3 #{$radius}, transparent #{$radius}),
        linear-gradient(to left, $color3, $color4),
        radial-gradient(circle at 100% 0%, transparent #{$radius - $width}, $color4 #{$radius - $width}, $color4 #{$radius}, transparent #{$radius}),
        linear-gradient(to top, $color4, $color1);
    
    background-position:
        top left,
        top center,
        top right,
        center right,
        bottom right,
        bottom center,
        bottom left,
        center left;
    
    background-size:
        #{$radius} #{$radius},
        calc(100% - (2 * #{$radius})) #{$width},
        #{$radius} #{$radius},
        #{$width} calc(100% - (2 * #{$radius}));
    
    background-repeat: no-repeat;
}

*, *::before, *::after {
    padding: 0;
    margin: 0 auto;
    box-sizing: border-box;
}

body {
    font-family: 'Open Sans Condensed', sans-serif;
    background-color: #333;
    color: #fff;
    min-height: 100vh;
    background-image: repeating-linear-gradient(45deg, #222, #333 2px, #222 4px);
    text-align: center;
}

a {
    color: #0075ff;
}

h2, h3 {
    text-decoration: underline;
    text-decoration-color: #aaa;
}

hr {
    width: 100%;
    height: 8px;
    background: none;
    border: none;
    @include bordient(0px, 2px, #D50000, #304FFE);
}

.content {
    max-width: 720px;
    padding: 4em 2em 2em;
    background-color: #0004;
    
    & p {
        text-align: left;
        font-size: 1.25em;
    }
    
    & > * + * {
        margin-top: 2em;
    }
}

.btns {
    display: grid;
    grid-gap: 1em 2em;
    grid-template-columns: repeat(4, 1fr);
    
    @media (max-width: 720px) {
        grid-template-columns: repeat(3, 1fr);
    }
    @media (max-width: 480px) {
        grid-template-columns: repeat(2, 1fr);
    }
}

.btn {
    font-size: 1em;
    padding: 1em ;
    width: 100%;
    border: none;
    background: none;
    color: white;
    font-weight: bold;
    filter: drop-shadow(0px 0px 3px rgba(0,0,0,0.25));
    transition: filter 0.2s;

    &:hover {
        filter: drop-shadow(3px 3px 3px rgba(0,0,0,0.5));
    }

    &:nth-child(1) {
        @include bordient(12px, 8px, #D50000, #304FFE, #00BFA5, #FFD600);
    }
    
    &:nth-child(2) {
        @include bordient(4px, 2px, #AA00FF, #0091EA, #64DD17, #FF6D00);
    }
    
    &:nth-child(3) {
        @include bordient(4px, 3px, #C51162, #00C853);
    }
    
    &:nth-child(4) {
        @include bordient(4px, 3px, #2962FF, #FFAB00, white);
    }

    &:nth-child(5) {
        @include bordient(24px, 2px, white, red);
    }
    
    &:nth-child(6) {
        @include bordient(12px, 4px, white, red, white, red);
    }
    
    &:nth-child(7) {
        @include bordient(0px, 7px, white, white, lime, lime);
    }
    
    &:nth-child(8) {
        @include bordient(16px, 4px, lime, white, lime, white);
    }

    &:nth-child(9) {
        @include bordient(4px, 2px, aqua, gold, white, white);
    }
    
    &:nth-child(10) {
        @include bordient(20px, 4px, aqua, gold);
    }
    
    &:nth-child(11) {
        @include bordient(10px, 1px, tomato, white, tomato, maroon);
    }
    
    &:nth-child(12) {
        @include bordient(1.5em, 1.5em, teal, maroon);
    }
}

.generator {
    max-width: calc(720px + 4em);
    padding: 4em 2em 0;
    display: grid;
    grid-template-columns: auto min-content;
    grid-gap: 2em;
    align-items: center;

    @media (max-width: 640px) {
        grid-template-columns: 1fr;
        grid-gap: 0em;
    }
}

.sliders {
    width: 100%;
    text-align: left;

    & input {
        width: 100%;
        margin-bottom: 2em;
    }
}

.resultBtn {

    &-wrepper {
        text-align: center;
        padding: 3em;
        margin-bottom: 2em;
    }
    
    position: relative;
    font-weight: bold;
    font-size: 1.25em;
    padding: 1em 3em;
    border: none;
    background: none;
    color: #fff;

    & input {
        position: absolute;
        width: 3em; height: 3em;
        background: none;
        border: none;

        &:nth-child(1) { top: -3em; left: -3em; }
        &:nth-child(2) { top: -3em; right: -3em; }
        &:nth-child(3) { bottom: -3em; right: -3em; }
        &:nth-child(4) { bottom: -3em; left: -3em; }
    }
}

.output {
    max-width: 720px;
    text-align: left;
    padding: 2em;
    background-color: #0004;
    
    &-code {
        padding: 2em;
        background-color: #fffa;
        color: #333;

        & span {
            display: block;
            padding-left: 4em;
            text-indent: -2em;
            margin: 0.5em auto;
        }
    }
}

.twitterLink {
  position: fixed;
  bottom: 0.5em; right: 0.5em;
  & img {
    width: 2em;
    filter: grayscale(100%);
    transition: filter 0.25s;
    &:hover {
      filter: grayscale(0%);
    }
  }
}
View Compiled
const resultBtn = document.querySelector('.resultBtn');
const output = document.querySelector('.output-code');

resultBtn.style.backgroundPosition = `top left,top center,top right,center right, bottom right,bottom center,bottom left,center left`;
resultBtn.style.backgroundRepeat = "no-repeat";

drawBtn();

function drawBtn() {
    const width = Number(document.querySelector('[name="width"]').value);
    const radius = Number(document.querySelector('[name="radius"]').value);

    const color = [
        document.querySelector('[name="colorA"]').value,
        document.querySelector('[name="colorB"]').value,
        document.querySelector('[name="colorC"]').value,
        document.querySelector('[name="colorD"]').value
    ]

    resultBtn.style.backgroundImage = `
        radial-gradient(circle at 100% 100%, transparent ${radius - width}px, ${color[0]} ${radius - width}px, ${color[0]} ${radius}px, transparent ${radius}px),
        linear-gradient(to right, ${color[0]}, ${color[1]}),
        radial-gradient(circle at 0% 100%, transparent ${radius - width}px, ${color[1]} ${radius - width}px, ${color[1]} ${radius}px, transparent ${radius}px),
        linear-gradient(to bottom, ${color[1]}, ${color[2]}),
        radial-gradient(circle at 0% 0%, transparent ${radius - width}px, ${color[2]} ${radius - width}px, ${color[2]} ${radius}px, transparent ${radius}px),
        linear-gradient(to left, ${color[2]}, ${color[3]}),
        radial-gradient(circle at 100% 0%, transparent ${radius - width}px, ${color[3]} ${radius - width}px, ${color[3]} ${radius}px, transparent ${radius}px),
        linear-gradient(to top, ${color[3]}, ${color[0]})
    `;


    resultBtn.style.backgroundSize = `
        ${radius}px ${radius}px,
        calc(100% - ${2 * radius}px) ${width}px,
        ${radius}px ${radius}px,
        ${width}px calc(100% - ${2 * radius}px)
    `;

    output.innerHTML = `
        <code>
            .button-with-gradient-border {
                <span>
                    <b>background-image</b>:
                    radial-gradient(circle at 100% 100%, transparent ${radius - width}px, ${color[0]} ${radius - width}px, ${color[0]} ${radius}px, transparent ${radius}px),
                    linear-gradient(to right, ${color[0]}, ${color[1]}),
                    radial-gradient(circle at 0% 100%, transparent ${radius - width}px, ${color[1]} ${radius - width}px, ${color[1]} ${radius}px, transparent ${radius}px),
                    linear-gradient(to bottom, ${color[1]}, ${color[2]}),
                    radial-gradient(circle at 0% 0%, transparent ${radius - width}px, ${color[2]} ${radius - width}px, ${color[2]} ${radius}px, transparent ${radius}px),
                    linear-gradient(to left, ${color[2]}, ${color[3]}),
                    radial-gradient(circle at 100% 0%, transparent ${radius - width}px, ${color[3]} ${radius - width}px, ${color[3]} ${radius}px, transparent ${radius}px),
                    linear-gradient(to top, ${color[3]}, ${color[0]});
                </span>
                <span>
                    <b>background-size</b>:
                    ${radius}px ${radius}px,
                    calc(100% - ${2 * radius}px) ${width}px,
                    ${radius}px ${radius}px,
                    ${width}px calc(100% - ${2 * radius}px);
                </span>
                <span>
                    <b>background-position</b>:
                    top left,top center,top right,center right, bottom right,bottom center,bottom left,center left;
                </span>
                <span>
                    <b>background-repeat</b>:
                    no-repeat;
                </span>
            }
        </code>
    `;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.