Question

Is it possible to create the following shape as a DIV in CSS.

The browser support is not important.

slanted div in 2 directions

Was it helpful?

Solution

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);
}

OTHER TIPS

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:

  • Consider a rectangle positioned 300px in front of the viewer's eye. It is being rotated towards to the viewer and as the rotation happens, the side which is getting closer to the user will appear taller than the other side.
  • We have fixed the transform origin's x coordinate as 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.
  • Because the transform origin's y coordinate is bottom, the bottom side of the shape would be kept straight and any height increase on the right side of the element would be projected upwards resulting in the shape going outside of the screen.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top