Using SVG fragments
There is a way to make image.svg#1
and image.svg#2
point to a variant of the same image.
bucket.svg#fill1 | bucket.svg#fill2 | bucket.svg#fill3 | bucket.svg#fill4 |
---|---|---|---|
This is the same image 4 times. Only one svg is downloaded as the part after the #
is not sent in the HTTP
request.
The :target
pseudo class
The trick is to use CSS. Thanks to the :target
selector we can differentiate between various states of the image.
The
:target
pseudo-class represents the unique element, if any, with an id matching the fragment identifier of the URI of the document.
A fragment identifier of a URI is the part that comes after the #
in the URI. In other words: if the uri is bucket.svg#fill1
the fragment is fill1
, thus :target
will match the element with id="fill1"
. By cleverly using this you can do some cool things.
How to use it in SVG
SVG allows you to add a style sheet. This can be placed in the defs
element of the code. The following SVG code resembles the code of bucket.svg
from above.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ...>
<defs>
<style>
#fill1,
#fill2,
#fill3,
#fill4 {
visibility: hidden;
}
:target {
visibility: visible !important;
fill: #0000ff;
paint-order: markers stroke fill;
}
</style>
</defs>
<path d="m19.543 11.888v-1.5822c0-1.007..." />
<path id="fill4" d="m4.3895 24.698h21.89..." />
<path id="fill3" d="m4.3895 32.108h21.89..." />
<path id="fill2" d="m4.7935 38.578 21.49..." />
<path id="fill1" d="m5.3995 44.968 20.52..." />
<path d="m27.261 22.197c-.79074 10.136-..." />
</svg>
The image below explains the structure:
Each level of filling has its own element filling the bucket to the desired level. Because all the fill...
elements have visibility: hidden
, only the fill...
that is in the fragments specifier will be shown (because the visibility is overwritten).
Showing and hiding multiple elements
The fragment specifier can only match one element at a time. If you want to match multiple elements, you can assign them a class
, for example hidden
. By assigning an id
to the root svg
-tag itself, the CSS selector :root:target .hidden
will select all elements with the class hidden
. The :root
element is an identifier for the root svg
-tag. Note that if there is no id
assigned to the root element, the URI without fragment specifier will target the root element in some browsers.
The same trick can be used by grouping all elements in multiple <g>
tags, and assigning each of them with a unique id. the code below gives an example
<svg ...>
<defs>
<style>
.inframe1,
.inframe2,
.inframe3,
.inframe4 {
visibility: hidden;
}
#frame1:target .inframe1 {
visibility: visible !important;
}
#frame2:target .inframe2 {
visibility: visible !important;
}
#frame3:target .inframe3 {
visibility: visible !important;
}
#frame4:target .inframe4 {
visibility: visible !important;
}
</style>
</defs>
<g id="frame1">
<g id="frame2">
<g id="frame3">
<path class="inframe1" ... />
<path class="inframe2" ... />
<path class="inframe3" ... />
<path class="inframe1 inframe2" ... />
<path class="inframe1 inframe2 inframe4" ... />
<path class="inframe4" ... />
</g>
</g>
</g>
</svg>