forked from jakegiltsoff/svgontheweb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
executable file
·632 lines (550 loc) · 46.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>A Practical Guide to SVGs on the web</title>
<link rel="stylesheet" href="/assets/css/style.min.css">
<link rel="shortcut icon" href="/assets/img/favicon.ico">
<script src="//use.typekit.net/erg0slu.js"></script>
<script>try{Typekit.load();}catch(e){}</script>
</head>
<body>
<header class="global-header">
<nav class="locale">
<ul>
<li class="active">En</li>
<li><a href="/zh">中国</a></li>
<li><a href="/ru">Ru</a></li>
</ul>
</nav>
<div class="section typeset">
<div class="column">
<h2 class="zeta">SVG on the web</h2>
<h1 class="mega">A Practical Guide</h1>
</div>
</div>
</header>
<nav class="global-nav">
<div class="section">
<ul class="column">
<li class="active">Guide</li>
<li><a href="/changelog">Changelog</a></li>
<li class="about"><a href="/about">About</a></li>
</ul>
</div>
</nav>
<section>
<div class="section typeset">
<div class="column column--sidebar">
<h6>Contents</h6>
<ul>
<li><a href="#svg"><span class="small-caps">SVG</span></a></li>
<li><a href="#preparation">Preparing & Optimising</a></li>
<li><a href="#implementation">Implementation options</a></li>
<li><a href="#css"><span class="small-caps">CSS</span> Manipulation</a></li>
<li><a href="#javascript"><span class="small-caps">JS</span> Manipulation</a></li>
<li><a href="#styling">Fixed width vs responsive</a></li>
<li><a href="#animating">Animating</a></li>
<li><a href="#spriting">Spriting</a></li>
<li><a href="#mediaqueries">Media queries</a></li>
<li><a href="#fallbacks">Fallbacks</a></li>
<li><a href="#resources">Resources</a></li>
</ul>
</div>
<div class="column column--main">
<h6>Introduction</h6>
<p>We live in the age of pixels. As designers & developers of the web, pixels can be both our friends and our enemies. We want everything to look nice and sharp for anyone who uses any of the websites we work on, but we need to keep file sizes down for performance. There is pretty much only one way to go with icons, logos and illustrations on the web — <span class="small-caps">SVG</span>. Scalable Vector Graphics can look crisp at all screen resolutions, can have super small file sizes, and can be easily edited and modified.</p>
<p>This guide aims to give a practical overview of how you can use <span class="small-caps">SVG</span>s on your websites — with some tips and tricks along the way to get the most out of them.</p>
</div>
</div>
</section>
<section class="group group--1" id="svg">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#svg"><span class="small-caps">SVG</span></a></h2>
</div>
<div class="column column--main">
<p>Scalable Vector Graphics are an <span class="small-caps">XML</span> based markup that can contain two-dimensional vectors. The vectors can be simple shapes, paths, or well just about anything you can do in Illustrator. It’s an image format that has more in common with a web page that it does with a <span class="small-caps">JPEG</span>. <span class="small-caps">SVG</span> is much more powerful than other image formats we can use on the web as we can manipulate them with code (either in our text editor or with <span class="small-caps">CSS / JS</span>).</p>
</div>
<div class="column column--sidebar">
<ul>
<li>Resolution independent</li>
<li>Supported by all modern browsers</li>
<li>Future-proof (<span class="small-caps">W3C</span> standard)</li>
<li>Easy to make and edit</li>
<li>Manipulatable with <span class="small-caps">CSS & JS</span></li>
<li>Highly compressible</li>
</ul>
</div>
</div>
</section>
<section class="group group--2" id="preparation">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#preparation">Preparing & Optimising</a></h2>
</div>
<div class="column column--main column--left">
<p>Preparing an <span class="small-caps">SVG</span> for use on the web is a simple process and no more complicated that exporting a <span class="small-caps">JPEG</span> or <span class="small-caps">PNG</span>. Work as you typically would in your preferred vector graphics editor (Illustrator, Sketch, Inkscape [free], etc [or even Photoshop if you use shape layers]) with the graphic at the size that you expect to use it. I’ll explain a few things I do using Illustrator as that is what I typically use, but the same principles apply to any software. You’ll probably want to convert any text to outlines as it most likely will not show in the correct font unless you plan on styling them with a web font you are using on the page (which you can do!). Don’t worry about expanding all your objects to solid shapes, particularly if you have strokes as you may want to manipulate these on the page and expanding them typically doesn’t make the file size any smaller. Any names you put on layers / groups will be added in to the <span class="small-caps">SVG</span> as an ID on that element. This can be handy for styling, but will add a little to the overall file size.</p>
<p>To export, check that the design is sitting in an area of whole pixels (i.e. not <span class="lining-numerals">23.3px × 86.8px</span>) otherwise it may not actually be crisp and then crop the artboard around it. You can do this in Illustrator with <code>Object > Artboards > Fit to Artwork Bounds</code>. Next hit <code>save as</code> and choose <span class="small-caps">SVG</span> and use the default settings. You can do some optimising here, but it isn’t really worth it as we will be post-processing them to optimise and any time spend playing with these settings is wasted.</p>
<h3 class="delta">Tips for smaller file sizes</h3>
<p class="caption sidenote">(See the <a href="#resources">resources</a> for external article links)</p>
<p>There are a number of good articles on <span class="small-caps">SVG</span> optimisation on the web which offer a wealth of knowledge on this subject, but I would like to share a few tips and tricks that I have found to be most effective and useful for me. They don’t take much extra work and can be easily added in to your workflow.</p>
<p>To keep your <span class="small-caps">SVG</span>s as small as possible you effectively want to remove anything unnecessary. The most well known and best (at least I think so) tool to post process <span class="small-caps">SVG</span>s is <a href="https://github.com/svg/svgo" class="small-caps">SVGO</a>. This strips out all the code that isn’t needed — note: remember to be careful when using this if you plan to manipulate with <span class="small-caps">CSS / JS</span> as it can sometimes over-optimise your files making them harder to do what you planned to with them later on. A very handy thing with <span class="small-caps">SVGO</span> is it can be added to your build process so it is automatic (or you can use a <span class="small-caps"><a href="https://github.com/svg/svgo-gui">GUI</a></span> to do it yourself if you prefer).</p>
<p>Taking things a step further in ‘removing anything unnecessary’ we can do some more in the graphics editor. First you want to make sure you are using as few paths / shapes as possible to achieve what you want and also that there are as few points on these paths as possible. You want to combine and simplify anything that you can. Then you want to remove as many points from your paths as possible. <a href="http://www.astutegraphics.com/software/vectorscribe/">VectorScribe</a> is an Illustrator plugin that has as part of it a <code>Smart Remove Brush Tool</code> — this allows you to remove points whilst still keeping the overall shape the same.</p>
<p class="caption sidenote">Pre optimisation</p>
<p><img src="/assets/img/2point.png" alt="Pre optimisation"></p>
<p class="caption sidenote">Smart Remove Brush Tool removed point</p>
<p><img src="/assets/img/1point.png" alt="Post optimisation"></p>
<p>Next you are going to want to zoom in. In Illustrator you will want to enable the Pixel Preview with <code>View > Pixel Preview</code> and take a look at where your path points sit. For the smallest file sizes you want these to sit on the pixel grid (i.e. at whole pixel values). This takes a little bit of time to snap them all in place but is worth the extra bit of effort as this also ensures the sharpest rendering (notice how before you can end up with some half-pixel areas).</p>
<p class="caption sidenote">Points off pixels</p>
<p><img src="/assets/img/nosnap.png" alt="Points off pixels"></p>
<p class="caption sidenote">Pixel snapped</p>
<p><img src="/assets/img/snap.png" alt="Pixel snapped"></p>
<p>If you have two (or more) shapes that align you will want to remove any unneeded overlap. A thing to look out for is they can appear to have a thin white line between them even if the paths align, so sometimes you need to overlap them a little to prevent this. Note: in <span class="small-caps">SVG</span> the <code>z-index</code> is defined by the order they appear in the file with the bottom being the highest, so put the top shape at the bottom of the file in the code.</p>
<p><img src="/assets/img/whiteline.png" alt="Post optimisation"></p>
<p>Last but not least, one thing that is often forgotten about, remember to enable gzip compression for <span class="small-caps">SVG</span>s on your websites in the <code>.htaccess</code> file.</p>
<pre><code>AddType image/svg+xml svg svgz
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE "image/svg+xml" \
"text/css" \
"text/html" \
"text/javascript"
... etc
</IfModule>
</IfModule></code></pre>
<hr>
<p>As an example of how effective these techniques can be, I took the original <a href="http://breakingborde.rs/">Breaking Borders</a> logo and optimised it thusly: re-sized it to as large as it needed to be, tidied the paths, removed as many points as possible, moved the points to whole pixel values, removed as much of the overlapping area as possible, and put it through <span class="small-caps">SVGO</span>.</p>
<h4 class="zeta">Original: 1,413b</h4>
<img src="/assets/img/bblogo.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-example">
<h4 class="zeta">Optimised: 409b</h4>
<img src="/assets/img/bblogo-optim.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-example">
<p><b>All in all that makes it <span class="lining-numerals">~71%</span> smaller (and <span class="lining-numerals">~83%</span> smaller if gzipped)</b></p>
<p><span class="small-caps highlight">ADDITION:</span> <a href="https://twitter.com/robsterlini">Rob Sterlini</a> pointed out that as the ‘b’ is repeated you could probably use a <code><use></code> element to repeat it which might make it smaller — and he was totally right.</p>
<h4 class="zeta">Optimised further with <use>: 311b</h4>
<img src="/assets/img/bblogo-optim2.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-example">
<p><b><span class="lining-numerals">~78%</span> smaller</b></p>
<p>If you do this to all the <span class="small-caps">SVG</span>s on a site it can really add up.</p>
</div>
</div>
</section>
<section class="group group--3" id="implementation">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#implementation">Implementation options</a></h2>
</div>
<div class="column column--main">
<p>When it comes to using <span class="small-caps">SVG</span>s on the web there are a number of different ways you can go. Some of them have benefits which can be useful depending on what you would like to achieve and some of them are best to be avoided. If you want to just keep things basic to get the resolution independence and file size benefits you can reference the <span class="small-caps">SVG</span> in an <code>img</code> or as a <code>background-image</code> in <span class="small-caps">CSS</span> just as you would any other image format.</p>
</div>
</div>
<div class="section typeset">
<div class="column column--duo">
<h4 class="epsilon">Img</h4>
<p>Just as you would with any other image. You can also use <span class="small-caps">SVG</span>s in a <code><picture></code> element. Note that this method limits manipulation functionality.</p>
<pre><code><img src="bblogo.svg" alt="Breaking Borders Logo" height="65" width="68"></code></pre>
<img src="/assets/img/bblogo-optim.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-example">
</div>
<div class="column column--duo">
<h4 class="epsilon">Background-image</h4>
<p>It’s best not to <span class="lining-numerals">base64</span> encode them as it this will block the loading of the rest of the styles while it downloads. Note that this method limits manipulation functionality.</p>
<pre><code>.logo {
background-image: url(bblogo.svg);
}</code></pre>
<div class="bb-bg"></div>
</div>
</div>
<div class="section typeset">
<div class="column column--duo">
<h4 class="epsilon">Iframe</h4>
<p>You can load <span class="small-caps">SVG</span>s in an <code><iframe></code>. It does let you do most things, but I’m not sure it is the best method to use moving forward ¯\_(ツ)_/¯.</p>
<pre><code><iframe src="bblogo.svg">Your browser does not support iframes</iframe></code></pre>
<iframe src="/assets/img/bblogo-optim.svg" class="bb-logo-example">Your browser does not support iframes</iframe>
</div>
<div class="column column--duo">
<h4 class="epsilon">Embed</h4>
<p><code><embed></code> is meant to be used to integrate ‘an external application’ or ‘interactive content’. You can use it for <span class="small-caps">SVG</span>s but yea probably just don’t.</p>
<pre><code><embed type="image/svg+xml" src="bblogo.svg" /></code></pre>
<embed type="image/svg+xml" src="/assets/img/bblogo-optim.svg" class="bb-logo-example" />
</div>
</div>
<div class="section typeset">
<div class="column column--duo">
<h4 class="epsilon">Object</h4>
<p><code><object></code> is pretty much the best option to use if you want to be able to manipulate an <span class="small-caps">SVG</span> without having to put it inline in your <span class="small-caps">HTML</span>.</p>
<pre><code><object type="image/svg+xml" data="bblogo.svg">Your browser does not support SVGs</object></code></pre>
<object type="image/svg+xml" data="/assets/img/bblogo-optim.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--duo">
<h4 class="epsilon">Inline</h4>
<p>Putting your <span class="small-caps">SVG</span> code inline will save an <span class="small-caps">HTTP</span> request but it will mean the image isn’t cached by the browser. It is the easiest way to manipulate, however maintaining inline <span class="small-caps">SVG</span> code can be a pain.</p>
<pre><code><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
<path fill="#1A374D" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
<path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
</svg></code></pre>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65" class="bb-logo-example"><path fill="#1A374D" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/><path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/></svg>
</div>
</div>
<div class="section typeset">
<div class="column">
<hr>
</div>
<div class="column column--main">
<h3 class="zeta">To Conclude</h3>
<p>If you want to get the most out of your <span class="small-caps">SVG</span>s use <code><object></code>. Alternatively you can use them inline to save the <span class="small-caps">HTTP</span> request, but note that it will not be cached. If you just want to use <span class="small-caps">SVG</span>s as you would any other image use <code><img></code> or a <code>background-image</code>. You have the ability to use <code><iframe></code> and <code><embed></code> but I don’t think they are the best options going forward (and for the purposes of this site, I will not focus on them any longer).</p>
</div>
<div class="column">
<table id="implementation-support">
<thead>
<tr>
<th></th>
<th>Object</th>
<th>Inline</th>
<th>Img</th>
<th>Background-image</th>
</tr>
</thead>
<tbody>
<tr>
<th class="feature"><span class="small-caps">CSS</span> Manipulation</th>
<td>Yes</td>
<td>Yes</td>
<td>Some inline</td>
<td>Some inline</td>
</tr>
<tr>
<th class="feature"><span class="small-caps">JS</span> Manipulation</th>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<th class="feature"><span class="small-caps">SVG</span> Animation</th>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<th class="feature">Interactive <span class="small-caps">SVG</span> Animation</th>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
</tbody>
</table>
</div>
<div class="column column--main">
<p>Note: ‘Some inline’ means somethings work, but only if the <span class="small-caps">CSS</span> <code><style></code> is embedded within the <span class="small-caps">SVG</span> code. More info on this in the next section.</p>
</div>
</div>
</section>
<section class="group group--4" id="css">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#css"><span class="small-caps">CSS</span> Manipulation</a></h2>
</div>
<div class="column column--main">
<p>One of the great things with using an <span class="small-caps">SVG</span> is we can change how elements within it are styled using good old <span class="small-caps">CSS</span>. Say we have an orange icon and we want it to be blue on some pages, we can do that without having to make a new blue icon. Ideal.</p>
<p>There are two ways we can change styles — inline in the <span class="small-caps">SVG</span> and externally (i.e. within our stylesheet). To put styles inline, wrap them in a <code><style></code> tag and also within <code><![CDATA[ ... ]]></code>. It’s best to do this as sometimes <span class="small-caps">XML</span> parsers can conflict with certain characters (i.e. <code>></code>). Even if you don’t have any funky characters in there now, it is best practice to use <code>CDATA</code> as some could be added at a later time and break all the things.</p>
<p>Inline styles will mostly work in all implementations. <code><img></code> and <code>background-image</code> don’t support <span class="small-caps">CSS3</span> animations even if they are inline (see section on <a href="#animating">animations</a> for more). <code>background-image</code> doesn’t support inline media queries (see section on <a href="#mediaqueries">media queries</a> for more).</p>
</div>
</div>
<div class="section typeset">
<div class="column column--sidebar">
<h4 class="epsilon">Inline styles</h4>
<object type="image/svg+xml" data="/assets/img/bblogo-css.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--main">
<pre><code><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
<style type="text/css">
<![CDATA[
.firstb { fill: yellow; }
.secondb { fill: red; }
]]>
</style>
<path class="secondb" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
<path class="firstb" d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
</svg></code></pre>
</div>
</div>
<div class="section typeset">
<div class="column column--main">
<p>If you want to use external styles, which are mostly much easier to work with and maintain, you can’t use <code><img></code> or <code>background-image</code>. If you are using <code><object></code> you need to reference your stylesheet internally from the <span class="small-caps">SVG</span> file (see code following). Remember: if you do this the <span class="small-caps">SVG</span> will also not be able to know what its parent class is (i.e. the <code><object></code>) so don’t try to use that in its styling. Inline <span class="small-caps">SVG</span>s don’t need this added and therefore can be slightly easier to work with in this sense.</p>
</div>
</div>
<div class="section typeset">
<div class="column column--sidebar">
<h4 class="epsilon">External styles</h4>
<object type="image/svg+xml" data="/assets/img/bblogo-nocss.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--main">
<pre><code>// Add to very start of SVG file before <svg>
<?xml-stylesheet type="text/css" href="style.css"?></code></pre>
<pre><code>// In style.css
.firstb { fill: yellow; }
.secondb { fill: red; }</code></pre>
</div>
</div>
</section>
<section class="group group--5" id="javascript">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#javascript"><span class="small-caps">JS</span> Manipulation</a></h2>
</div>
<div class="column column--main">
<p>My JavaScript knowledge is pretty minimal, so I’m just going to point out some basic tips on how you can use <span class="small-caps">JS</span> to change things in an <span class="small-caps">SVG</span>. If you want to embed your scripts within the <span class="small-caps">SVG</span> file, remember to wrap them in <code><![CDATA[ ... ]]></code> again to prevent parsing errors. Scripts will not run if you use <code><img></code> or <code>background-image</code> as a security measure (i.e. to prevent potentially malicious code running on your page).</p>
<p>When working with external <span class="small-caps">JS</span> (i.e. not embeded within the <span class="small-caps">SVG</span> file), if you have your <span class="small-caps">SVG</span> inline you can target it as you would any other <span class="small-caps">DOM</span> element. If you use an <code><object></code> you can target it with <code>contentDocument</code>. You can get much more creative than the following, but here is an example:</p>
</div>
</div>
<div class="section typeset">
<div class="column column--sidebar">
<h4 class="epsilon">External scripts</h4>
<object type="image/svg+xml" data="/assets/img/bblogo-js.svg" id="logoObject" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--main">
<pre><code>window.onload=function() {
var object = document.getElementById("logoObject");
var svgDocument = object.contentDocument;
var svgb1 = svgDocument.getElementsByClassName("firstb");
var svgb2 = svgDocument.getElementsByClassName("secondb");
svgb1[0].setAttribute("fill", "yellow");
svgb2[0].setAttribute("fill", "red");
};</code></pre>
</div>
</div>
</section>
<section class="group group--6" id="styling">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#styling">Fixed width vs responsive</a></h2>
</div>
<div class="column column--main">
<p>When using images on the web in responsive designs there are two options you can use to style them, you can keep them at a fixed-size and adjust at breakpoints if needed, or allow them to resize with the page depending on their parent container.</p>
<p>If they are a fixed size the only thing you need to be careful of is if you are using the <span class="small-caps">SVG</span> as a <code>background-image</code> you need to make sure to include a <code>background-size</code> because browsers can get a bit confused and either crop it or shrink it, particularly if you are showing it at a different size to the actual size of the image.</p>
<p>When implementing an <span class="small-caps">SVG</span> that can resize there are a couple of things to remember (again mostly with the <code>background-image</code> implementation) as outlined here:</p>
</div>
</div>
<div class="section typeset">
<div class="column column--quad">
<h4 class="epsilon">Object</h4>
<p>Works as expected with <code>width: 100%;</code></p>
<object type="image/svg+xml" data="/assets/img/bblogo-optim.svg" class="bb-logo-resp">Your browser does not support SVGs</object>
</div>
<div class="column column--quad">
<h4 class="epsilon">Inline</h4>
<p>Previously needed a <code>max-height</code> value to work, of recent works as expected. Note Safari doesn’t redraw these as quickly (if they are complex) on window resize.</p>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65" class="bb-logo-resp"><path fill="#1A374D" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/><path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/></svg>
</div>
<div class="column column--quad">
<h4 class="epsilon">Img</h4>
<p>Works as expected with <code>width: 100%;</code></p>
<img src="/assets/img/bblogo-optim.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-resp">
</div>
<div class="column column--quad">
<h4 class="epsilon">Background-image</h4>
<p>Needs <code>padding-bottom: #%;</code> to keep the proportions of the image else it will not show.</p>
<div class="bb-bg-resp"></div>
</div>
</div>
</section>
<section class="group group--7" id="animating">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#animating">Animating</a></h2>
</div>
<div class="column column--main">
<p>When it comes to animating <span class="small-caps">SVG</span>s there are a few different options that we can use — <span class="small-caps">SVG</span> animation (based on the <span class="small-caps">SMIL</span> spec), <span class="small-caps">CSS3</span> animations, or <span class="small-caps">JS</span> animations. <span class="small-caps">SVG</span> animation and <span class="small-caps">CSS3</span> animations let you do most things you will want to do — with <span class="small-caps">SVG</span> animation being slightly more powerful in that it has control over a few extra things. JavaScript allows you to do some pretty complex animations relatively easily, especially with libraries such as <a href="http://snapsvg.io/">Snap.svg</a>. This is a little beyond my knowledge of JavaScript so I’ll let you check out their demos to see for yourself if that is the right option.</p>
<p><span class="small-caps">SVG</span> animation is super powerful but I’m not going to go in to too much depth on it as to be honest I’ve not really ever used it. I can imagine it being useful for illustrations that you would like to have some nice animations happening with, but from a practical point of view not every project has the time or budget to spend on this. If you do, it is actually pretty simple to start playing around with and there are some <a href="#resources">great tutorials</a> online. Basically you can add a child element of <code><animate></code> to any paths and shapes in your <span class="small-caps">SVG</span>s which will control the animations. The best thing about it is, it works in all implementation methods. Internet Explorer does not support <span class="small-caps">SVG</span> animation, however you can use a polyfill such as <a href="https://leunen.me/fakesmile/">FakeSmile</a> if you need it to work in <span class="small-caps">IE</span> too.</p>
<p>Here’s a little demo to show you. Note: I’ve lightened the blue to make it easier to see the animation.</p>
<pre><code><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
<path fill="#4e86b1" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z">
<animate dur="2s" values="#000000; #4e86b1; #000000" keyTimes="0; 0.5; 1" attributeName="fill" repeatCount="indefinite"/>
</path>
<path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z">
<animate dur="2s" values="#4e86b1; #000000; #4e86b1" keyTimes="0; 0.5; 1" attributeName="fill" repeatCount="indefinite"/>
</path>
</svg></code></pre>
</div>
</div>
<div class="section typeset">
<div class="column">
<h4><span class="small-caps">SVG</span> animation</h4>
</div>
<div class="column column--quad">
<h4 class="epsilon">Object</h4>
<object type="image/svg+xml" data="/assets/img/bblogo-anim2.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--quad">
<h4 class="epsilon">Inline</h4>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65" class="bb-logo-example"><path fill="#4e86b1" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"><animate dur="2s" values="#000000; #4e86b1; #000000" keyTimes="0; 0.5; 1" attributeName="fill" repeatCount="indefinite"/></path><path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"><animate dur="2s" values="#4e86b1; #000000; #4e86b1" keyTimes="0; 0.5; 1" attributeName="fill" repeatCount="indefinite"/></path></svg>
</div>
<div class="column column--quad">
<h4 class="epsilon">Img</h4>
<img src="/assets/img/bblogo-anim2.svg" alt="Breaking Borders Logo" height="65" width="68" class="bb-logo-example">
</div>
<div class="column column--quad">
<h4 class="epsilon">Background-image</h4>
<div class="bb-bg-anim"></div>
</div>
</div>
<div class="section typeset">
<div class="column column--main">
<p>Often when we want to animate icons or illustrations on the web it will be for an interaction, i.e. on hover etc. This falls under <span class="small-caps">CSS</span> Manipulation and Interactive <span class="small-caps">SVG</span> Animation in the <a href="#implementation-support">table of support</a> above and thus doesn’t work for either <span class="small-caps">SVG</span> animation or <span class="small-caps">CSS3</span> animations if you use <code><img></code> or <code>background-image</code>. To get interactive animations in <span class="small-caps">SVG</span> animation we can add <code>begin="mouseover"</code> & <code>begin="mouseout"</code> and with <span class="small-caps">CSS3</span> animations just as you would anywhere else — add classes to the <span class="small-caps">SVG</span> elements and style them on <code>hover</code>. One thing to note is, if you want to style the animations from your external stylesheet it will work as expected if you have the <span class="small-caps">SVG</span> inline, but if you use <code><object></code> you will need to reference the external stylesheet from within the <span class="small-caps">SVG</span> too.</p>
</div>
</div>
<div class="section typeset">
<div class="column column--sidebar">
<h4 class="epsilon">Interactive <span class="small-caps">SVG</span> animation</h4>
<p>Only works with <code><object></code> or inline.</p>
<object type="image/svg+xml" data="/assets/img/bblogo-anim.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--main">
<pre><code><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
<path fill="#4e86b1" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z">
<animate fill="freeze" dur="0.1s" to="#000000" from="#4e86b1" attributeName="fill" begin="mouseover"/>
<animate fill="freeze" dur="0.1s" to="#4e86b1" from="#000000" attributeName="fill" begin="mouseout"/>
</path>
<path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z">
<animate fill="freeze" dur="0.1s" to="#4e86b1" from="#000000" attributeName="fill" begin="mouseover"/>
<animate fill="freeze" dur="0.1s" to="#000000" from="#4e86b1" attributeName="fill" begin="mouseout"/>
</path>
</svg></code></pre>
</div>
</div>
<div class="section typeset">
<div class="column column--sidebar">
<h4 class="epsilon"><span class="small-caps">CSS3</span> animation</h4>
<p>Only works with <code><object></code> or inline. Also works with external <span class="small-caps">CSS</span> as explained <a href="#css">previously</a>.</p>
<object type="image/svg+xml" data="/assets/img/bblogo-animcss.svg" class="bb-logo-example">Your browser does not support SVGs</object>
</div>
<div class="column column--main">
<pre><code><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
<style type="text/css">
<![CDATA[
.firstb { fill: #000; transition: fill 0.1s; }
.firstb:hover { fill: #4e86b1; }
.secondb { fill: #4e86b1; transition: fill 0.1s; }
.secondb:hover { fill: #000; }
]]>
</style>
<path class="secondb" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
<path class="firstb" d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
</svg></code></pre>
</div>
</div>
</section>
<section class="group group--8" id="spriting">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#spriting">Spriting</a></h2>
</div>
<div class="column column--main">
<p>You can create and use <span class="small-caps">SVG</span> sprites just as we typically do with <span class="small-caps">PNG</span>s and <code>background-image</code> to get the resolution benefits or you can take it a step further using the extra power we have with <span class="small-caps">SVG</span>. I’m not going to go in to too much depth here again as it does get pretty complex and I’ve never found a need to implement them personally. The benefit is getting all the power of <span class="small-caps">SVG</span> with fewer <span class="small-caps">HTTP</span> requests.</p>
<p>There are two approaches you can take — in the first you define all the icons within <code><symbol></code> elements in the <span class="small-caps">SVG</span> but hide them. Then reference each later when needed with a <code><use></code> element referencing the <code><symbol></code> with <code>xlink:href="#id"</code>. The second uses the <span class="small-caps">SVG</span> <code>viewbox</code> attribute to crop the artboard (area of the <span class="small-caps">SVG</span> that shows) around a certain area. These are both quite advanced <span class="small-caps">SVG</span> uses so only worry about them if you want to use them.</p>
<p>If you do want to learn how to implement these techniques please take a look at the links in the <a href="#resources">resources</a>, especially <a href="https://twitter.com/SaraSoueidan">Sara Soueidan’s</a> 24ways <a href="http://24ways.org/2014/an-overview-of-svg-sprite-creation-techniques/">article</a>.</p>
<p>If you want to use an <span class="small-caps">SVG</span> sprite just as you would a <span class="small-caps">PNG</span> sprite with <span class="small-caps">CSS</span> it is worth noting that you will need to add the <code>width</code> and <code>height</code> attributes back in alongside the <code>viewBox</code> attribute in the <span class="small-caps">SVG</span> code. During the optimising process these are typically removed because they aren’t usually needed. In this case however <span class="small-caps">IE9 & 10</span> need them to be able to correctly crop to part of the image sprite. This is because those browsers take the width and height sizes specified in the <span class="small-caps">CSS</span> for the image size, but these are actually the sizes of the part of the image wanted (not the whole image). Confusing I know, but it is something I ran into recently.</p>
</div>
</div>
</section>
<section class="group group--9" id="mediaqueries">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#mediaqueries">Media queries</a></h2>
</div>
<div class="column column--main">
<p>A really cool thing about <span class="small-caps">SVG</span>s is, if you use media queries in the styles you embed within the file, instead of them working from the viewport size they will work from the <span class="small-caps">SVG</span>s viewport size. Basically that means they have their own working implementation of element queries out of the box. Nice. This allows us to control how the <span class="small-caps">SVG</span> will look at whatever size it is shown.</p>
<p>Imagine you are a big brand and you want people to use your logo correctly no matter what size it’s shown. Well you pretty much can! Just embed some media queries and you can change its formatting based on what size it is displayed at. This works with all implementations apart from <code>background-image</code> and in all browsers (note: <span class="small-caps">IE9–11</span> seem to ignore some breakpoints). Have a play with the slider below to see an example of how that could work:</p>
<form oninput="getElementById('responsive-logo').setAttribute('width',value=slider.value);" style="min-height: 200px;">
<input id="slider" type="range" min="30" max="335" value="335"></input>
<br>
<img id="responsive-logo" class="slider-image" src="/assets/img/bblogo-resp.svg" width="335" alt="svg">
</form>
</div>
</div>
</section>
<section class="group group--10" id="fallbacks">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#fallbacks">Fallbacks</a></h2>
</div>
<div class="column column--main">
<p>A word on fallbacks. <span class="small-caps">SVG</span>s are supported in all modern browsers. If you still have to support <span class="small-caps">IE8</span> then you will need to implement fallbacks, most likely in the form of <span class="small-caps">PNG</span>s. I’m not going to go in to this much because you probably shouldn’t be supporting <span class="small-caps">IE8</span> anymore ¯\_(ツ)_/¯. Anyway, if you do want fallbacks, basically things get pretty complicated pretty quickly as most things do with <span class="small-caps">SVG</span>. I would recommend to read this comprehensive article by <a href="https://twitter.com/AmeliasBrain">Amelia Bellamy-Royds</a> on <a href="https://css-tricks.com/a-complete-guide-to-svg-fallbacks/">CSS-Tricks</a>.</p>
</div>
</div>
</section>
<section class="group group--11" id="resources">
<div class="section typeset">
<div class="column">
<h2><a class="title" href="#resources">Resources</a></h2>
</div>
<div class="column column--duo">
<h3 class="zeta">General</h3>
<ul>
<li><a href="http://www.webdesignerdepot.com/2015/01/the-ultimate-guide-to-svg/">Ultimate guide to <span class="small-caps">SVG</span></a></li>
<li><a href="http://www.sitepoint.com/add-svg-to-web-page/">How to Add <span class="small-caps">SVG</span>s to Your Web Page</a></li>
<li><a href="http://www.w3.org/Graphics/SVG/About.html"><span class="small-caps">W3C</span> About <span class="small-caps">SVG</span></a></li>
<li><a href="http://www.smashingmagazine.com/2014/03/05/rethinking-responsive-svg/">Rethinking Responsive <span class="small-caps">SVG</span></a></li>
<li><a href="http://tympanus.net/Tutorials/ResponsiveSVGs/index6.html">Making <span class="small-caps">SVG</span>s Responsive</a></li>
<li><a href="https://css-tricks.com/using-svg/">Using <span class="small-caps">SVG</span></a></li>
<li><a href="http://blogs.adobe.com/webplatform/2013/01/08/svg-styling/"><span class="small-caps">SVG</span> Styling</a></li>
</ul>
</div>
<div class="column column--duo">
<h3 class="zeta">Optimising</h3>
<ul>
<li><a href="http://calendar.perfplanet.com/2014/tips-for-optimising-svg-delivery-for-the-web/">Tips For Optimising <span class="small-caps">SVG</span> Delivery For The Web</a></li>
<li><a href="http://jaydenseric.com/blog/how-to-optimize-svg">How To Optimize <span class="small-caps">SVG</span></a></li>
<li><a href="https://css-tricks.com/understanding-and-manually-improving-svg-optimization/">Understanding and Manually Improving <span class="small-caps">SVG</span> Optimization</a></li>
<li><a href="https://www.youtube.com/watch?v=1AdX8odLC8M"><span class="small-caps">SVG</span> Optimization Video</a></li>
<li><a href="https://jakearchibald.github.io/svgomg/"><span class="small-caps">SVGOMG</span> — <span class="small-caps">SVGO GUI</span> in browser</a></li>
</ul>
</div>
</div>
<div class="section typeset">
<div class="column column--duo">
<h3 class="zeta">Animating</h3>
<ul>
<li><a href="https://css-tricks.com/guide-svg-animations-smil/">A Guide to <span class="small-caps">SVG</span> Animations</a></li>
<li><a href="http://www.smashingmagazine.com/2014/11/03/styling-and-animating-svgs-with-css/">Styling And Animating <span class="small-caps">SVG</span>s With <span class="small-caps">CSS</span></a></li>
<li><a href="http://product.voxmedia.com/2013/11/25/5426880/polygon-feature-design-svg-animations-for-fun-and-profit"><span class="small-caps">SVG</span> animations for fun and profit</a></li>
<li><a href="http://snapsvg.io/">Snap.svg</a></li>
<li><a href="http://svgjs.com/"><span class="small-caps">SVG</span>.js</a></li>
</ul>
</div>
<div class="column column--duo">
<h3 class="zeta">Spriting</h3>
<ul>
<li><a href="http://24ways.org/2014/an-overview-of-svg-sprite-creation-techniques/">An Overview of <span class="small-caps">SVG</span> Sprite Creation Techniques</a></li>
<li><a href="http://sarasoueidan.com/blog/structuring-grouping-referencing-in-svg/">Structuring, Grouping, and Referencing in <span class="small-caps">SVG</span></a></li>
<li><a href="http://taye.me/blog/svg/a-guide-to-svg-use-elements/">A guide to <span class="small-caps">SVG</span> <use> elements</a></li>
<li><a href="https://github.com/filamentgroup/grunticon">Grunticon</a></li>
<li><a href="https://github.com/lukewhitehouse/svg-icon-workflow"><span class="small-caps">SVG</span> icon workflow</a></li>
<li><a href="http://tomhazledine.com/inline-svg-icons/">Inline <span class="small-caps">SVG</span> icons</a></li>
</ul>
</div>
</div>
</section>
<footer class="global-footer">
<p>An <a href="https://github.com/designbyjake/svgontheweb">open source</a> side project from <a href="https://twitter.com/designbyjake">Jake Giltsoff</a></p>
</footer>
<script>
window.onload=function() {
var object = document.getElementById("logoObject");
var svgDocument = object.contentDocument;
var svgb1 = svgDocument.getElementsByClassName("firstb");
var svgb2 = svgDocument.getElementsByClassName("secondb");
svgb1[0].setAttribute("fill", "yellow");
svgb2[0].setAttribute("fill", "red");
};
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-23355677-22', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>