6

I am currently building a website which requires buttons to have a slant on the left hand side of the button. The website is responsive and the button requires rounded corners too. I am trying to avoid using background images too.

Would someone be able to show me a solution to this? Ignore the icon on the button, I am able to do this. I just need the slanted side.

div with slanted side and rounded corners

Sample jsfiddle

body {
  background: lightblue;
  font-family: sans-serif;
}
div {
  background: purple;
  width: 200px;
  padding: 30px;
  border: 3px solid white;
  color: white;
}
<div>Some Text</div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
Ben H
  • 502
  • 1
  • 7
  • 24
  • 3
    You could have a look at my answer here - http://stackoverflow.com/questions/28248723/rounded-arrow-shape-with-gradient-fill/28248994#28248994. The arrow is created with two parts each of which has a slant on one side and rounded corners. This (http://stackoverflow.com/questions/30441122/shape-with-a-slanted-side-responsive/30441123) is another thread that covers creation of a shape with one slanted side but it doesn't cover rounded corners. – Harry Aug 17 '15 at 08:19
  • possible duplicate of [Shape with a slanted side (responsive)](http://stackoverflow.com/questions/30441122/shape-with-a-slanted-side-responsive) – JJJ Aug 17 '15 at 08:20
  • Unfortunately from my understanding neither of those solutions will work because you cannot add a border and border radius to the pseudo elements? – Ben H Aug 17 '15 at 08:26
  • 1
    @BenH: The first thread that I linked does use `border-radius` on pseudo-elements and you can most definitely add border to pseudo elements. – Harry Aug 17 '15 at 08:28
  • @Harry I will take another look! thanks Harry – Ben H Aug 17 '15 at 08:39

3 Answers3

8

Note: I am adding a separate answer because though the answers that I linked in comment seem to give a solution, this one is a bit more complex due to the presence of border also along with the border-radius.

The shape can be created by using the following parts:

  • One main container element which is positioned relatively.
  • Two pseudo-elements which are roughly half the width of parent element. One element is skewed to produce the skewed left side whereas the other is not skewed.
  • The skewed pseudo-element is positioned at the left while the normal element is positioned at the right of the container element.
  • The skewed pseudo-element has only top, left and bottom borders. The right border is omitted as it would come right in the middle of the shape. For the pseudo-element that is not skewed, the left border is avoided for the same reason.
  • Left border of the skewed pseudo-element is a bit more thicker than other borders because skew makes the border look thinner than it actually is.

I have also added a hover effect to the snippet to demonstrate the responsive nature of the shape.

.outer {
  position: relative;
  height: 75px;
  width: 300px;
  text-align: center;
  line-height: 75px;
  color: white;
  text-transform: uppercase;
}
.outer:before,
.outer:after {
  position: absolute;
  content: '';
  top: 0px;
  height: 100%;
  width: 55%;
  background: purple;
  border: 2px solid white;
  border-left-width: 3px;
  z-index: -1;
}
.outer:before {
  left: 0px;
  border-radius: 20px;
  border-right: none;
  transform: skew(20deg);
  transform-origin: top left;
}
.outer:after {
  right: 0px;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
  border-left: none;
}

/* Just for demo of responsive nature */

.outer{
  transition: all 1s;
}
.outer:hover{
  height: 100px;
  width: 400px;
  line-height: 100px;
}
body{
  background: lightblue;
}
<div class='outer'>
  Call me back
</div>

Advantage:

  • A big advantage of this approach is that it provides a graceful fallback. That is, in non CSS3 compliant browsers it would look like normal button with rounded corners (and no slanted side).
  • The page (or container element) background need not be a solid color.
  • The shape itself can have non-solid colors (that is, images or gradients) as background. It would need some extra tweaking but the approach itself will remain same.

In the below snippet, I have given each component a different color to visually illustrate how the shape is achieved:

.outer {
  position: relative;
  height: 75px;
  width: 300px;
  text-align: center;
  line-height: 75px;
  color: white;
  text-transform: uppercase;
}
.outer:before,
.outer:after {
  position: absolute;
  content: '';
  top: 0px;
  height: 100%;
  width: 55%;
  background: purple;
  border: 2px solid white;
  border-left-width: 3px;
  z-index: -1;
}
.outer:before {
  left: 0px;
  border-radius: 20px;
  border-right: none;
  transform: skew(20deg);
  transform-origin: top left;
  background: seagreen;
  border-color: red;
}
.outer:after {
  right: 0px;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
  border-left: none;
  background: yellowgreen;
  border-color: maroon;
}

/* Just for demo of responsive nature */

.outer{
  transition: all 1s;
}
.outer:hover{
  height: 100px;
  width: 400px;
  line-height: 100px;
}
body{
  background: lightblue;
}
<div class='outer'>
  Call me back
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • This worked really well! Thank you @Harry! I have ended up using SVG paths as we have all the visuals however I will use this method for some of the variable buttons. :) – Ben H Aug 18 '15 at 07:34
  • @BenH: SVG paths are nice except for two things (1) Curves at each corner have to be coded through commands instead of just setting a property in CSS and (2) The border strokes in SVG tend to get thicker when scaled (that is, the stroke also scales). When only one height/width changes, it would make borders on two sides thicker than the other two. The SVG attribute which avoids that doesn't work in IE. I would recommend SVG for shapes anyday but just be careful with these two :) – Harry Aug 18 '15 at 07:39
  • 1
    i noticed that in IE the buttons did cause a few issues using SVG so I am going to try your method for them all. It's a shame as the icons look so much sharper when using the SVG buttons! – Ben H Aug 18 '15 at 13:54
5

Yes You can do using an white overlay using css-pseudo element or like this

.slantButton {
  position: relative;
  background-color: #8D3F81;
  border: 1px solid transparent;
  border-radius: 5px 5px 5px 20px;
  color: #fff;
  padding: 10px 20px;
  text-transform: uppercase;
  font-size: 18px;
  cursor: pointer;
  outline: 0;
}
.slantButton:before {
  content: '';
  position: absolute;
  top: 0;
  left: -5px;
  width: 0;
  height: 0;
  border-bottom: 42px solid #fff;
  border-right: 16px solid transparent;
}
<button class="slantButton">Call Me Back</button>

Explaination

I have applied different border radius to bottom left corner using

border-radius: 5px 5px 5px 20px;

Then using css triangle in pseudo element. Made one white overlay of triangle and made slant edge as you suggested

    .slantButton {
      position: relative;
      background-color: #8D3F81;
      border: 1px solid transparent;
      border-radius: 5px 5px 5px 20px;
      color: #fff;
      padding: 10px 20px;
      text-transform: uppercase;
      font-size: 18px;
      cursor: pointer;
      outline: 0;
    }
    .slantButton:before {
      content: '';
      position: absolute;
      top: 0;
      left: -5px;
      width: 0;
      height: 0;
      border-bottom: 42px solid rgba(0,0,0,0.5);
      border-right: 16px solid transparent;
    }
<button class="slantButton">Call Me Back</button>
Suresh Karia
  • 17,550
  • 18
  • 67
  • 85
2

This is also possible using CSS border-radius' by setting multiple values.

This does have a bit more curvature than your example image but it is much cleaner and doesn't require extra elements or pseudo elements.

body {
  background: lightblue;
  font-family: sans-serif;
}
div {
  background: purple;
  width: 200px;
  padding: 30px;
  border: 3px solid white;
  border-radius: 15px;
  border-bottom-left-radius: 50px 150px;
  color: white;
}
<div>Some Text</div>
Stewartside
  • 20,378
  • 12
  • 60
  • 81