CSS 三角形以适应可变大小的 div 元素
CSS triangle to fit variable sized div elements
请参考我的fiddle。我的目标是创建一个三角形(放置在 div 内),并使其完全适合(角到角)。
以下是概述的规则:
- 将三角形放在所有 div 个元素内。
- 三角形的左下角应适合所有 div 内的左下角。
- 三角形的右上角应与所有 div 内的右上角相吻合。
- divs 具有固定的宽度和高度,但在现实生活中它们都是未知的,继承自 parent。
- 每个 div 的对角线角度都会不同,但没关系。
- 使用边框、渐变、变换或 SVG 来解决问题。我不想使用 canvas 或 PNG 等固定像素解决方案。
.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>
使用 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>
请参考我的fiddle。我的目标是创建一个三角形(放置在 div 内),并使其完全适合(角到角)。
以下是概述的规则:
- 将三角形放在所有 div 个元素内。
- 三角形的左下角应适合所有 div 内的左下角。
- 三角形的右上角应与所有 div 内的右上角相吻合。
- divs 具有固定的宽度和高度,但在现实生活中它们都是未知的,继承自 parent。
- 每个 div 的对角线角度都会不同,但没关系。
- 使用边框、渐变、变换或 SVG 来解决问题。我不想使用 canvas 或 PNG 等固定像素解决方案。
.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>
使用 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>