1

I need to create a button with straight, beveled corners instead of rounded corners, for example, this:

beveled corner

Instead of this:

rounded corner

I can't use multiple box-shadow declarations, because I need a 1px border to outline the whole shape. And I can't use the arrow trick from a 0px by 0px div because of the same problem. Using -moz-linear-gradient etc. won't work because it will only effect the top half of the element, and I need the angle to continue all the way to the bottom.

border-radius is closest, but it's rounded by default. Is it possible to CSS or JavaScript to achieve this effect?

Harry
  • 87,580
  • 25
  • 202
  • 214
user1997781
  • 1,913
  • 2
  • 14
  • 17
  • 1
    The not-universally-supported `border-image` may be your best bet. I have a vague recollection of seeing something about a "CSS Shapes" proposal. (*edit* - well CSS Shapes seems to be irrelevant; never mind.) – Pointy Jul 09 '13 at 21:14
  • 2
    I would use a background image – TGH Jul 09 '13 at 21:14
  • @TGH yes that would be the simplest thing (and what one would do in 2009 :) It also might be possible to do something interesting with CSS translate/rotate. – Pointy Jul 09 '13 at 21:15
  • 1
    The deciding factor will be browser support requirements :-) – TGH Jul 09 '13 at 21:20

4 Answers4

0

I've seen some CSS tricks where you can use transparent borders and border width to create all kinds of triangular shapes, that might be what you are looking for, you can just add it to the ends of your button. here An alternative would be to create button with an image background. Manipulating an image would be much easier.

EDIT: Apparently, there's a Triangle Generator, who knew?

Seano666
  • 2,238
  • 1
  • 15
  • 14
0

Fiddle

A daring use of CSS3 pseudo elements

CSS Code :

div {
    width: 118px; /* 118 = rectangle width - 2 */
    height: 33px; /* 33 = shape height - 2 */
    border: 1px solid #007bff;
    background-color: white;
}

div:before {
    content: '';
    border-right: 30px solid transparent; /* 30 = triangle width */
    border-bottom: 35px solid #007bff; /* 35 = shape height */
    float: left;
    margin-left: 119px; /* 121 = rectangle width - 1 */
    margin-top: -1px; /* always 1*/
}

div:after {
    content: '';
    border-right: 29px solid transparent; /* 29 = triangle width - 1 */
    border-bottom: 33px solid white; /* 33 = shape height - 2 */
    float: left;
    margin-left: 118px; /* 120 = rectangle width - 2 */
    margin-top: -34px; /* 34 = shape height - 1 */
}
assembly_wizard
  • 2,034
  • 1
  • 17
  • 10
0

I can't take the credit for this answer but I found somebody that has a solution for this. Check out this fiddle.

It would work something like this:

HTML:

<div id="box3">
Content Here  
<div id="box3bottom"></div>
</div>

CSS:

    p {
    margin: 10px;
}

#box1, #box2, #box3 {
    background-color: #207cca;
    border: 1px solid black;
    color: white;
    height: 200px;
    margin: 20px auto;
    position: relative;
    text-align: center;
    width: 300px;
}
#box1:before, #box2:before, #box3:before {
    background-color: white;
    border-bottom: 1px solid black;
    content: "";
    height: 20px;
    left: -12px;
    position: absolute;
    top: -8px;
    -moz-transform: rotate(-45deg);
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
    width: 30px;
}

#box2:after, #box3:after {
    background-color: white;
    border-bottom: 1px solid black;
    content: "";
    height: 20px;
    position: absolute;
    right: -12px;
    top: -8px;
    -moz-transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
    width: 30px;
}

#box3bottom {
    height: 100%;
    left: 0px;
    position: absolute;
    top: 0px;
    width: 100%;
}
#box3bottom:before {
    background-color: white;
    border-top: 1px solid black;
    bottom: -8px;
    content: "";
    height: 20px;
    left: -12px;
    position: absolute;
    -moz-transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
    width: 30px;
}
#box3bottom:after {
    background-color: white;
    border-top: 1px solid black;
    bottom: -8px;
    content: "";
    height: 20px;
    position: absolute;
    right: -12px;
    -moz-transform: rotate(-45deg);
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
    width: 30px;
}
TCD Factory
  • 2,344
  • 2
  • 15
  • 12
  • This works beautifully in FF, Chrome, and IE 10...but not in IE 9 or 8, otherwise it'd be perfect. Any ideas? – user1997781 Jul 10 '13 at 14:25
  • It should work in IE 9... I'm surprised if it doesn't. IE8 or lower on the other hand don't really support the :after pseudo selector so that is an issue there. There is a couple java-script poly-fills that I've seen that can help with that. Here is one: https://code.google.com/p/ie7-js/ – TCD Factory Jul 25 '13 at 06:00
0

I ended up using a background image on a div that overlaid the menu, and changed the class of both the last tab and the div with JavaScript when the last tab was selected.

I would have liked to do this purely through CSS, and the use of :before and :after pseudo elements that were offset came very close, but it was too difficult to get a pixel-perfect layout working across all browsers.

Here's my code for the curious.

Javascript:

if($('.tabs .tab-right').hasClass('selected')){
    $(".tab .angle").addClass('angle-selected');
}else{
    $(".tab .angle").removeClass('angle-selected');
}

CSS:

.tabs .tab-right {
    padding: 8px 28px 8px 12px;
}
.tabs .angle {
    background: url("../img/angle-noborder.png") no-repeat transparent;
    height: 35px;
    width: 28px;
    display: inline-block;
    position: relative;
    right: 28px;
}
.tabs .angle.angle-selected {
    background: url("../img/angle-border.png") no-repeat transparent;
}
user1997781
  • 1,913
  • 2
  • 14
  • 17