LearningSVG
This page is about my novice steps with Scalable Vector Graphics (SVG). Since SVG can be embedded into HTML documents it can even be considered a web technology, or web API. Consequently this page also has information about SVG's ties to HTML and CSS.
A separate page on this wiki has information about Inkscape, an open source vector graphics editor.
References
- [[wikpedia:SVG|Wikipedia]
- SVG reference over at the W3C.
- SVG reference at MDN Web Docs.
- SVG tutorial on w3schools.
- w3schools SVG reference on w3schools.
- Using SVG on CSS-Tricks shows how SVG integrates into HTML, and has a few teasers how CSS can be used to control SVG.
Shapes
Rectangle
Example for drawing a rectangle:
<rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill: blue; stroke: pink; stroke-width: 5; fill-opacity: 0.1; stroke-opacity: 0.9;" />
Notes:
- x/y define the upper-left corner of the rectangle
- width/height define the dimensions of the rectangle
- rx/ry (optional) define how rounded corners are
Circle and ellipse
Example for drawing a circle and an ellipse:
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /> <ellipse cx="200" cy="80" rx="100" ry="50" style="fill: yellow; stroke: purple; stroke-width: 2;" />
Notes:
- cx/cy define the center of the circle or ellipse. The default is 0/0.
- r defines the radius of the circle
- rx/ry define the horizontal/vertical radius of the ellipse
Line
Example for drawing a line:
<line x1="0" y1="0" x2="200" y2="200" style="stroke: rgb(255,0,0); stroke-width: 2;" />
Notes:
- x1/y1 define the starting point of the line
- x2/y2 define the end point of the line
Polyline
Example for drawing a polyline:
<polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" style="fill: white; stroke: red; stroke-width: 4;" />
Notes:
- The value of the
points
attribute consists of a series of x/y coordinates that define the polyline points. TODO: Is there a minimum number of points that have to be specified? It would be logical if at least three points had to be specified, because two points only are a regular line. - The order in which points are defined is important: It defines the order in which the lines that form the polyline are drawn.
- The path drawn by a polyline is usually open, unless you explicitly specify points that form a closed path.
Polygon
Examples for drawing a polygon:
<polygon points="200,10 250,190 160,210" style="fill: lime; stroke: purple; stroke-width: 1;" /> <polygon points="100,10 40,198 190,78 10,78 160,198" style="fill: lime; stroke: purple; stroke-width: 5; fill-rule: nonzero;" />
Notes:
- The value of the
points
attribute consists of a series of x/y coordinates that define the polygon points. The minimum polygon is a triangle, so at least three points must be specified. - The order in which points are defined is important: It defines the order in which the lines that form the polygon are drawn. This can be important when you have to define a fill rule.
- A polygon is always closed, i.e. a line is implicitly drawn from the last point to the first point.
Path
In the previous section we saw a number of elements for predefines shapes. However, the most generic of all drawing constructs are paths (<path>
element). These are used to draw arbitrary things.
TODO: Add examples.
Text
Examples for drawing a text:
<text x="0" y="15" fill="red">Hello world</text> <text x="0" y="15" fill="red" transform="rotate(30 20,40)">Hello world</text> <text x="0" y="15" fill="red">Hello world <tspan x="0" y="40">First line</tspan> <tspan x="0" y="65">Second line</tspan> </text> <a xlink:href="https://example.com/" target="_blank"> <text x="0" y="15" fill="red">Hello world</text> </a>
Notes:
- x/y defines the upper/left corner where the text begins
- The
tspan
element can be used to define several sub-groups of text, each with its individual set of properties - TODO: What about fonts?
Units
SVG units are the same as in CSS 2. Here's a short overview, a slightly more informative list is available on the LearningCSS page on this wiki. See the SVG specs for the ultimate reference.
- Absolute units: pt, pc, cm, mm, in.
- Relative units: em, ex, px.
- Percentages: Relative to the viewport size.
If the unit is omitted, it defaults to px
.
Here's a quote from the SVG specs on the use of px
(emphasis is mine):
One px unit is defined to be equal to one user unit. Thus, a length of "5px" is the same as a length of "5".
Note that at initialization, a user unit in the the initial coordinate system is equivalenced to the parent environment's notion of a px unit. Thus, in the the initial coordinate system, because the user coordinate system aligns exactly with the parent's coordinate system, and because often the parent's coordinate system aligns with the device pixel grid, "5px" might actually map to 5 devices pixels. However, if there are any coordinate system transformation due to the use of ‘transform’ or ‘viewBox’ attributes, because "5px" maps to 5 user units and because the coordinate system transformations have resulted in a revised user coordinate system, "5px" likely will not map to 5 device pixels. As a result, in most circumstances, "px" units will not map to the device pixel grid.
Stroke and fill
A shape or path is made up from lines. The way how those lines are drawn is defined by various properties:
- Stroke color: What color does the line have? This is defined by the
stroke
property. - Stroke width: How thick is the line? This is defined by the
stroke-width
property. - Stroke dash: Is the line solid or dashed, and how do the dashes look? This is defined by the
stroke-dasharray
property. - Stroke opacity: How transparent is the line? This is defined by the
stroke-opacity
property. - Stroke linecap: How does the end of a line look like (applies to open paths only)? This is defined by the
stroke-linecap
property.
The "fill" of a shape or path defines how the inside of the shape looks like. Various properties define the fill:
- Fill color: What color does the fill have? This is defined by the
fill
property. - Fill rule: Which parts of the shape or path are filled? This is defined by the
fill-rule
property. Possible values arenonzero
andevenodd
. TODO: How does this work?
General notes:
- Stroke and fill properties can be specified in two ways:
- CSS rules. Example:
<rect style="stroke: blue;" ... />
- Attributes. Example:
<rect stroke="blue" ... />
- CSS rules. Example:
- Color property values can be pre-defined color names (e.g.
blue
) or RGB values (e.g.rgb(0, 0, 0)
). - The
opacity
property can be used to control the opacity of the entire shape or path, i.e. both stroke and fill. - Opacity property values range from 0 (transparent) to 1 (opaque).
Object groups
SVG objects can be grouped with the <g>
element.
TODO: Write more.
Filters
An SVG filter is a collection of SVG filter primitives.
- In terms of SVG markup, the SVG element
<filter>
is composed of 0-n<fe...>
elements. Each SVG filter primitive has its own dedicated element with a name prefixed by "fe" (probably an abbreviation of "filter effect"), e.g.<feGaussianBlur>
. - The SVG element
<filter>
also has an attributeid
which is used to reference the filter. - When an element being drawn on the canvas references an SVG filter via the filter's
id
, the filter as a whole is applied to the element being drawn - meaning all SVG filter primitives that the filter is composed of are applied, according to the definition of the filter. - An SVG filter can be applied to individual SVG objects, but also to a group of SVG objects.
- An SVG object, or group of objects, can reference only one SVG filter.
TODO: Write details.
Filters and CSS
CSS can be used to apply filters. TODO: Add more information how this works exactly. Is it possible to apply the filter to normal HTML elements?
Example:
----- the.svg ----- <svg ...> [...] <filter id="fooFilter" > [...] </filter> </svg> ----- the.css ----- /* TODO: Not sure what #bar can refer to. */ #bar { filter: url(#fooFilter); }
Blur effects
TODO Write more
Drop shadows
TODO Write more
Gradients
TODO Write more
Symbols
SVG symbols use the <symbol>
element to define template objects which can be instantiated by a <use>
element.
TODO Write more
SVG / HTML integration
SVG as web API
SVG is similar to the Canvas web API in that it provides functions for drawing. Unlike Canvas, however, the elements in an SVG image are available via the DOM.
General SVG support is available in all modern browser, even Internet Explorer (since 9.0). However, a particular SVG feature may not be supported by a given browser version.
Displaying an SVG
An SVG can be embedded directly in the HTML document by using the svg
element:
<svg width="100" height="100"> <!-- Add SVG content here --> </svg>
If the SVG is in an external file you can reference it in an img
element:
<img src="foo.svg" ...>
Pretty obvious, but still worth mentioning: CSS can also be used:
body { background: url(foo.svg); /* This is necessary to scale the SVG image. If omitted the SVG's canvas size is used. */ background-size: ...; }
SVG and CSS
SVG elements can be styled with CSS just like any other HTML elements. However, the CSS properties used for SVG styling are usually different from those used for HTML styling. Example: You control the background of an SVG element with the fill
property, not with the background-color
propery.
You can use CSS selectors to select SVG elements in the same way that you would to select HTML elements. Notably, SVG elements can have id
and class
attributes just like normal HTML elements.
The Raphaël library
The Raphaël library is a JavaScript library that provides an API to create and manipulate SVG drawings.
URL = http://raphaeljs.com/
TODO: Provide at least a few details.
SVG sprites
SVG sprites are, to my understanding, SVG drawings that are defined once and then reused many times on a website, potentially across many different pages.
Sprite definition
An SVG sprite uses the <symbol>
element, roughly like this:
<symbol id="foo" class="hidden"> [...] </symbol>`
Notes:
- Each sprite needs to have a unique id.
- The
hidden
class will be explained in a moment.
When you have multiple sprites you can place each one in its own SVG definition, or you can lump them together in a single SVG definition using the <defs>
element. This roughly looks like this:
<!-- Single sprite in a file --> <svg> <symbol id="foo"> [...] </symbol> </svg> <!-- Multiple sprites in a file --> <svg> <defs> <symbol id="foo"> [...] </symbol> <symbol id="bar"> [...] </symbol> [...] </defs> </svg>
Including the sprite definition in HTML
In the HTML document you inline the definitions of all sprites you want to use at the beginning of the body. Here it is usually more convenient to have the sprites lumped together in a single <svg>
element:
[...] <body> <svg><defs>[...]</defs></svg> [...] </body> [...]
Since you don't want to actually display the sprites at the beginning of the body you add a CSS rule that hides the sprites based on the class hidden
.
Use sprite in HTML
When you want to use a sprite you reference it like this:
<svg class="icon foo"> <use xlink:href="#foo"></use> </svg>
To style the actually used sprites (not the definitions, these are all hidden) with CSS you use class-based rules:
- To style all sprites you use a generic class, in the example above the class
icon
. - To style an individual sprite you use the class that identifies that sprite, in the example above the class
foo
.