How do I style this button?

I need to style the buttons in the image below (the one on the right is transparent, not white).

The bottom right corner is obviously the tricky part. It's not just a simple bevel; it is slightly rounded.

The best solution I have come up with is to apply an SVG image mask to the pseudo element located to the right of the button and scale down the correct padding to compensate. But this approach has its limitations:

  • it requires a fixed height button (at least if I want to keep the aspect ratio in the corner)
  • a different SVG is required for each button size.
  • I don't see how it can work for the transparent style of the button

So I hope someone can suggest a different / better approach!

thank

UPDATE:

Here is my current approach - https://codepen.io/peteheaney/pen/jwVEPm

$primary: #FAB500;

*, *::after, *::before {
    font-family: sans-serif;
    box-sizing: border-box;
}

.button {    
  background-image: none;
  border-width: 2px;
  border-style: solid;
  border-color: transparent;
  cursor: pointer;
  display: inline-block;
  font-weight: bold;
  margin-bottom: 0;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  touch-action: manipulation;
  vertical-align: middle;
  white-space: nowrap;
  transition: all 0.2s;

  &:active,
  &:hover,
  &:focus {
    text-decoration:none;
  }

  &--large {
    font-size: 15px;
    padding-left: 24.818px;
    height: 52px;
    line-height: 52px;
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
    position: relative;
    margin-right: 24.818px;

    &:after {
            border-top: 2px solid $primary;
            border-bottom: 2px solid $primary;
            background: $primary;
      content: "";
      border-top-right-radius: 6px;
      position: absolute;
      left: 100%;
      bottom: -2px;
      width: 24.818px;
      height: 52px;
      mask: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-right.svg) top left / cover;
    }
  }

    &--primary {
        color: #000;
        background-color: $primary;
        border-color: $primary;

        &:active,
        &:hover,
        &:focus {
            background-color: darken($primary, 2%);
            border-color: darken($primary, 2%);
        }
    }
}

      

enter image description here

+3


source to share


6 answers


I decided to go for the approach I demonstrated in this pen - https://codepen.io/peteheaney/pen/bRBOMq (compiled CSS version below)

*, *::after, *::before {
  font-family: sans-serif;
  box-sizing: border-box;
}

.button {
  background-image: none;
  border-style: solid;
  border-top-width: 2px;
  border-bottom-width: 2px;
  border-left-width: 2px;
  border-right-width: 0;
  border-color: transparent;
  cursor: pointer;
  display: inline-block;
  font-weight: bold;
  margin-bottom: 0;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  touch-action: manipulation;
  vertical-align: middle;
  white-space: normal;
  transition: all 0.2s;
}
.button:active, .button:hover, .button:focus {
  text-decoration: none;
}
.button--large {
  font-size: 15px;
  padding: 16px 0 14px 21px;
  border-top-left-radius: 6px;
  border-bottom-left-radius: 6px;
  position: relative;
  margin-right: 21px;
}
.button--large:before {
  content: "";
  position: absolute;
  left: 100%;
  top: -2px;
  width: 21px;
  height: calc(100% - 17px);
  border-top-right-radius: 6px;
}
.button--large:after {
  position: absolute;
  left: 100%;
  bottom: -2px;
  width: 21px;
  height: 21px;
  transition: all 0.2s;
}
.button--primary {
  color: #000;
  background-color: #FAB500;
  border-color: #FAB500;
}
.button--primary:before {
  background-color: #FAB500;
  transition: all 0.2s;
}
.button--primary:active:before, .button--primary:hover:before, .button--primary:focus:before {
  background-color: #f0ae00;
  border-color: #f0ae00;
}
.button--primary:after {
  content: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-primary-large.svg);
}
.button--primary:active, .button--primary:hover, .button--primary:focus {
  background-color: #f0ae00;
  border-color: #f0ae00;
}
.button--secondary {
  color: #000;
  border-color: #FAB500;
}
.button--secondary:before {
  border: 2px solid #FAB500;
  border-bottom: 0;
  border-left: 0;
  transition: all 0.2s;
}
.button--secondary:active:before, .button--secondary:hover:before, .button--secondary:focus:before {
  background-color: #FAB500;
}
.button--secondary:after {
  content: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-secondary-large.svg);
}
.button--secondary:active, .button--secondary:hover, .button--secondary:focus {
  background-color: #FAB500;
  border-color: #FAB500;
}
      

<a class="button button--large button--primary" href="">My button</a>

<a class="button button--large button--secondary" href="">My other button</a>
      

