2

I would like to create a button that has 2 slight wings either side but not completely sure how to achieve this shape and was wondering if anyone could offer some guidance?

enter image description here

I understand that I will need to use the before and after psuedos but unsure how to create that slight curve going into the main body of the button?

Harry
  • 87,580
  • 25
  • 202
  • 214
styler
  • 15,779
  • 23
  • 81
  • 135
  • The trapezoid is simple enough but the radiused corners will be somewhat problematical. Sometimes an image is the best way to go. – Paulie_D Nov 05 '13 at 12:46
  • @Paulie_D how so? In my example I just used `border-top-left-radius` and `border-top-right-radius` and it was fine. – Albzi Nov 05 '13 at 12:47
  • 1
    Because the angled sides will not meet the border radius at a precise point that can be described with a border-radius property. They meet at a tangent. If the button is small enough no-one will notice...but that's a design decision. – Paulie_D Nov 05 '13 at 12:49
  • hey yeah border-radius doesn't seem to work so great with this example – styler Nov 05 '13 at 12:51
  • Ah I see what you mean now, but only if the button is big enough to realise. – Albzi Nov 05 '13 at 12:54
  • yeah the button eventually will be fluid so should be able to scale up and down without ever losing the quality – styler Nov 05 '13 at 12:54
  • Also, your example only relates to borders. Try putting some text in the div...since this is supposed to be a button. – Paulie_D Nov 05 '13 at 12:55
  • Text works OK (Could be better) @Paulie_D – Albzi Nov 05 '13 at 13:02

4 Answers4

2

Taken from this site here.

You can create thate shape by using this:

#trapezoid {
    border-bottom: 100px solid red;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    height: 0;
    width: 100px;
}

Here is an example

If you want text, put text in the div and add to the css this:

text-align:center;
line-height:30px; /*Size of bottom border*/

However you'll need to do some fiddling to get it to the right width and height etc.

UPDATED EXAMPLE

Albzi
  • 15,431
  • 6
  • 46
  • 63
2

To give the impression of a 3d plane rotating away from POV, like Star Wars opening crawls (recreated in svg too), use (prefixed) perspective and rotate3d (or rotateX).

To prevent aliasing, use an 1px transparent outline, as described here.

Running example

#trapezoid {
    -webkit-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
       -moz-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
         -o-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
        -ms-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
            transform : perspective(400px) rotate3d(1, 0, 0, 20deg);

        border-radius : 5px 5px 0 0;
              outline : 1px solid transparent;
}

If you instead do not want the text to be rotated, apply the code above to the ::before pseudo element, absolutely positioned relatively to its parent:

Running example with non rotated text

Code:

#trapezoid {    
         width : 200px;
        height : 50px;
        margin : 10px;
       padding : 10px;
      position : relative;
    text-align : center;
}

#trapezoid::before {
    -webkit-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
       -moz-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
         -o-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
        -ms-transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
            transform : perspective(400px) rotate3d(1, 0, 0, 20deg);
              outline : 1px solid transparent;
        border-radius : 5px 5px 0 0;
             position : absolute;
                  top : 0;
               bottom : 0;
                 left : 0;
                right : 0;
              content : '';
              z-index : -1;
           background : red;
}
Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
1

You can achieve that style by using :before and :after. The trick is to skew the elements on the sides and apply a little border-radius for the smooth rounding, like this:

button {
  border: 0 none;
  background-color: red;
  position: relative;

  font-size: 4em;
  margin-left: 100px; 
}

button:before,
button:after {
  content: '';
  position: absolute;
  background-color: inherit;
  top: 0;
  bottom: 0;
  width: 1em;
  z-index: -1;
}

button:before {
  left: -0.5em;
  -webkit-transform: skew(-10deg);
  transform: skew(-10deg);
  border-top-left-radius: 10%;
}

button:after {
  left: auto;
  right: -0.5em;
  -webkit-transform: skew(10deg);
  transform: skew(10deg);
  border-top-right-radius: 10%;
}

Fiddle here: http://jsfiddle.net/JyhwZ/1/

Severin
  • 381
  • 1
  • 3
  • Works well except in IE. – Albzi Nov 05 '13 at 13:00
  • It's nice but I think you have a lot of magic numbers in there....I'd be interested to see how flexible it is at smaller sizes, different widths etc. Still...nice! – Paulie_D Nov 05 '13 at 13:02
  • It should be pretty flexible since I used `ems` and `%`. In the fiddle, just change the font-size of the button from 4em to anything to see the button adapting. The only px-based value is the margin-left of the button which I use to only make enough space on the left side of the button for the :before to be fully visble. – Severin Nov 05 '13 at 13:06
1

LIVE DEMO

enter image description here

  <ul>
    <li><a href="#" class="active">HOME</a></li>
    <li><a href="#">ABOUT</a></li>
    <li><a href="#">CONTACT</a></li>
  </ul>

ul{
  list-style:none;
  border-bottom:2px solid #000;
  overflow:auto;
}
ul li a{
  color:#fff;
  float:left;
  border-bottom: 30px solid #EC2327;
  border-left:   4px solid transparent;
  border-right:  4px solid transparent;
  border-top:    4px solid #EC2327;
  border-radius: 14px 14px 0 0;
  height: 0;
  padding:0 20px;
  line-height:30px;
  text-align:center;
  text-decoration:none;
}
a.active{
  border-bottom-color: #000;
  border-top-color:    #000;
}
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313