Interacting with SVG image files using Twig
Pierre Poupin3 min read
What is the SVG file format and why should I care?
SVG stands for Scalable Vector Graphics.
It is a file format for vectorial images described using XML tags.
Since it is vectorial, it presents a few advantages:
- it is lightweight
- you can zoom it as much as you want without it getting blurry
- you can dynamically modify it (colours, shapes)
Dynamically change your SVG using CSS
The SVG format can be directly included in a HTML document as a DOM element.
Each stroke or shape is an object that can own a class
Knowing this, we can add CSS styles for strokes and shapes, and dynamically modify the objects.
We will use the following SVG file to illustrate our examples (credits to Jean-Rémi Beaudoin for the very nice drawing skills!).
This is the content of the svg file:
<?xml version="1.0" encoding="UTF-8"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 100 100"
height="100"
width="100">
<g
transform="translate(0,-952.36216)">
<path
d="m 5,1021.1122 56.071429,-56.96433 -3.75,50.71433 z"
class="my-path"
fill="#9f9f9f" />
<path
d="M 96.607142,1036.8265 5,1021.1122 l 52.321429,-6.25 z"
fill="#7a7a7a"
class="my-path" />
<path
d="m 96.607142,1036.8265 -35.535713,-72.67863 -3.75,50.71433 z"
fill="#e0e0e0"
class="my-path" />
</g>
</svg>
For example, this will fill every svg path of the image with red:
path {
fill: #ff0000;
}
See the Pen wgKKMJ by Pierre Poupin (@Pierpo) on CodePen.
You can be more specific.
You can add classes to your SVG elements and select them independently:
.first-element {
fill: #ff0000;
}
.second-element {
fill: #00ff00;
}
You can even use the :hover
and :active
selectors, which is very nice to integrate nice buttons.
See the Pen EZadxE by Pierre Poupin (@Pierpo) on CodePen.
Using external SVG files
Naive approach
Most of the time, you won’t copy and paste your SVG directly in your HTML page.
You naturally want to import your SVG as an image.
The most intuitive way would be to include it this way:
<img src="my-svg.svg">
Which totally works for an SVG as it is.
However, including it like this prevents you from interacting with it.
The img
field will make your browser import it as a black box, and no operation on anything inside it would be possible.
That means the above CSS examples would not work!
Unfortunately, you will get the same behaviour if you use background-image: 'my-svg.svg'
.
One simple way using Twig
Thus, we want the SVG and all its sub-elements to be well determined parts of our DOM as well as our SVG to be an external file.
There’s a very simple way to do it using Twig! Simply use the source
function in your template.
{{ source('my-svg.svg') }}
This will copy the text present in the SVG file and put it in your generated HTML, thus make it a proper recursive and editable DOM element.
That’s it!