3

After searching extensively I am stuck on how I might go about replicating this button in CSS, specifically the border as I deed to use this on other elements if possible.

The Designed Button

Button with top-right gradient border

button.rounded-button {
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    padding: 1.125rem 2rem;
    
    position: absolute;
    width: 13.5919rem;
    height: 4.375rem;
    
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(0.7942rem);

    border-radius: 5.8652rem;
    border-image-slice: 1 1 0 0;
    border: 1px solid;
    border-image-source: linear-gradient(257.34deg, #FFFFFF 4.56%, rgba(255, 255, 255, 0) 29.19%);
    
    font-size: 1.25rem;
    line-height: 2.125rem;
    color: #fff;
}

body {
    background: #393939;
}
<!-- SVG Not included with the example -->
<button type="button" class="rounded-button">
  Watch video
  <!-- <img src="/assets/img/glyphs/ic-play.svg" alt="Watch video"> -->
</button>

Ideally I am looking to have a class that I can apply to any element which adds the desired effect and that can be reversed, I have tried pseudo elements such as :after but to no joy

I really am not sure if this can be acvhieved in pure css ‍♂️

Newbie
  • 4,462
  • 11
  • 23
Justin Erswell
  • 688
  • 7
  • 42
  • 87
  • 1
    You can't combine `border-radius` with `border-image-source` unfortunately: https://stackoverflow.com/questions/62052199/border-radius-with-border-image – Terry Sep 30 '21 at 11:25
  • @Terry Ah I thought I was struggling thanks for the heads up and link to explanation – Justin Erswell Sep 30 '21 at 11:31

2 Answers2

6

Consider using a ::before hidden behind. This is the closest I can make it without additional elements.

button.rounded-button {
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    
    padding: 1rem 2.25rem;
    border-radius: 1000px;
    
    border: none;
    position: relative;
    background: #343434;
    
    font-size: 1.25rem;
    line-height: 2rem;
    color: #fff;
}
button.rounded-button::before {
    content: '';
    display: block;
    position: absolute;
    border-radius: 1000px;
    top: -0.1em;
    bottom: -0.1em;
    right: -0.1em;
    left: -0.1em;
    z-index: -1;
    background: linear-gradient(240deg, #ffffff 0%, #343434 25%);
}

body {
    background: #1d1d1d;
    padding: 2rem;
}
<button type="button" class="rounded-button">
  Watch video
</button>

But it would be better to have a wrapper around the button as ::before with z-index: -1 is a bit of a hack.

Bonus

Then you can add some glass like effect to it.

button.rounded-button {
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    
    padding: 1rem 2.25rem;
    border-radius: 1000px;
    
    border: none;
    position: relative;
    background: #343434;
    
    font-size: 1.25rem;
    line-height: 2rem;
    color: #fff;
    cursor: pointer;
}
button.rounded-button::before {
    content: '';
    display: block;
    position: absolute;
    border-radius: 1000px;
    top: -0.1em;
    bottom: -0.1em;
    right: -0.1em;
    left: -0.1em;
    z-index: -1;
    background: linear-gradient(240deg, #343434 0%, #ffffff 20%, #343434 50%);
    background-size: 140%;
    background-position: 0 0;
    transition: background .3s;
}

button.rounded-button:hover::before {
    background-position: 100% 0;
    
}

body {
    background: #1d1d1d;
    padding: 2rem;
}
<button type="button" class="rounded-button">
  Watch video
</button>
Newbie
  • 4,462
  • 11
  • 23
1

You can use box-shadow to apply a border effect on just the right side:

box-shadow: 5px 0 1px -2px grey;

.rounded-button {
    box-shadow: 5px 0 1px -2px grey;
}



/* YOUR INITIAL CODE */
button.rounded-button {
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    padding: 1.125rem 2rem;
    
    position: absolute;
    width: 13.5919rem;
    height: 4.375rem;
    
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(0.7942rem);

    border-radius: 5.8652rem;
    border-image-slice: 1 1 0 0;
    border: 1px solid;
    border-image-source: linear-gradient(257.34deg, #FFFFFF 4.56%, rgba(255, 255, 255, 0) 29.19%);
    
    font-size: 1.25rem;
    line-height: 2.125rem;
    color: #fff;
}

body {
    background: #393939;
}
<button type="button" class="rounded-button">
  Watch video
</button>
  • 1
    thanks for the above I hadn't considered box shadow. Using your method is there a way to get the gradient (Transparent to White to Transparent) effect do you think? – Justin Erswell Sep 30 '21 at 11:30
  • It's possible if you know the background-color of the button. You could use `#4D4D4D` : `box-shadow: inset 130px -1px 5px 0 #4D4D4D, inset -5px 3px 5px -5px white;`. It might be better to use @Newbie 's approach for that effect. – TerminalVelocity Sep 30 '21 at 11:49