Div with cut out edges, border and transparent background
Solution 1:
If you think in 3d, you can use the perspective
and rotateX()
properties to alter only one or two angles of an element.
This will allow you to style pseudo elements of the container to give them the desired shape and cut out the top right and bottom left corners.
You can also give the desired borders to the shape, (see following demo) :
DEMO
Output :
div {
position: relative;
width: 50%;
height: 300px;
margin: 10% auto;
background: rgba(0, 0, 0, 0.7);
border-top: 6px solid rgba(0, 0, 0, 0.8);
border-bottom: 6px solid rgba(0, 0, 0, 0.8);
}
div:before,
div:after {
content: '';
position: absolute;
top: -6px;
width: 20%;
height: 100%;
}
div:before {
right: 100%;
background: inherit;
border-top: 6px solid rgba(0, 0, 0, 0.8);
border-left: 6px solid rgba(0, 0, 0, 0.8);
border-bottom: 6px solid rgba(0, 0, 0, 0.8);
-webkit-transform-origin: 100% 0;
transform-origin: 100% 0;
-webkit-transform: perspective(1px) rotateY(-0.15deg);
transform: perspective(1px) rotateY(-0.15deg);
}
div:after {
left: 100%;
border-top: 6px solid rgba(0, 0, 0, 0.8);
border-right: 6px solid rgba(0, 0, 0, 0.8);
border-bottom: 6px solid rgba(0, 0, 0, 0.8);
border-left: none;
background: inherit;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-webkit-transform: perspective(1px) rotateY(0.15deg);
transform: perspective(1px) rotateY(0.15deg);
}
<div></div>
Solution 2:
You can create that shape by using only one element, with simple transforms
and overflow: hidden;
properties
You can add content in another element:
body {
background: url(http://i.imgur.com/RT7XR3C.jpg);
background-size: cover;
}
div {
height: 200px;
width: 300px;
margin: 40px auto;
overflow: hidden;
position: relative;
}
div:before {
content: '';
position: absolute;
left: -58px; /*-half buffer -left border*/
height: 188px;
width: 400px;
background: rgba(30, 30, 30, 0.8);
-webkit-transform: skewX(45deg);
-moz-transform: skewX(45deg);
transform: skewX(45deg);
border-left: 8px solid #222;
border-right: 8px solid #222;
border-top: 6px solid #222;
border-bottom: 6px solid #222;
}
div:after {
content: '';
position: absolute;
top: 0;
left: 0;
height: 157px;
width: 6px;
background: #222;
box-shadow:0 0 0 0 #222, 294px 43px 0 0 #222;
}
<div></div>
FIDDLE
Output:
Solution 3:
Unfortunately you cannot have a pseudo-element added to a pseudo-element (i.e. :after:after{}
will not work) - with a complex shape like yours, you might have to cheat a little and rely on pseudo-elements of its children.
<div class="fancy-box">
<h2>Title</h2>
<p>Content</p>
</div>
.fancy-box{/*container, top+bottom borders*/}
.fancy-box:before{/*left-top "square" corner*/}
.fancy-box:after{/*right-bottom "square" corner*/}
.fancy-box>p:before{/*left-bottom "dog ear" border*/}
.fancy-box>p:after{/*right-top "dog ear" border*/}
.fancy-box>h2:before{{/*left-bottom "dog ear" background*/}
.fancy-box>h2:after{/*right-top "dog ear" background*/}
Again, this fiddle shows you how it would work with solid colors (reasonably well, although I don't like the "thinner" angles) - but this would fail when you apply opacity. Your best would probably be around having "dog ears" made into pre-rendered semitransparent PNGs, for extra credit you could base64-encode them.
The "solution" above is a complete semantic horror though - you may have better luck using multiple backgrounds with pre-rendered graphics.