SVG Support
SVG elements are supported for usage as background-image and as source for <img> nodes. Starting with version 1.15 inline SVGs are available as well.
The feature set that is supported is a large subset of the SVG Tiny 1.2 specification. SVG elements can be styled and animated, using standard CSS.
The most notable sections from the specification that are missing are:
- 10 Text
- Basic support for
<text>nodes. No other properties/nodes are supported. <tspan>nodes are ignored and the text in them is a part of the parent<text>node.
- Basic support for
- 12 Multimedia
- No multimedia support.
- 13 Interactivity
- No interactivity support.
- 14 Linking
- Support for
xlink:hrefattribute in<use>elements; The newer versionhrefis not supported.
- Support for
- 15 Scripting
- No support for
<handler>, or<listener>elements.
- No support for
- 16 Animation
- No SMIL animation support. CSS/web animations can be used instead.
- 17 Fonts
- No support for SVG fonts.
- 18 Metadata
- No support for metadata.
- 19 Extensibility
- No extensibility support (i.e. no
<foreignObject>elements).
- No extensibility support (i.e. no
SVG elements support
| Element type | Notes |
|---|---|
<circle> | |
<defs> | |
<desc> | |
<ellipse> | |
<g> | |
<line> | |
<linearGradient> | |
<path> | |
<polygon> | |
<polyline> | |
<radialGradient> | |
<rect> | |
<solidcolor> | * Deprecated in the web standard, but supported. |
<stop> | |
<style> | |
<svg> | |
<text> | |
<title> | |
<use> | |
<mask> | * See the notes below |
* Gradients applied on use elements follow the color stops, as if defined in the coordinate space of the used element. | |
| * Does not create Shadow DOM yet, uses alternative methods for displaying the linked node. |
Notes on the
<mask>element support:
- SVG elements cannot have
mask=url(#...)andclip-path=url(#...)simultaneously,<mask>elements do not support themask-typeproperty.<mask>elements support only alpha masking mode (mask-type=alpha)<mask>elements support only the attributesx,y,width,height,maskContentUnits, andmaskUnits<mask>elements must always have theirx,y,width, andheightspecified. The default usage should be<mask id="maskId" x="0%" y="0%" width="100%" height="100%">...</mask>
SVG attributes support
| Attributes | Notes |
|---|---|
| cx | |
| cy | |
| d | |
| fill | |
| fill-opacity | |
| fill-rule | Parsed, but not used at this point. Only “even-odd” fill rule is supported. |
| font-size | |
| gradientunits | |
| height | |
| offset | |
| pathLength | |
| points | |
| preserveaspectratio | |
| r | |
| rx | |
| ry | |
| solid-color | |
| solid-opacity | |
| stop-color | |
| stop-opacity | |
| stroke | |
| stroke-dasharray | |
| stroke-dashoffset | |
| stroke-linecap | |
| stroke-linejoin | |
| stroke-miterlimit | |
| stroke-opacity | |
| stroke-width | |
| style | |
| transform | |
| viewbox | |
| viewport-fill | |
| viewport-fill-opacity | |
| width | |
| x | |
| x1 | |
| x2 | |
| xlink:href | No support for the newer href. |
| xml:space | |
| y | |
| y1 | |
| y2 |
“Duplicated” SVG attributes / CSS properties
The following SVG attributes have the same name as standard CSS properties, but need to be parsed differently:
widthheightfont-sizetransform
The most notable difference is that you need to include measurement units (e.g. px, em, etc.) in CSS properties, while SVG attributes are unitless and it’s an error to specify the units. There are a few more differences in the transform property, as it can define a transform-origin in the SVG variant.
You don’t need to worry about defining CSS keyframe animations, except when using the “duplicated” properties. See the Animation section below for more details.
Using the inspector
- Node’s internal text cannot be changed through the inspector (attributes can be changed).
- Hovering elements within the
svgelement root won’t be highlighted.- This is due to the internal representation of SVG nodes (they do not exist in the Layout tree). Support for this is not planned at the moment.
Animation
Standard CSS animations are supported for animating inline SVGs.
There are two important shortcomings to note:
- Several CSS properties use the same name as SVG ones but are parsed differently. For example,
widthin standard CSS must include the units in which thewidthis specified, while SVG’swidthmust not. Due to internal specifics, when defining keyframe animation for such “duplicated” properties, you must include the units, even though you shouldn’t by standard. Note how theyproperty (which is available for SVGs only) doesn’t have units specified, whilewidthneedspx.
@keyframes moving-rect {
0% {
y: 0;
width: 85px;
}
100% {
y: 100;
width: 125px;
}
}
- Interpolating between 2 paths containing elliptical arc curves (
A/acommands) is not guaranteed to be interpolatable, even if they contain the same types of commands. This is because elliptical arcs are converted to up to 4 quadratic Bezier curves, leading to possible differences in the internal path representation. Paths that have the same types of internal commands are the only ones that can be interpolated. For example,M 10,30 A 20,20 0,0,1 50,30cannot be interpolated withM 10,30 A 40,20 0,0,1 50,30, because the first path’s arc is converted to 2 Bezier curves while the second is converted to a single one. If possible, avoid using elliptical arcs and use quadratic/cubic curves.
Performance optimizations
SVGs are internally cached when one of the following conditions is satisfied:
coh-use-aa-geometryis disabled (default: enabled)- The content size of the SVG does not exceed 1024x1024, and in the case of a non-inline SVG element,
background-repeatis not set tono-repeat
SVGs are re-tessellated and redrawn when one of the following conditions is satisfied:
- The content rectangle has changed (e.g., as a result of an animated element)
- The element has been invalidated because of a change in the style of an SVG node
Inline SVGs are never cached in GPU textures. They completely follow the redraw rules as the other DOM elements, in other words, they are redrawn only if a region of their content is dirty.
Example:
<!DOCTYPE html>
<html>
<style>
.cached1 {
width: 300px;
height: 300px;
background-image: url("cohtml.svg");
}
.cached2 {
width: 2048px;
height: 2048px;
background-image: url("cohtml.svg"); /* 800x600 content size */
}
.cahced3 {
width: 300px;
height: 300px;
}
.cahced4 {
width: 300px;
height: 300px;
background-repeat: no-repeat;
}
.non-cached1 {
width: 300px;
height: 300px;
background-image: url("cohtml.svg");
background-repeat: no-repeat;
}
.non-cached2 {
width: 300px;
height: 300px;
background-image: url("cohtml-large.svg"); /* 2048x2048 content size */
}
</style>
<body>
<!-- Cached, since the content rectangle of `cohtml.svg` does not exceed 1024x1024. The element size is irrelevant. -->
<div class="cached1"></div>
<div class="cached2"></div>
<!-- Inline images are also cached. The `background-repeat` property is ignored here. -->
<img class="cached3" src="cohtml.svg">
<img class="cached4" src="cohtml.svg">
<!-- Not cached, since the `background-repeat` property is set to `no-repeat`. -->
<div class="non-cached1"></div>
<!-- Not cached, since the content rectangle of `cohtml-large.svg` exceeds 1024x1024. The element size is irrelevant. -->
<div class="non-cached2"></div>
</body>
</html>