SVG

Tools:

Good to know:

  • Presentation attributes will overwrite inherited styles specified on a parent element

  • Links inside an SVG embedded as an <object> will open inside the boundaries of that <object>

  • Certain CSS characters like brackets will cause an XML error when used inside an SVG file

Accessibility

Only img, iframe and object can provide alternative content. img only provide text alternative (via the alt attribute)

Restrictions

SVG Embed Technique

External resources (styles, images)

Scripts

Interactivity (links, etc.)

CSS Animations

<svg> … </svg> (inlined)

Yes

Yes

Yes

Yes

Yes

<svg><use xlink:href="#id"></svg>

Yes

Yes

Yes

Yes

Yes

<svg><use xlink:href="image.svg#id"></svg>

Yes

Yes

Yes

Yes

<object type="image/svg+xml" data="image.svg"></object>

Yes

Yes

Yes

Yes, only inlined

No

<embed type="image/svg+xml" src="image.svg">

Yes

Yes

Yes

Yes, only inlined

No

<iframe src="image.svg"></iframe>

Yes

Yes

Yes

Yes, only inlined

No

<img src="img.svg" alt="">

No

No

No

Yes, only inlined?

No

element::before{content: url(img.svg);}

No

No

No

Yes, only inlined?

No

background-image: url(image.svg);

No

No

No

Yes, only inlined?

No

TODO test CSS Animations for "SVG as an Image" aka "SVG img src", SMIL animations (apprears to works at least with Safari)

When used as an image: iframe doesn't work (no data URI, no srcdoc) (don't know what I wanted to say there)

Basically when using a foreign object tag [in fact elements inside SVG as an Image] all its content must be origin free

Related bugs:

Fragment identifier and SVG stack

SVG symbols

Aka icon

  • The viewBox can be defined on the symbol, so you don't need to use it in the markup (easier and less error prone).

  • title and desc tags can be added within the <symbol> and they kinda "come along for the ride" when the symbol gets used, making accessibility easier to do right.

  • Symbols don't display as you define them, so no need for a <defs> block.

  • This is probably what <symbol> was invented for anyway

Path

Relative ↔︎ Absolute path

  • https://stackoverflow.com/questions/14179333/convert-svg-path-to-relative-commands/14179367#14179367

  • https://stackoverflow.com/questions/9677885/convert-svg-path-to-absolute-commands/9677915#9677915

  • https://github.com/DmitryBaranovskiy/raphael/blob/bef7f6b0e259030138193d42f2c74b754c292f3e/dev/raphael.core.js#L1646

Path Data API

SVGPathSeg, getPathData() and setPathData()

Primitives to path

See MorphSVGPlugin.convertToPath (require to be Club GreenSock membership)

Polyline to path: <polygon points="x1,y1 x2,y2 x3,y3"/> as <path d="Mx1,y1 x2,y2 x3,y3Z"/>

Transform

transform-origin in SVG not the same as HTML

Default values:

  • HTML: center, center

  • SVG: 0, 0

Transform on Firefox

transform-origin: 50% 50% is not supported in Firefox. Use translate(-halfWpx -halfHpx) ... translate(halfWpx halfHpx) or transform-origin: 200px 200px instead

Animation

SMIL animation in SVG are powerfull, but hard to control. Prefer use CSS animation/transition but it is not supported in IE -11+. A pure JS fallback is the solution.

  • http://jakearchibald.com/2013/animated-line-drawing-svg/

Animation as a huge impact on performance, especially on mobile. Rasterization is the problem. May be use canvas instead.

[SVG is] perfect for mobile… as long as it doesn’t move. There is no way to animate it smoothly on Android - rasterization won’t give you a chance.

  • https://github.com/kdzwinel/progress-bar-animation

  • https://github.com/kdzwinel/progress-bar-animation/issues/1

SMIL

