Is it possible to create the following shape as a DIV
in CSS.
The browser support is not important.
Using SVG:
Below is a sample using SVG polygon
which can also be scaled easily. Text (if required) can be absolutely positioned on top of the shape.
.shape-svg {
position: relative;
height: 100px;
width: 300px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
polygon {
fill: black;
}
/* Just for demo*/
.shape-svg{
transition: all 1s;
}
.shape-svg:hover {
height: 200px;
width: 600px;
}
<div class="shape-svg">
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<polygon points='5,35 100,0 95,100 0,100' />
</svg>
</div>
The shape can be created using SVG clip path also instead of polygon.
Using CSS and Single Element:
The same shape can be achieved with CSS using only one element also. The key is to set the transform-origin
as the side that is required to be straight.
.shape{
height: 100px;
width: 300px;
margin-top: 50px;
background: black;
transform-origin: 0% bottom;
transform: perspective(300px) rotateY(-15deg) skewX(-10deg);
transition: all 1s;
}
.shape:hover{
width: 350px;
height: 150px;
transform: perspective(450px) rotateY(-15deg) skewX(-10deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
The shape achieved using this method can also be scaled. However as the height of the shape increases, the right side becomes taller and pushes the top-right corner even more higher. So, either the rotation angle needs to be decreased (or) the perspective needs to be increased (shape needs to be moved farther away) for the height of the right side to remain small enough and be within the viewing area. Or else, the margin-top should be increased.
Below is an explanation on why this happens:
0%
and so the height of the left side of the shape would be constant and that of the right side would keep increasing based on the rotation angle. There is no such problem if only the width increases because the rotation angle is too minimal and so the shape's right side will never get anywhere close enough to the viewer to look very tall.
The shape in question is not an exact duplicate of the one discussed here but you can get some more ideas by looking at it :)
You could look into CSS transformations (transform
) I have created a JsFiddle with a quick example.
HTML
<div class="skew"></div>
CSS
/* Skew the container one way */
.skew {
background: #000;
display: inline-block;
height: 50px;
width: 500px;
margin-top: 100px;
-webkit-transform: skewY(-5deg);
-moz-transform: skewY(-5deg);
-ms-transform: skewY(-5deg);
-o-transform: skewY(-5deg);
transform: skewY(-5deg);
}
NOTE:
You may need to include other transformations to get the unbalanced look.
--EDIT--
Here is another solution but using :before
and :after
CSS. JsFiddle.
You cannot skew an element like this directly, you'll need to use two elements (or generated content) and hide certain overflow to make the flat bottom edge:
http://jsfiddle.net/6DQUY/1/
#skew {
height: 240px;
overflow: hidden;
}
.skew {
background: #000;
display: inline-block;
height: 300px;
width: 500px;
margin-top: 100px;
transform: skew(-8deg, -8deg);
}
Note: I removed the cross browser definitions for better readability.
UPDATE: This would be a more fluid example which resizes in set dimensions: http://jsfiddle.net/6DQUY/3/. Note the padding-bottom on the wrapper which defines the ratio. You may have to play around with the percentage amounts.
#skew {
padding-bottom: 20%;
overflow: hidden;
position: relative;
}
.skew {
background: #000;
position: absolute;
top: 30%;
right: 8%;
left: 8%;
height: 100%;
transform: skew(-8deg, -8deg);
}