CSS 三角形以适应可变大小的 div 元素

CSS triangle to fit variable sized div elements

请参考我的fiddle。我的目标是创建一个三角形(放置在 div 内),并使其完全适合(角到角)。

以下是概述的规则:

.one {
  width: 100px;
  /* Unknown */
  height: 30px;
  /* Unknown */
  background: #ccc;
}
.two {
  width: 40px;
  /* Unknown */
  height: 90px;
  /* Unknown */
  background: #aaa;
}
.three {
  width: 70px;
  /* Unknown */
  height: 70px;
  /* Unknown */
  background: #aaa;
}
.triangle {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 0 50px 50px;
  border-color: transparent transparent #007bff transparent;
}
<div class="one"></div>
<br>
<div class="two"></div>
<br>
<div class="three"></div>
<br>

<div class="triangle"></div>

JSFiddle Reference

使用 border 实现此效果对于动态大小的容器是不可能的,因为它们不能采用百分比值或根据容器尺寸的变化进行调整。他们只能使用像素或视口单位。对于动态容器,这两者都没有多大用处。

可以通过在容器顶部放置一个伪元素来使用变换,但它们需要根据三角方程计算元素的高度和宽度。更简单的方法是渐变和 SVG 方法。

使用渐变:

您可以使用带有 to [side] [side] 语法的渐变来做到这一点。这是响应式的,适用于所有容器尺寸。唯一的缺点是在某些情况下,宽度或高度相对于另一个太大时会出现锯齿线。

这样做的一个优点是它不需要任何额外的元素(SVG 或 HTML,甚至不需要伪元素)但缺点是当悬停和单击效果仅需要三角形时(受限到三角形的边界)。由于元素仍然是rectangle/square,即使鼠标在三角形外但在容器内,也会触发悬停或点击效果。

.one {
  width: 100px;
  height: 30px;
  background-color: #ccc;
}
.two {
  width: 40px;
  height: 90px;
  background-color: #aaa;
}
.three {
  width: 70px;
  height: 70px;
  background-color: #aaa;
}
div {
  background-image: linear-gradient(to top left, blue 50%, transparent 51%);
}
<div class="one"></div>
<br>
<div class="two"></div>
<br>
<div class="three"></div>
<br>


使用 SVG:

您也可以像下面的代码片段一样使用 SVG path 元素来实现。 SVG 必须相对于容器绝对定位,并且具有父级宽度和高度的 100%。

对三角形使用 SVG 而不是渐变的优点是悬停和单击效果可以单独添加到三角形。

.one {
  width: 100px;
  height: 30px;
  background-color: #ccc;
}
.two {
  width: 40px;
  height: 90px;
  background-color: #aaa;
}
.three {
  width: 70px;
  height: 70px;
  background-color: #aaa;
}

div{
  position: relative;
}
div > svg {
  position: absolute;
  height: 100%;
  width: 100%;
}
svg path{
  fill: #0007bf;
}
svg path:hover{
  fill: crimson;
}
<div class="one">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>
<div class="two">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>
<div class="three">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>

渐变

风格

.triangle {
width: 100%;
height: 100%;
background: linear-gradient(to bottom right, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, #007bff 50%, #007bff 100%)
}

html

<div class="one">
  <div class="triangle"></div>
</div><br>
<div class="two">
  <div class="triangle"></div>
</div><br>
<div class="three">
  <div class="triangle"></div>
</div>