Reproducing SVG gradient equivalent to CSS gradien

2020-02-15 02:10发布

You can create CSS gradients in modern sites with something as simple as:

background-image: linear-gradient(red, orange);

The goal is to recreate this gradient in SVG, so what percentages are being used by default for each CSS stop?

We tinkered with different percentages (e.g., 50/50, 25/75) with the code below, but none of these experiments produced the same gradient. The closest was 10/90, but could someone confirm the default percentages used if you omit them?

div {
  height: 100px;
  background-color: red;
  background-image:
    linear-gradient(
      red 50%, 
      orange 50%
    );
}

2条回答
神经病院院长
2楼-- · 2020-02-15 02:49

Per your post, to reproduce the gradient in SVG, define your linear gradient in the svg <defs/> element.

See the snippet below (the css only applies to the html divs).

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>

查看更多
Melony?
3楼-- · 2020-02-15 03:09

When you have 2 colors the percentages are 0% and 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>

If we check the specification we can see read:

The colors in gradients are specified using color stops. A color stop is a combination of a color and a position. While every color stop conceptually has a position, the position can be omitted in the syntax, in which case it gets automatically filled in by the user agent; see below for details.

And then

When the position of a color stop is omitted, it is positioned automatically halfway between the two surrounding stops. If multiple stops in a row lack a position, they space themselves out equally.

And the full set of rules:

The following steps must be applied in order to process the list of color stops. After applying these rules, all color stops will have a definite position and color and they will be in ascending order:

  1. If the first color stop does not have a position, set its position to 0%. If the last color stop does not have a position, set its position to 100%.

  2. If a color stop has a position that is less than the specified position of any color stop before it in the list, set its position to be equal to the largest specified position of any color stop before it.

  3. If any color stop still does not have a position, then, for each run of adjacent color stops without positions, set their positions so that they are evenly spaced between the preceding and following color stops with positions.

The first rule is trivial. The second rules means that we should logically have an incrementation. So if we have something like linear-gradient(red 20%, blue 10%, yellow 5%) it will get transformed to linear-gradient(red 20%, blue 20%, yellow 20%). The third rule will simply position non positionned color to be spaced equally between two positionned colors.


So if we have multiple colors without position it will be something like this:

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

And in case we have some defined positions we will have this:

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

More complex cases:

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

查看更多
登录 后发表回答