【问题标题】:Reproducing SVG gradient equivalent to CSS gradient with linear-gradient使用线性渐变再现 SVG 渐变等价于 CSS 渐变
【发布时间】:2022-01-10 12:17:44
【问题描述】:
您可以在现代网站中创建 CSS 渐变,使用以下简单方法:
background-image: linear-gradient(red, orange);
目标是在 SVG 中重新创建这种渐变,那么每个 CSS 停止默认使用的百分比是多少?
我们用下面的代码修改了不同的百分比(例如,50/50、25/75),但这些实验都没有产生相同的梯度。最接近的是 10/90,但是如果您省略它们,有人可以确认使用的默认百分比吗?
div {
height: 100px;
background-color: red;
background-image:
linear-gradient(
red 50%,
orange 50%
);
}
【问题讨论】:
标签:
html
css
svg
linear-gradients
【解决方案1】:
当你有 2 种颜色时,百分比是 0% 和 100%
.box {
height:200px;
background:
linear-gradient(to right,red,blue) top/100% 40%,
linear-gradient(to right,red 0%,blue 100%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
<div class="box">
</div>
如果我们检查the specification,我们可以看到:
渐变中的颜色是使用色标指定的。色标是颜色和位置的组合。虽然每个色标在概念上都有一个位置,但可以在语法中省略该位置,在这种情况下,它会由用户代理自动填充;详情见下文。
然后
当省略色标的位置时,它会自动定位在两个周围色标之间的中间位置。如果连续的多个停靠点缺少位置,则它们的间距相等。
以及全套规则:
必须执行以下步骤才能处理色标列表。应用这些规则后,所有色标都会有一个确定的位置和颜色,并且它们将按升序排列:
-
如果第一个色标没有位置,则将其位置设置为 0%。如果最后一个色标没有位置,则将其位置设置为 100%。
-
如果色标的位置小于列表中任何色标的指定位置,则将其位置设置为等于其之前任何色标的最大指定位置。
-
如果任何色标仍然没有位置,则对于每轮相邻的无位置色标,设置它们的位置,使它们在前后有位置的色标之间均匀间隔。
第一条规则是微不足道的。第二条规则意味着我们在逻辑上应该有一个增量。所以如果我们有类似linear-gradient(red 20%, blue 10%, yellow 5%) 的东西,它将被转换为linear-gradient(red 20%, blue 20%, yellow 20%)。第三条规则将简单地将非定位颜色定位在两个定位颜色之间。
所以如果我们有多个没有位置的颜色,它将是这样的:
.box {
height:100px;
background:
linear-gradient(to right,red,yellow,blue) top/100% 40%,
linear-gradient(to right,red 0%,yellow 50%,blue 100%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
.box1 {
height:100px;
background:
linear-gradient(to right,red,yellow,purple,blue) top/100% 40%,
linear-gradient(to right,red 0%,yellow 33.333%,purple 66.66%,blue 100%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
<div class="box">
</div>
<div class="box1">
</div>
如果我们有一些明确的位置,我们将有这样的:
.box {
height:100px;
background:
linear-gradient(to right,red,yellow,blue 80%) top/100% 40%,
linear-gradient(to right,red 0%,yellow 40%,blue 80%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
.box1 {
height:100px;
background:
linear-gradient(to right,red,yellow 20%,purple,blue 80%) top/100% 40%,
linear-gradient(to right,red 0%,yellow 20%,purple 50%,blue 80%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
<div class="box">
</div>
<div class="box1">
</div>
更复杂的案例:
.box {
height:100px;
background:
linear-gradient(to right,red 20%,yellow 5%,red,orange,blue 80%,pink) top/100% 40%,
linear-gradient(to right,red 20%,yellow 20%,red 40%,orange 60%,blue 80%,pink 100%) bottom/100% 40%;
background-repeat:no-repeat;
border:5px solid;
}
<div class="box">
</div>
【解决方案2】:
根据您的帖子,要在 SVG 中重现渐变,请在 svg <defs/> 元素中定义您的线性渐变。
参见下面的 sn-p(css 仅适用于 html div)。
div {
height: 100px;
width: 100px;
display: inline-block;
background-color: red;
background-image: linear-gradient(red, orange);
}
<div></div>
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px" viewBox="0 0 100 100">
<defs>
<linearGradient id="gradient" x1="0" y1="0" x2="0" y2="100%" >
<stop offset="0%" style="stop-color:red;stop-opacity:1" />
<stop offset="100%" style="stop-color:orange;stop-opacity:1" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#gradient)"/>
</svg>