I'm wondering if there's an "easy" way to do something like below using CSS3, I want to avoid using images and absolute positioning, or similar, and would prefer to use some CSS method to achieve this.
I would also like to avoid using any fixed heights for this style too, since I'll be using the same style on various elements that all vary in size and colour.
You can use a simple clip-path in the CSS:
clip-path:polygon(0 0, 100% 0, 95% 50%, 100% 100%, 0 100%, 5% 50%);
Result (in Chrome):
ONLINE DEMO
But be aware of that the support isn't that great yet for all browsers. Currently it does not work in FF as far as I can tell (I believe you can use SVG for FF instead).
Update
Ok, after playing around with SVG (I'm no expert on SVG) I came up with a "prototype" that works in FF:
In HTML:
<!-- For firefox -->
<svg class="svg-graphic" width="250" height="36" viewBox="0 0 250 36" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<clipPath id="mask">
<polygon points="0, 0, 250, 0, 235, 18, 248, 35, 1, 35, 15, 18" />
</clipPath>
</svg>
Then set its ID as clipping path in CSS:
clip-path:url(#mask);
And it will produce this in Firefox:
(fiddle updated with this code)
This allows your cut-out areas to be transparent:
HTML
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
CSS
.left {
width: 0;
height: 0;
border-top: 60px solid red;
border-bottom: 60px solid red;
display: inline-block;
border-left: 60px solid transparent;
}
.center {
width: 300px;
height: 120px;
background-color: red;
display: inline-block;
margin-left: -4px;
margin-right: -4px;
}
.right {
width: 0;
height: 0;
border-top: 60px solid red;
border-bottom: 60px solid red;
display: inline-block;
border-right: 60px solid transparent;
}
Updated Fiddle w/ background image to show trasparency: http://jsfiddle.net/Eg9jF/1/
You can do it using CSS3 gradients for support in most modern browsers:
h1 {
background: red;
display: inline-block;
color: white;
font-family: sans-serif;
padding: .5em 1em;
margin: 5em;
position: relative;
}
h1:before, h1:after {
content: '';
width: 2em;
height: 100%;
position: absolute;
top: 0;
}
h1:before {
left: -2em;
background-image: -webkit-linear-gradient(45deg, transparent 50%, #ff0000 50%), -webkit-linear-gradient(-45deg, #ff0000 50%, transparent 50%);
background-image: -moz-linear-gradient(45deg, transparent 50%, #ff0000 50%), -moz-linear-gradient(-45deg, #ff0000 50%, transparent 50%);
background-image: -o-linear-gradient(45deg, transparent 50%, #ff0000 50%), -o-linear-gradient(-45deg, #ff0000 50%, transparent 50%);
background-image: linear-gradient(45deg, transparent 50%, #ff0000 50%), linear-gradient(-45deg, #ff0000 50%, transparent 50%);
}
h1:after {
right: -2em;
background-image: -webkit-linear-gradient(-135deg, transparent 50%, #ff0000 50%), -webkit-linear-gradient(135deg, #ff0000 50%, transparent 50%);
background-image: -moz-linear-gradient(-135deg, transparent 50%, #ff0000 50%), -moz-linear-gradient(135deg, #ff0000 50%, transparent 50%);
background-image: -o-linear-gradient(-135deg, transparent 50%, #ff0000 50%), -o-linear-gradient(135deg, #ff0000 50%, transparent 50%);
background-image: linear-gradient(-135deg, transparent 50%, #ff0000 50%), linear-gradient(135deg, #ff0000 50%, transparent 50%);
}
Demo
(You may run into this problem, but you can read how to solve it.)
I needed to do this for each of the headers in my 3 column row and I only needed a cut out on one side. None of these answers worked for me so I came up with this.
CSS
#test {
height: 66px;
width: 90%;
background-color: #2a6999;
position: relative;
}
#test::before {
z-index: -1;
content: "";
position: absolute;
left: 25px;
width: 100%;
height: 33px;
top: 0px;
background-color: #2a6999;
-webkit-transform: skew(-45deg);
-moz-transform: skew(-45deg);
-o-transform: skew(-45deg);
-ms-transform: skew(-45deg);
transform: skew(-45deg);
}
#test::after {
z-index: -1;
content: "";
position: absolute;
left: 25px;
width: 100%;
height: 33px;
top: 33px;
background-color: #2a6999;
-webkit-transform: skew(45deg);
-moz-transform: skew(45deg);
-o-transform: skew(45deg);
-ms-transform: skew(45deg);
transform: skew(45deg);
}
Fiddle Demo