role
attribute, title/desc
tags)
PS: And do not forget to serve it as image/svg+xml MIME type
SVG canvas is infinite. ViewPort is defined by width
and height
and is
internally for percentage sizing use + it gives document's parent (HTML, SVG) its desired dimensions
<svg width="200" height="200"><!-- content --></svg>
ViewBox is defined by viewBox
and defines document's canvas visibility box. Use it a lot, I do!
Four values stand for definition of: left top width height
frame
<svg viewBox="-50 -50 200 200"><!-- content --></svg>
No one of them is mandatory, but they are very useful and they can co-exists easily, if you want or need to
<svg viewBox="-50 -50 200 200" width="100" height="100"><!-- … --></svg>
There are many ways how to integrate SVG in your web project (page). I recommend to stick to these ones:
svg
markup
object
tag
img
) tag
background
property
Mind necessity to keep XML syntax for all SVG markup
…
<h2>Some Title</h2>
<div class="wrapper">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<circle cx="40" cy="40" r="35" fill="orange"/>
<line x1="0" y1="0" x2="80" y2="50" stroke="green" stroke-width="4"/>
</svg>
<script>
if (!document.implementation.hasFeature(
"http://www.w3.org/TR/SVG11/feature#Shape", "1.1")) {
// optional fallback here
}
</script>
</div>
<p>Text of some paragraph</p>
…
Use if stretching is needed; fixed size works OK Live demo
<style>
.wrapper {
width: 50%;
height: 0;
padding-top: 50%; /* (svg-height / svg-width) * wrapper-width */
position: relative;
}
svg {
position: absolute;
top: 0;
left: 0;
}
</style>
<div class="wrapper">
<svg viewBox="0 0 50 50"></svg>
</div>
…
<h2>Some Title</h2>
<object type="image/svg+xml" data="turtle.svg" width="323" height="153">
</object>
<p>Some paragraph…</p>
…
Setting width does the trick. Live demo
<style>
.wrapper {
width: 50%;
}
.wrapper object {
width: 100%;
}
</style>
<div class="wrapper">
<object type="image/svg+xml" data="turtle.svg"></object>
</div>
Good old, familiar and easy way to go…
<img src="svg/dog.svg" alt="Dog" width="136" height="200"
onerror="this.onerror=null; this.src='fallback.png'"/>
<!-- with possible fallback using onerror attribute -->
Similar to object
tag - you need to set width. Live demo
<style>
img {
width: 100%;
}
</style>
<img width="136" height="200" src="svg/dog.svg" alt="Dog"/>
<style>
.holder {
width: 50%;
height: 50%;
background: url('img/turtle.png'); /* possible fallback trick */
background-image: url(svg/fish.svg), none;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
}
</style>
<div class="holder"/>
Embed your media queries inside SVG = put it where it belongs! (OOP Encapsulation, proven practice)
There are many SVG only CSS properties and all of them (and more) could be written
as direct presentation attributes, but probably the most notable are:
HTML | SVG |
---|---|
border | stroke |
color, background | fill |
border rgba (alpha for opacity) | stroke-opacity |
background-color rgba (for opacity) | fill-opacity |
z-index | element order (planned to SVG2) |
background-size: cover/contain | preserveAspectRatio = meet/slice |
Example of (not only) Twitter logo recreated in HTML/CSS and crushed to the minimum size (single color image only)
Legend | Lock | |
---|---|---|
HTML+CSS GZipped | 2.9 kB 1.4 kB | impossible to do ???? |
SVG GZipped | 1.2 kB 0.6 kB | 24.7 kB 6.4 kB |
PNG crunched | 4.1 kB 1.4 kB | 124.7 kB 31.9 kB |
Inline code case, notice symbol
element use.
<style> span { color: darkgreen; fill: currentColor; } </style>
<span>My cute jellyfish
<svg stroke="none" width="60" height="60">
<symbol id="jellyfish" viewBox="0 0 400 500">
<path d="M200,0.438c-90,0.772-172,72-192,160-6.89,28-8.74,57…
<g id="eye" transform="matrix(0.89472818,0,0,0.89472818,363.45969…
<path fill="yellow" d="m-139,494c-4.15,39.8,46.2,71.1,80.1…
<path fill="black" d="m-112,494c-4.57,20,18.9,32.5,35.7,26.2,12.5…
</g>
<use xlink:href="#eye" transform="translate(-150 0)"/>
</symbol>
<use xlink:href="#jellyfish"/>
</svg>
</span>
<span>Another cute jellyfish
<svg><use xlink:href="#jellyfish"/></svg>
</span>
My cute jellyfish
Another cute jellyfish
/* objectcase.css file */
span, use#jellyfishExt { color: magenta; fill: magenta; }
<style type="text/css">
@import url(css/objectcase.css);
</style>
<span>My shared jellyfish
<object type="image/svg+xml" data="jellyfish.svg" width="60" height="60"/>
</span>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<style type="text/css">
@import url(css/objectcase.css);
</style>
<!-- I prefer this CSS linking instead of <?xml-stylesheet… ?> way -->
<symbol id="jellyfish" viewBox="0 0 400 500">
…rest of the symbol definition…
</symbol>
<use xlink:href="#jellyfish" id="jellyfishExt"/>
</svg>
My shared jellyfish
<svg xmlns="http://www.w3.org/2000/svg">
<symbol viewBox="0 0 800 1313" id="r2d2">
<path d="M10.965784,-230.08768L54.388126,-413.23943L161.54509…">…
</symbol>
<symbol viewBox="0 0 200 222" id="darth">…</symbol>
</svg>
<h3>Smart R2D2</h3>
<svg>
<use xlink:href="svg/sprites.svg#r2d2"/>
</svg>
<h3>Darth Minnie</h3>
<svg>
<use xlink:href="svg/sprites.svg#darth"/>
</svg>
External link
Use of view with identifier is another very popular way.
<svg xmlns="http://www.w3.org/2000/svg">
<view viewBox="0 0 800 1313" id="r2d2"/>
<path d="M10.965784,-230.08768L54.388126,-413.23943L161.54509…">…
<view viewBox="900 900 200 222" id="darth"/>
</svg>
<h3>Smart R2D2</h3>
<img src="svg/sprites2.svg#r2d2"/>
<h3>Darth Minnie</h3>
<img src="svg/sprites2.svg#darth"/>
</svg>
External link
<input onchange="document.getElementById('txt').firstChild.data=this.value">
<svg width="310" height="120">
<path id="crc" stroke="none" fill="none" d="M50,0c0,27.6-22.4,50-50,50s-50-22.4-50-50,22.4-50,50-50,50,22.4,50,50z"/>
<g transform="translate(150 60) scale(2 0.8)">
<text font-size="26px" font-family="sans-serif" fill="green">
<textPath xlink:href="#crc" id="txt">Text Writ Around The Circle</textPath>
<animateTransform attributeName="transform" type="rotate" from="0" to="360" begin="click" repeatCount="1" dur="9s"/>
</text>
</g>
</svg>
Substitutes every other shape. Some available commands:
Notice two Control Points in curve command.
MSIE compatible solution, DOM manipulation involved.
<svg>
<path id="drawMe" d="M 246,188 l3,12h2l5-6c0,4,1,6,5,7,3-5,8-2…"/>
<script>
var lineElem = document.getElementById("drawMe");
var lineLength = elem.getTotalLength();
lineElem.style.strokeDasharray = lineLength; // +' '+ lineLength
lineElem.style.strokeDashoffset = lineLength;
// animation cycle follows
window.requestAnimationFrame(…shift strokeDashoffset here…);
</script>
<svg>
External link
Synchronized Multimedia Integration Language solution.
<svg>
<path stroke-dasharray="1439" stroke-dashoffset="1439" d="M 246,188…">
<animate attributeName="stroke-dashoffset" from="1439" to="0"
dur="4s" repeatCount="1" fill="freeze"/>
</path>
<svg>
External link
Don't forget to add necessary prefixes (like -webkit-…)
<svg>
<style>
.animate {
animation: draw 4s linear 1 forwards;
}
@keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
</style>
<path stroke-dasharray="1439" stroke-dashoffset="1439" d="M 246,188…"/>
<svg>
External link
Does not work with standalone SVG documents
and is somewhat commercial
<html>
<head/>
<body>
<script src="http://https://cdnjs.cloudflare… …TweenMax.min.js"></script>
<svg>
<path stroke-dasharray="1439" stroke-dashoffset="1439" d="M 246,188…"/>
</svg>
<script> TweenLite.to('path', 4, {strokeDashoffset:0}); </script>
<body>
<html>
External link
use
tag creates live reflection of any existing node.
It not only saves lines of code, but can do true miracles!!
<g id="complexElementID" class="…">
<circle …/> <rect …/> <text …/> <path id="somePathID" …/>
</g>
<use xlink:href="#complexElementID" transform="scale(2)" class="c1…"/>
<g class="whatever">
<use xlink:href="#complexElementID" transform="scale(5)" class="c2…"/>
<use xlink:href="#somePathID" transform="rotate(180)" class="c3…"/>
</g>
References are using xlink:href="#refID"
syntax.
You know it already, I know, but just to be sure ;-)
<mask id="myMask"/>
<g id="pumpkin">…several paths there…</g>
<script>
var carving;
pumpkin.onmousedown = function(evt) {
carving = document.createElement('path');
myMask.appendChild(carving);
}
pumpkin.onmousemove = function(evt) {
carving.setAttribute('d', carving.getAttribute('d') +
" " + evt.clientX + " " + evt.clientY);
}
External link
<path d="M5,5 L10,10 15,20 50,33…>
<animate attributeName="d" dur="10s" start="0s" repeatCount="indefinite"
values="M15,10 L5,5 17,30 7,20…;
M15,10 L2,2 70,11 8,42…" />
</path> (Batman Logo Evolution by Tavmjong Bah, M$ incompatible)
External link
MSIE/Edge doesn't support CSS Transformations to SVG content, so direct tag attributes have to be used.
MSIE also doesn't support CSS Transitions and Animations of otherwise supported
SVG related CSS properties - latest Edge does?,
which leaves us with reasonable utilization of only one property: opacity.
They are also the only browsers not supporting SMIL Animation, so putting SVG in motion is not so easy.
Scripting and tools could solve these issues, but it's a pity.
Following exceptional and wise people and sophisticated tools are great to learn from or definitely worth trying:
canvas
integration