Can't make multiple transform in the same time. Don't have an equivalent of transform-orign (it's the fault of SVG transform)

Control it with JS: Add begin="indefinite" to animate* element, and element.beginElement() or element.endElement() (and few others methods) to control it.

  • http://leunen.me/fakesmile/index.html

  • http://css-tricks.com/guide-svg-animations-smil/

  • http://tutorials.jenkov.com/svg/svg-animation.html

  • http://oak.is/thinking/animated-svgs

  • http://apike.ca/prog_svg_smil.html

  • https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL

CSS

  • https://stackoverflow.com/questions/24302615/css3-animation-is-not-working

JS

  • http://codepen.io/GreenSock/full/gpDrC/

  • http://www.w3.org/TR/SVG/animate.html#DOMAnimationExample

Now (05/11/2014) there no lib that can animate SVG transform attribute.

Interpolation:

  • http://www.w3.org/TR/css3-transforms/#interpolation-of-transform-functions

  • http://www.w3.org/TR/css3-transforms/#transform-function-lists

  • https://wiki.csswg.org/topics/transform-interpolation

  • transform-origin: 200px 300px; transform: rotate(45deg); is equivalent to: transform: translate(200px 300px) rotate(45deg) translate(-200px -300px). Apply it to scale, rotate, `` (exist in SVG only for rotate: transform="rotate(45 200 300)" ). http://www.w3.org/TR/css3-transforms/#transformation-matrix-computation

  • https://stackoverflow.com/questions/19154631/how-to-get-coordinates-of-an-svg-element https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/math/transform.js

  • http://greensock.com/forums/tags/forums/svg/

  • http://greensock.com/forums/topic/10666-svg-animations-in-ie/

  • http://greensock.com/forums/topic/10684-apply-transforms-with-transform-attr-instead-of-inline-style-on-svg/

  • http://greensock.com/forums/topic/10725-animating-svgs-fill-opacity/

  • http://greensock.com/forums/topic/7376-general-purpose-svg-plug-in/

  • https://github.com/akbr/GSAPSvgPlugin/blob/master/SvgPlugin.js

  • https://gist.github.com/raldred/7769278

  • http://www.benknowscode.com/2012/09/diving-into-matrices-with-css3_4970.html

  • http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

  • https://github.com/jcoglan/sylvester

Stroke animation

Works only on path elements. See code below to do that.

Stroke

Pattern

Unit

  • stroke-width

  • stroke-dasharray

  • ...

unit less (5) = viewBox percentage (5%) = viewport

DOM

Don't forget the SVG namespace:

Filter

Filter cropped, filter size

By default filter are <filter x="-10%" y="-10%" width="120%" height="120%">. If you want a bigger drop shadow, blur, etc. use <filter x="-30%" y="-30%" width="160%" height="160%">.

Filter

Use clip-path over alpha channel filter as mask

...when it's possible for better performances

Mask

Mask SVG qui disparaissent quand certain elements en contiennent ne sont plus affiché (visibility: hidden;, display: none;, removed)

<use> with external source

Not work properly on IE9-11+?

Optimizations

Don't remove xmlns="http://www.w3.org/2000/svg" if you not inline the SVG document in an HTML document.

  • element used once (<use xlink:href="#ID" />), replace replace it directly

  • remove useless id="ID" attribute (if not reference by xlink:ref="#ID", clip-path="url(#ID)", etc.)

  • same attributes (like fill, stroke, stroke-***, style, etc.) create a <g></g> wrapper with this attributes (will inherit attributes)

  • remove useless namespace (like: xmlns:xlink) if not used

  • remove whitespaces before and after value of d="", points=""

  • change color like #FFFFFF to it's named equivalent black...

  • simplify transform matrix matrix(1 0 0 1 $e $f) to translate($e $f), translate(...) rotate(...) scale(...)... to matrix(...)

  • remove subtle transforms ex: matrix(1 0 0 1 -1.220703e-04 -6.103516e-05)

  • remove on root <svg></svg> attributes like id, x, y, width, height, enabled-background, xml:space...

  • precompress (gzip) and use appropriate headers http://kaioa.com/node/45

  • reduce precision

  • <?xml version="1.0"?> can be omitted

  • xmlns:xlink="http://www.w3.org/1999/xlink" can be removed if not used

  • version="1.1" on svg node can be omitted

  • <linearGradient> inside <defs> not necessary

  • width and height when viewBox is defined on svg node are not required

  • stop-opacity on stop nodes are optional

  • stop-color="#ffffff" and stop-opacity="0" can be merged to stop-color="rgba(255,255,255,0)"

  • attribute quotes could be simple ones: attribute='value' instead of attribute="value"

  • Remove all uncessary whites spaces like new lines, tabs

Some tools already exist:

Performances

Use HTML+CSS hardware acceleration (split SVG and wrap in HTML elements differents parts), Canvas (2D or WebGL) or just an still image (PNG) instead of SVG:

Inlined or as separate document vs CSS background image (data URI or separate document) impact rendering time and memory usage:

CSS animations applied on definition elements

CSS animations applied on elements used by use can be realy bad and not recommended.

Case sensitivity

Since SVG is XML, node's name are case sensitive. Be carefull when create element in XML stream or via DOM (createElement()).

  • http://ejohn.org/blog/nodename-case-sensitivity/

Gradient

https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Gradients

Linear gradients can be defined as horizontal, vertical or angular gradients:

  • Horizontal gradients are created when y1 and y2 are equal and x1 and x2 differ

  • Vertical gradients are created when x1 and x2 are equal and y1 and y2 differ

  • Angular gradients are created when x1 and x2 differ and y1 and y2 differ

Gardient — Left to right

Gardient — Top to bottom

Coordinates, position and viewport

If viewBox is not defined nor width and height, SVG dimentions will not scale Use viewBox instead of width, height, x and y.

Responsive

Adaptive image

Scale bug on IE

  • http://www.seowarp.com/blog/2011/06/svg-scaling-problems-in-ie9-and-other-browsers/

  • http://benfrain.com/svg-backgrounds-dont-zoom-correctly-in-internet-explorer-10/

preserveAspectRatio

preserveAspectRatio="xMidYMid meet" (default, CSS equivalent background: center / contain) has no effect if viewBox is not set

Scaling:

keyword | CSS equivalent meet | background-size: contain slice | background-size: cover none | background-size: 100% 100% (stretching or squishing to fit the height and width)

For alignment (in conjuction with meet or slice), use 2 keywords concatenated (like xMinYMin):

keyword | CSS equivalent xMin | background-position-x: left xMid | background-position-x: center xMax | background-position-x: right YMin | background-position-y: top YMid | background-position-y: center YMax | background-position-y: bottom

Align text

Fallback

the logic is embedded inside the <svg> and use the <foreignObject> element to insert the non-SVG fallback. Using <switch>, SVG-capable browsers will render the first markup they understand (the SVG) and ignore the rest (the contents of the <foreignObject>). IE will do the opposite: it ignore the SVG it does not understand and renders the contents of the <foreignObject> because it is plain HTML.

HTML Entities

Data attributes

Graphics Canvas

Aka WebGL

Text to Path

See also:

  • HarfBuzz - "HarfBuzz is a text shaping library"

  • Pango - "Pango is a library for laying out and rendering of text, with an emphasis on internationalization"

SVG Font

Last updated

Was this helpful?