opacity vs fill-opacity in svg
Solution 1
The difference is exactly what the name indicates :). fill-opacity
is applicable only to the fill
of the element (or in other words, just its background), stroke-opacity
is applicable only to the stroke
whereas the opacity
is applicable to both.
The opacity
is kind of a post-processing operation. That is, the element (or group) as a whole (the fill + stroke) is rendered and then the transparency is adjusted based on the opacity setting whereas the fill-opacity
and stroke-opacity
are intermediate steps, so the transparency is individually added to the stroke and fill. So when stroke-opacity
and fill-opacity
are used together, the result would still not be the same as using opacity
(because the transparency on the fill will let the fill color show through wherever they overlap). You can see the difference visually in the first two elements below.
Also as indicated by Robert (in comments), fill-opacity
doesn't apply to image
whereas opacity
does work.
svg {
width: 100vw;
height: 100vh;
}
body {
background: url(http://lorempixel.com/600/600/nature/1);
height: 100vh;
}
polygon {
stroke-width: 3;
}
<svg viewBox='0 0 40 190'>
<polygon points='10,10 30,10 30,30 10,30' fill='steelblue' stroke='crimson' opacity='0.5' />
<polygon points='10,40 30,40 30,60 10,60' fill='steelblue' stroke='crimson' fill-opacity='0.5' stroke-opacity='0.5' />
<polygon points='10,70 30,70 30,90 10,90' fill='steelblue' stroke='crimson' fill-opacity='0.5' />
<polygon points='10,100 30,100 30,120 10,120' fill='steelblue' stroke='crimson' stroke-opacity='0.5' />
<image xlink:href='http://lorempixel.com/100/100/nature/3' x='8.5' y='130' width='23' height='23' stroke='crimson' opacity='0.5' />
<image xlink:href='http://lorempixel.com/100/100/nature/3' x='8.5' y='160' width='23' height='23' stroke='crimson' fill-opacity='0.5' />
</svg>
In the CSS world you can think of it as something like in the below snippet. (Note that I am not saying they are equal, there are subtle differences between SVG and CSS. It is just an attempt to explain what those SVG attributes would translate to in CSS.)
div {
height: 20vh;
width: 20vh;
margin: 30px auto;
font-family: Verdana;
font-size: 2vw;
}
div:nth-of-type(1) {
opacity: 0.5;
background: rgba(70, 130, 180, 1);
border: .35vw solid rgba(220, 20, 60, 1);
}
div:nth-of-type(2) {
background: rgba(70, 130, 180, 0.5);
border: .35vw solid rgba(220, 20, 60, 1);
}
div:nth-of-type(3) {
background: rgba(70, 130, 180, 1);
border: .35vw solid rgba(220, 20, 60, 0.5);
}
body {
background: url(http://lorempixel.com/600/600/nature/1);
height: 100vh;
}
<div></div>
<div></div>
<div></div>
Solution 2
In addition to affecting which parts of each individual element are affected (e.g. fill versus stroke) another difference is what happens when elements overlap within a group. opacity
affects the transparency of the group as a whole while fill-opacity
affects the transparency of the individual elements within the group. One consequence of this is that when elements within such a group overlap, there is a compounding effect in the region of overlap when fill-opacity
is used but not when opacity
is used. This is demonstrated in the image below when a (fill-)opacity of 0.5 is applied to either each element within a group or to the group itself.
<svg height="200">
<g transform="translate(0, 0)">
<rect x="10" y="10" width="40" height="40" fill-opacity="0.5"/>
<rect x="30" y="30" width="40" height="40" fill-opacity="0.5"/>
</g>
<g transform="translate(80, 0)" fill-opacity="0.5">
<rect x="10" y="10" width="40" height="40"/>
<rect x="30" y="30" width="40" height="40"/>
</g>
<g transform="translate(0, 80)">
<rect x="10" y="10" width="40" height="40" opacity="0.5"/>
<rect x="30" y="30" width="40" height="40" opacity="0.5"/>
</g>
<g transform="translate(80, 80)" opacity="0.5">
<rect x="10" y="10" width="40" height="40"/>
<rect x="30" y="30" width="40" height="40"/>
</g>
<text transform="translate(170,45)">fill-opacity</text>
<text transform="translate(170,125)">opacity</text>
<text transform="translate(10,175)">applied to</text>
<text transform="translate(0,190)">each element</text>
<text transform="translate(90,175)">applied to</text>
<text transform="translate(103,190)">group</text>
</svg>
Solution 3
fill-opacity
controls the opacity for the fill color. opacity
controls the opacity of the entire thing.
Take a look at this demo: https://jsfiddle.net/DerekL/9mvrL66g/
Solution 4
I found this table helpful when considering which flavor of opacity
to use with SVG
. Let's not forget about stroke-opacity
and stop-opacity
.
| Attribute | Explanation | Applies to: |
|:--------------:|:----------------------------------:|:------------------------------------:|
| opacity | The overall opacity of the element.| Everything but gradient stops |
| fill-opacity | The opacity of the fill paint. | Elements with the attribute 'fill' |
| stroke-opacity | The opacity of the stroke paint. | Elements with the attribute 'stroke' |
| stop-opacity | The opacity of the gradient stop. | Gradient stops |
ak_rails
Striving to write beautiful code that solves real problems.
Updated on November 16, 2020Comments
-
ak_rails over 3 years
What is the difference in
opacity
vsfill-opacity
in SVG?I referred the docs for fill-opacity and opacity but I am confused what is meant by
fill-opacity: opacity of the content of the current object
vs
opacity: transparency of an object
-
Robert Longson almost 8 yearsWhat about flood-opacity?
-
Robert Longson almost 8 yearsThere's nothing incorrect here but ideally you'd explain how opacity=0.5 differs from setting both fill-opacity=0.5 and stroke-opacity=0.5.
-
Harry almost 8 years@RobertLongson: Oh yeah. Wanted to add a sample for that but seem to have forgot. Per my understanding the only difference would be that
opacity='0.5'
is done as something like post processing and so it will be like the fill + stroke painted and then opacity reduced whereas the other two are like intermediate options and so when both are used together the stroke's opacity will show a bit of the fill's color through (where they overlap). Are there any other differences? -
Robert Longson almost 8 yearsCorrect + opacity applies to images, fill/stroke opacity doesn't.
-
ak_rails almost 8 yearsThanks for the detailed answer, this clears my confusion. Thank you @RobertLongson for the additional info.
-
ak_rails almost 8 yearsThank you for the demo.. that helps
-
ak_rails almost 8 yearsThank you. The table is very helpful.