
SVG Fills: none or transparent?
A ‘fill’ quandry
As I worked through an exercise in D3.js in Action, I was prompted to create a rectangle with only an outline and no fill. Which I did as follows:
<rect x="100" y="100" width="20" height="20" fill="none" stroke="black" />
When I read through the solution though, I noticed that they did one thing differently: fill="transparent"
instead of my fill:"none"
.
I was curious about this difference, and decided to dig into transparent
vs none
as SVG fill properties and why I might want to use each.
Presentation attributes and style
Fill
and stroke
are SVG presentation attributes and can also be defined through the style attribute. The fill
property defines the color that is used to paint the shape.
Which means, you can set an SVG fill color…
// As a SVG attribute property
<rect ... fill="black"/>
// Or as a CSS element style property
<rect ... style="fill: black;"/>
Testing fills
So what is the difference between fill: "none"
and fill: "transparent"
when applied as an svg attribute? And how do these interact with other presentation attributes like stroke
?
In the following example 3 SVG rect
s are defined. They are each placed in a dashed blue outline to make it clearer where they sit (the first rectangle is there but not visible!). They all have a dark-on-hover
class on them, which should change the shape fill to a darker shade of pink.
// Leftmost square
<rect class="dark-on-hover" ... fill="none" />
// Middle square
<rect class="dark-on-hover" ... fill="none" stroke="hotpink"/>
// Rightmost square
<rect class="dark-on-hover" ... fill="transparent" stroke="hotpink"/>
See the Pen SVG fill none vs. transparent by Luisa Vasquez (@VLuisa) on CodePen.
Some insights from this experiment
-
As expected,
fill: "none"
leads to nothing appearing on screen. However, it’s important to note thatnone
prevents anything from being painted to the screen inside the shape, which means that this shape cannot be used as an event target. If you try hovering inside the leftmost container, nothing will happen even though the css class is defined to target the rectangle and give it a fill of a darker color. -
Because the inside of the shape is not painted to the screen, adding a
stroke
to a shape withfill: "none"
leads to interesting results. In the middle rectangle you can test it and observe that the shape only changes fill color while hovering on the stroke itself. For a thin stroke this can be difficult to target and lead to unexpected results. For thicker strokes this could be used intentionally. -
If the goal is to have a shape with a stroke but no (visible) fill, then using
fill: "transparent"
with a definedstroke
is likely the intended set of properties. This results in a rectangle that can predictably be targeted to trigger results - such shifting the fill from transparent to another color on hover.