Run codeHide result




First, I split the right side into top and bottom (using: before and: after). The top-right pseudo-element only has a background color and a top-right radius. Thus, the upper right portion can have a flexible height, that is, the buttons do not have to have a fixed height. The pseudo-element at the bottom right is essentially SVG (using content: url (/path/to/svg.svg)). This pseudo-element always has a fixed width and height, so it maintains the size and aspect ratio regardless of the width / height of the button.

An outline style button is just a variation in a different style, with more borders and less background.

The only downside to this approach is the need to use a different SVG for each button style. But I'm happy with this compromise.

0


source


If you don't mind keeping the corner pressed, you can make the button invisible and just use a background image:

button{
    width:x;
    height:y;
    border:none;
    background-color:none
    background-image:url(button_image.png);
    background-position:center;
    background-size:x y;
    background-repeat:no-repeat;
}

      



With a button, button_image.png is an image of your button style without text.

0


source


You can try to do it like this using before

and after

:

.button {
  position: relative;
  display: inline-block;
  background-color: orange;
  color: white;
  padding: 20px 40px;
  font-size: 14px;
  border-radius: 5px;
  text-decoration: none;
}

.button:after {
  content: '';
  position: absolute;
  z-index: 10;
  display: block;
  bottom: -6px;
  right: -2px;
  width: 10px;
  height: 20px;
  transform: rotate(45deg);
  background-color: white;
}

.button:before {
  content: '';
  position: absolute;
  z-index: 100;
  display: block;
  bottom: -1px;
  right: 4px;
  width: 13px;
  height: 23px;
  transform: rotate(45deg);
  background-color: orange;
  border-radius: 10px;
}
      

<a href="#" class="button">Button</a>
      

Run codeHide result


0


source


Here's an example of how this can be achieved with pure CSS. However, an image or SVG may be a more efficient way to solve this problem.

.Large{
  position:relative;
  display:inline-block;
  background:#FFB300;
  border:none;
  padding:20px 0 20px 30px;
  border-radius:10px 0 0 10px;
  height:40px;
  font:700 1.5em/40px Arial;
}
.Large::after{
  content:"";
  display:block;
  position:absolute;
  top:0;
  right:-30px;
  width:30px;
  height:50px;
  background:#FFB300;
  border-radius:0 10px 0 0;
}
.Large::before{
  content:"";
  display:block;
  position:absolute;
  bottom:0;
  right:-30px;
  width:0;
  height:0;
  border-top: 15px solid #FFB300; 
  border-right: 15px solid transparent;
  border-bottom: 15px solid transparent;  
  border-left: 15px solid #FFB300;
}
      

<a class="Large">LARGE</a>
      

Run codeHide result


0


source


I'm not very happy with my result, but here it goes just in case you can do it better.

Different color is just to make it easier to see what exactly.

I focused on the transparent solution. Once you've done that, it's easier to decide otherwise.

:root {
  --width: 10px;
  --width2: 14px;
}


.test {
  position: relative;
  margin: 20px;
  width: 300px;
  height: 150px;
  position: absolute;
  border: var(--width) solid transparent;
  border-image: linear-gradient(to bottom right, orange 0%, orange 70%, transparent 70%);
  border-image-slice: 1;
}

.test:before {
  content: "";
  position: absolute;
  height: 25px;
  width: 150px;
  right: 29px;
  bottom: -10px;
  transform: skewX(-45deg);
  border: solid 0px transparent;
  border-bottom-color: red;
  border-bottom-width: var(--width);
  border-right-color: red;
  border-right-width: var(--width2);
  border-bottom-right-radius: 25px;
}


.test:after {
  content: "";
  position: absolute;
  height: 50px;
  width: 25px;
  right: -10px;
  bottom: 29px;
  transform: skewY(-45deg);
  border: solid 0px transparent;
  border-bottom-color: red;
  border-bottom-width: var(--width2);
  border-right-color: red;
  border-right-width: var(--width);
  border-bottom-right-radius: 25px;
}
      

<div class="test"></div>
      

Run codeHide result


0


source


Another approach to Arthur.

If you are creating the bottom right image (white corner and yellow corner border), you can position it so that it stays in the bottom right corner and the rest of the button is on its own.

 button {
    background-image:url(corner.svg);
    height: 20px;
    padding: 5px;
    border-radius: 5px;
    background-color: yellow;
    background-repeat: no-repeat;
    background-position: bottom right;
}

      

0


source







All Articles