Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Responsive CSS Trapezoid Shape

I'm looking to create a responsive trapezoid shape which can be in either CSS, SVG or Canvas.

Trapezoid Shape

I have been able to create the triangle shape but not a trapezoid shape that is responsive.

div {
  width: 0;
  height: 0;
  border-top: 5vw solid transparent;
  border-left: 10vw solid red;
  border-bottom: 5vw solid transparent;
}
<div></div>

I have seen there are many questions on SO already that encompass a trapezoid shape but very little have reasons why they are better than other methods and also a large majority aren't responsive.

As an example, these questions don't require responsiveness and therefore the answers aren't responsive:

  • CSS3 Transform Skew
  • create an adaptive quadrilateral trapezoid in css
like image 449
Stewartside Avatar asked Nov 03 '15 16:11

Stewartside


People also ask

How do you make a trapezoid shape in CSS?

For that, we have to design a div element of HTML with a class property of CSS named trapezoid . After that, we use CSS border properties (left, top, and bottom), and we will use the default value of border-right for div to create a Trapezoid shape.

How do you make a shape responsive in CSS?

The key to making a truly responsive rectangle is vertical padding, either padding-bottom or padding-top will work. Why, you might ask? Vertical padding is calculated on the basis of the width of the element.

How do I create a polygon shape in CSS?

CSS | polygon() Function The polygon() function is an inbuilt function in CSS which is used with the filter property to create a polygon of images or text. Syntax: polygon( percentage | length); Parameter: This function accepts two parameter percentage or length which is used to hold the value of polygon size.


2 Answers

There are many different ways to create the trapezoid shape and each have their own benefits and downfalls.

Below is a comprehensive list of the various ways and all should be responsive.

CSS Border

The most well supported of all the answers. It is supportwed way back to IE and across all other browsers both on the desktop and mobile.

  • border - CSS | MDN

#trapezoid {
  border-left: 20vw solid red;
  border-top: 5vw solid transparent;
  border-bottom: 5vw solid transparent;
  width: 0;
  height: 10vw;
}
<div id="trapezoid"></div>

CSS Perspective

A fairly new approach within CSS is the perspective method within CSS Transforms. It is now reasonably well supported across all modern browsers but can be quite difficult to get the exact shape size you want.

  • perspective - CSS | MDN

#trapezoid {
  margin-top: 3vw;
  width: 20vw;
  height: 10vw;
  background-color: red;
  transform: perspective(20vw) rotateY(45deg);
}
<div id="trapezoid"></div>

CSS Clip-Path

Clip-paths create an SVG style clip and uses that to create the shape you want. It is the most simplistic way (atleast in my opinion) to create any and all shapes with just pure CSS but isn't very well supported, even in modern browsers.

  • clip-path - CSS | MDN
  • CanIUse Support
  • clip-path Generator

#trapezoid {
  width: 20vw;
  height: 20vw;
  -webkit-clip-path: polygon(0 0, 100% 20%, 100% 80%, 0% 100%);
  clip-path: polygon(0 0, 100% 20%, 100% 80%, 0% 100%);
  background: red;
}
<div id="trapezoid"></div>

CSS Skew with Pseudo Elements

This answer was given to me by web-tiki

It is similar to the perspective answer in that it uses transforms but also uses pseudo elements which have the skew on instead.

  • skew - CSS | MDN

#trapezoid {
  position: relative;
  background: red;
  width: 20vw;
  height: 12vw;
  margin: 8vw 0;
}
#trapezoid:before,
#trapezoid:after {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  background: inherit;
  transform-origin: 100% 0;
  transform: skewY(-20deg);
}
#trapezoid:before {
  transform: skewY(20deg);
}
<div id="trapezoid"></div>

SVG

SVG stands for Scalable Vector Graphic. The web browser views it as an image but you can add text and normal HTML elements within an SVG.

It is well supported across all browsers as viewable here: CanIUse

  • SVG | MDN

<svg id="trapezoid" viewbox="0 0 100 100" preserveAspectRatio="none" width="20%">
  <path d="M0,0
           L100,20
           L100,80
           L0,100z" fill="red"></path>
</svg>

Canvas

Canvas is similar to SVG but uses a raster (pixel based) instead of a vector to create the shape.

The browser support for Canvas is quite good.

var shape = document.getElementById('trapezoid').getContext('2d');
shape.fillStyle = 'red';
shape.beginPath();
shape.moveTo(0, 0);
shape.lineTo(100, 20);
shape.lineTo(100, 80);
shape.lineTo(0, 100);
shape.closePath();
shape.fill();
<canvas id="trapezoid"></canvas>
like image 186
Stewartside Avatar answered Oct 01 '22 02:10

Stewartside


I'm going to add the missing methods of the above answer:

Multiple background & linear-gradient

#trapezoid {
  width: 200px;
  height: 100px;
  background:
    /* Center area (rectangle)*/
    linear-gradient(red,red) center /100% calc(100% - 40px),
    /* triangle shape at the top*/
    linear-gradient(to bottom left, transparent 49%,red 51%) top    / 100% 20px,
    /* triangle shape at the bottom*/
    linear-gradient(to top    left, transparent 49%,red 51%) bottom / 100% 20px;
    
  background-repeat:no-repeat;
  animation:change 2s linear infinite alternate;
}

@keyframes change {
  from {
    width: 200px;
    height: 100px;
  }
  to {
    width: 120px;
    height: 180px;
  }
}
<div id="trapezoid"></div>

The same idea can be used with mask to have any kind of background:

#trapezoid {
  width: 200px;
  height: 100px;
  -webkit-mask:
    /* Center area (rectangle)*/
    linear-gradient(red,red) center /100% calc(100% - 40px),
    /* triangle shape at the top*/
    linear-gradient(to bottom left, transparent 49%,red 51%) top    / 100% 20px,
    /* triangle shape at the bottom*/
    linear-gradient(to top    left, transparent 49%,red 51%) bottom / 100% 20px;    
  -webkit-mask-repeat:no-repeat;
  background:url(https://picsum.photos/id/1064/400/300) center/cover;
  animation:change 2s linear infinite alternate;
}

@keyframes change {
  from {
    width: 200px;
    height: 100px;
  }
  to {
    width: 120px;
    height: 180px;
  }
}
<div id="trapezoid"></div>
like image 2
Temani Afif Avatar answered Oct 01 '22 02:10

Temani Afif