I've been trying to figure out how to make a custom shape in CSS that visually will look like this:
With the property of background:rgba(44, 44, 48, 0.9)
and border:6px solid rgba(29, 30, 35, 0.9);
My problem is that I cannot find a way to make the top-right and bottom-left border look like the image I provided. Tried the tips on CSS Custom Shape on CSS-Tricks but it doesn't seem to solve the problem as it cannot have background. Any ideas?
Example explained First, we create a <div> element (class="background") with a background image, and a border. Then we create another <div> (class="transbox") inside the first <div>. The <div class="transbox"> have a background color, and a border - the div is transparent.
To achieve this, use a color value which has an alpha channel—such as rgba. As with opacity , a value of 1 for the alpha channel value makes the color fully opaque. Therefore background-color: rgba(0,0,0,. 5); will set the background color to 50% opacity.
Style the cut corner with the ::before pseudo-element and use the content property required while using the :: before pseudo-element to generate and insert content. Set the position to "absolute" and add the top and right, border-top and border-right properties.
In CSS, we can create a transparent border by using the border property in a nested div tag.
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>
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With