响应式CSS梯形形状

18

我想要创建一个响应式的梯形形状,可以使用CSS、SVG或Canvas实现。

梯形形状

我已经能够创建三角形,但是无法创建一个响应式的梯形形状。

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

我发现在SO上已经有很多关于梯形形状的问题,但很少有人说明它们比其他方法更好的原因,并且绝大部分都不具有响应式。

比如,这些问题不需要响应式,因此答案也不具备响应式:


@Paulie_D 这不是一个重复问题,因为你说它是一个重复问题的那个问题并不需要响应性,而且答案也不是响应式的。 - Stewartside
好的,重新打开。 - Paulie_D
也许这个应该是这个的副本? :) - Paulie_D
@Paulie_D,这取决于你。但我确实觉得4年前的那个问题并没有完全涵盖所有新技术,甚至响应式设计现在已经成为现代Web开发的基本要求。 - Stewartside
2个回答

49

创建梯形图形有许多不同的方法,每种方法都有其优点和缺点。

以下是各种方法的综合清单,所有方法均应具有响应性。

CSS边框

所有答案中最受支持的方式。它支持远至IE以及桌面和移动设备上的其他所有浏览器。

#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透视效果

CSS中的一个相对较新的方法是CSS变换中的透视方法。它在现代浏览器中得到了合理的支持,但要获得您想要的精确形状大小可能会很困难。

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

CSS Clip-Path

Clip-path可以创建SVG样式的剪切路径,并使用它来创建所需的形状。它是使用纯CSS创建任何形状的最简单方法(至少在我看来),但即使在现代浏览器中,它的支持程度也不太好。

#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 倾斜效果

以下内容是由web-tiki提供的。

这种方法与透视效果很相似,同样使用了 transform 属性,但也利用了伪元素来实现倾斜效果。

#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是可缩放矢量图形(Scalable Vector Graphic)的简称。网页浏览器将其视为一张图片,但你可以在SVG中添加文本和常规的HTML元素。

它得到了所有浏览器的很好支持,具体可参见此处:CanIUse

<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>

画布

画布类似于SVG,但使用栅格(基于像素)而不是矢量来创建形状。

浏览器对于画布的支持相当良好了解更多

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>


5
太棒了的回答,提供了我所想到的一切。 - Type-Style
不错!我认为还有一种方法:渐变 - 尽管这不支持悬停或其他指针事件.. - Max Payne

4

我将补充上面答案中缺失的方法:

多重背景和线性渐变

#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>

同样的想法可以用掩码来实现任何类型的背景:

#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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接