Scalable Vector Graphics (SVG) is a W3C standard for drawing vector images.
Here is a simple standalone SVG file:
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="25" fill="blue"/>
</svg>
SVG can also be embedded in HTML, in which case the xmlns
attribute is not required.
Other graphical elements are:
<line>
<ellipse>
<path>
<polygon>
and <polyline>
<text>
including child elements such as <tspan>
and <textPath>
CSS is used for styling although not all CSS properties apply to SVG and SVG itself defines some specific properties such as fill
and stroke
that are not used elsewhere.
Shapes can be filled with gradients or patterns and additional raster effects can be achieved using filters.
Clipping is available by using the above graphical elements as clip paths.
Regarding versions of the W3C SVG standard:
Detailed information on the SVG 'circle' element can be found in the W3C Recommendation for SVG.
Detailed information on the SVG path
element can be found in the W3C Recommendation for SVG.
Detailed information on the SVG 'rect' element can be found in the W3C Recommendation for SVG.
baseline-shift is not supported by the most current versions of Firefox and Microsoft browsers as of July 2016.
Detailed information on the SVG 'line' element can be found in the W3C Recommendation for SVG.
Graphic elements can be altered by adding a transform attribute.
<svg xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="30" height="30" transform="translate(10, 10)" />
</svg>
Instead of the top left origin being rendered at coordinates (0, 0), it will be shown down and right, from point (10, 10).
Whole groups of elements can be transformed together, and transformations can add to one another.
<svg xmlns="http://www.w3.org/2000/svg">
<g transform="rotate(45)">
<rect x="0" y="0" width="30" height="30" />
<circle cx="5" cy="5" r="5" transform="scale(3)" />
</g>
</svg>
First, every point of the circle will be scaled with the factor 3 in relation to the origin, bringing the center of the circle to the middle of the rectangle at (15, 15) and its radius to 15. Then, the rectangle and the circle will be rotated together by 45 degrees clockwise around the origin.
By default, the pattern will be tiled by setting the middle of the pattern unit at the top left corner of the shape.
SMIL animation via the <animate>
element is currently (July 2016) supported in major browsers with the exception of Microsoft browsers. There is a library (fakeSMIL) which can be used as a polyfill for Microsoft compatibility.
Chrome 45 deprecated SMIL in favor of CSS animations and forthcoming Web animations declarative animation syntax, which unfortunately, is only partially implemented in current browsers. But the Chrome developers recently suspended their intent (see this StackOverflow answer)
Most filter attributes are animateable via the <animate>
element, although you must use the "fakeSMIL" library on IE to achieve the same results. SMIL animation (the <animate>
element) will be deprecated in favor of the new Web Animations spec - which has very limited support as of mid 2016.
Child elements of the Filter element - filter primitives - have two optional attributes that specify the color space within which color interpolation calculations are performed: color-interpolation and color-interpolation-filters. The default for the former is sRGB, and the default for the latter is linearRGB. Manipulations that invert the color space (through feColorMatrix or feComponentTransfer) can result in non-intuitive results - for those used to the CSS sRGB color space. For example, a color inversion of a greyscale image in linearRGB will result in a pronounced shift toward whiter tones. This can be corrected by setting the value of the primitive to sRGB. These attributes can be set on the individual filter primitives or inherited from the filter element itself.
If no other input is specified, but one is required, the first filter primitive within a filter will take a rasterized (bitmapped) version of the referring element as its input. Subsequent filter primitives that expect an input will take the result of the immediately preceding filter primitive as input.
In complex filters, it can become difficult to keep track (and debug) inputs and outputs if they are left implicit; and it is good practice to explicitly declare inputs and outputs for each primitive.
SVG filter primitives can be colloquially divided into inputs, transformations, lighting effects and combinations.
Inputs:
feFlood: generates a color field
feTurbulence: generates a wide variety of noise effects
feImage: generates an image from an external image reference, data URI or object reference (object references are not supported in Firefox as of mid Dec '12)
Transformations:
feColorMatrix: transforms the input values of an RBGA pixel into output values
feComponentTransfer: adjusts the color curve of an individual color channel
feConvolveMatrix: replaces each pixel with a new pixel calculated from pixel values in an area relative to the current pixel)
feGaussianBlur: replaces the current pixel with a weighted average of pixels in an area around the pixel
feDisplacementMap: moves each pixel from its current position based on the R,G or B values from another input graphic.
feMorphology: replaces each pixel with a new pixel calculated from the maximum or minimum value of all pixels in a rectangular area around that pixel.
feOffset: moves the input from its current position
Lighting Effects:
feSpecularLighting: provides a "shiny" 2D or pseudo-3D lighting effect
feDiffuseLighting: provides a "matte" 2D or pseudo-3D lighting effect
feDistantLight: provides a distant light source for specular or diffuse lighting
feSpotLight: provides a conic section light source for specular or diffuse lighting
fePointLight: provides a point light source for specular or diffuse lighting
Combinations:
feMerge: creates a simple over composite from multiple inputs (including previous filter inputs)
feBlend: blends multiple inputs using mixing rules
feComposite: combines multiple inputs using set combination rules, taking into account alpha values.
feTile: tiles input to create a repeating pattern
Other Notes
Although SVG is a vector graphics technology, it is important to emphasize that SVG Filters perform pixel-level operations on all inputs (including SVG shapes) and produce rasterized (bitmapped) outputs at a specified level of resolution. Applying a 10x scale transform (for example) on an plain SVG curve that has been filtered at normal screen resolution will produce pixelated edges since the anti-aliasing of the original graphic has been converted to pixels by the filter and scaled up. (It is unclear whether this is spec compliant or just a limitation of current implementations)
Remember that SVG is XML when you write filters, so all tags must be closed and many properties and attributes are required to be specified explicitly or the filter will not execute.
A filter element is never rendered directly. It is only referenced using the filter property on the element to which the filter is applied. Note that the display property does not apply to the filter element and elements are not directly rendered even if the display property is set to a value other than "none". Conversely, filter elements are available for referencing even when thedisplay property on the filterelement or any of its ancestors is set to "none".
SVG filters can be referenced via a CSS Filter, although as of mid 2016, only a subset of primitives are supported via this mechanism, and this mechanism is not supported in Microsoft browsers.
SVG is case sensitive so remember to use a capital G in the middle.
<switch>
is a conditional processing attribute. It doesn't prevent elements from being referenced by other elements. In our case, <switch>
evaluates the systemLanguage value on its direct child elements that matches the user's language. Once is found, the child is rendered and the other children will be bypassed.
If the systemLanguage is not specified, the child will be displayed, allowing us specifying a fallback.
Scripting: rendered marker elements are not exposed in the DOM, so it is impossible to adjust properties or elements for specific rendered markers (although it's completely possible to script the defined marker element).
The overflow
property of the marker element is automatically set to hidden
. This is what clips any drawing that overflows the marker tile. This can be explicitly set to visible
in CSS. As of July 2016, Chrome does not support markers with overflow: visible
- but a workaround is to set a filter on the marker element - which seems to disable the overflow clipping.
Filters can be applied to elements within a marker. Although not explicitly permitted in the spec, filters also seem to work when specified on the marker element itself.
For more details on the marker element, please see the marker section in the SVG 1.1 spec.
Scripting SVG using the native DOM interfaces is currently (2016) in a state of slight change. The current SVG standard (1.1) is implemented well by most major web browsers. However, as the SVG 2.0 standard is under development, some browsers have begun to remove SVG 1.1 features that will be obsolete in 2.0. You can see a full list of proposed changes from SVG 1.1 to SVG 2.0 in Appendix L of SVG 2.0.
pathSegList
and other SVGPathSeg
usageIn SVG 1.1 <path>
elements are defined to have a pathSegList
property that gives access to a native representation of all path commands. Google Chrome v48 removed this property at the end of 2015, in preparation for a proposed replacement in SVG 2.0. Until SVG 2.0 support is added, you must use a polyfill to either get the 1.1 functionality back, or to implement the proposed 2.0 API.
getTransformToElement()
Chrome v48 also removed the SVGGraphicsElement.getTransformToElement()
method. A simple polyfill exists to implement the old method.
The <defs>
element is used as a container element for elements that are intended to be used solely by reference and not rendered directly. Elements that would normally be rendered (e.g. <rect>
, <circle>
) that are declared inside a <defs>
block are treated as if their style included display:none
.
Although it's not strictly necessary, the SVG spec. recommends putting all gradient, filter, pattern, mask, symbol, and marker definitions within a defs
block.
Details can be found in the W3C Recommendation for SVG as well as the new Candidate Recommendation for SVG2
Be aware that masks are a computational expensive operation. The calculation needs to be made for every pixel in the area of the mask. So keep the area of your mask as small as possible.