Creative Typography with SVG



Brenna O'Brien / @brnnbrn

front-end engineer /  


#SVGType

These 8 Weird SVG Tricks Will Totally blow your mind

You might also learn a lot about SVG

SVG101

 =


  
    <path fill="#BE1637" stroke="#fff"
      d="M96.333,18.385c-2.396-6.01-7.205-11.064-13.857-14.194
      C76.595,1.423,70.26,1.09,64.501,2.782
      C58.743,4.472,53.566,9.081,50,14.408
      c-3.565-5.327-8.743-9.936-14.5-11.626
      C29.743,1.09,23.406,1.423,17.526,4.191
      c-6.652,3.128-11.46,8.184-13.858,14.194
      c-2.396,6.01-2.407,12.987,0.614,19.927
      C10.743,53.154,49.795,87.993,50,88.588
      c0.205-0.595,39.258-35.434,45.718-50.276
      C98.74,31.371,98.729,24.395,96.333,18.385z" />
  
  

V.R.E.A.M


viewBox Rules
Everything Around Me

resolution independent


easy to manipulate with CSS & JS


  .heart:hover {
    fill: #fff;;
  }
      

great for icons and logos

Let's talk about <text>
baby

<text>
is accessible

<text>101



  
    CSS Dev Conf
  
  

<text>101


  • watch out for y=0 default

  • no automatic line breaks

1

typo-
graphic
lock-up

http://codepen.io/brenna/full/raOBaw/

Let's talk about...


  • <tspan>

  • textLength

  • lengthAdjust

<tspan>


  • similar to HTML <span>

  • absolute positioning with x & y

  • relative positioning with dx & dy

typographic lock-up


  
    
      <tspan textLength="80" x="0" y="1em"
        lengthAdjust="spacing">What is</tspan>
      <tspan textLength="80" x="0" dy="1em"
        lengthAdjust="spacingAndGlyphs">love</tspan>
    
  
  

typographic lock-up


  
    
      <tspan textLength="80" x="0" y="1em"
        font-size="20" >What is</tspan>
      <tspan textLength="80" x="0" dy="0.9em"
        font-size="30" font-weight="bold" >love</tspan>
    
  
  

CSS can set most attributes


  .love {
    fill: #FF6666;
  }
     

  
    
      <tspan textLength="80" x="0" y="1em"
        font-size="20" >What is</tspan>
      <tspan class="love" textLength="80" x="0" dy="0.9em"
        font-size="30" font-weight="bold" >love</tspan>
    
  
    

RESPONSIVE TEXT!

responsive SVG


viewBox + flexible container

Fitter, Happier, Text
2

curved
text

Let's talk about...


  • <textPath>

  • alignment-baseline

  • <defs>

<textPath>


set text along an arbitrary path

curved text with <textPath>


  
    <path id="arc" stroke="red" d="M82.372,165.969 c44.126-35.084,60.236-50.782,150.325-50.782s131.802,28.198,158.194,62.77" />
    <text fill="#5D509D" width="500">
      <textPath alignment-baseline="middle" xlink:href="#arc" font-size="44"  dy="100">
        Are You Afraid
      </textPath>
    </text>
  
  

<defs>


  • where you define re-usable SVG components

  • a trusty steed as we combine SVG techniques

curved text with <textPath>


  
    
     
    
    
      <textPath xlink:href="#arc" font-size="44"  dy="100">
        Are You Afraid
      </textPath>
      of the
      Dark?
    
  
  
3

text
filled
with gradients

smell ya later

-webkit-background-clip: text;

Let's talk about ...


  • <linearGradient>

  • <radialGradient>

  • gradientUnits

<linearGradient>


  <linearGradient id="fire" x1="0" y1="0" x2="100%" y2="100%">
    <stop stop-color="hotpink" offset="0%"/>
    <stop stop-color="goldenrod" offset="100%"/>
  </linearGradient>
  

<radialGradient>


  <radialGradient id="ring-of-fire" cx="50%" cy="50%" r="40"
    gradientUnits="userSpaceOnUse">
    <stop stop-color="hotpink" offset="0%"/>
    <stop stop-color="goldenrod" offset="100%"/>
  </radialGradient>
  

gradientUnits


  • userSpaceOnUse
    = absolute

  • objectBoundingBox
    = object relative


see also:
clipPathUnits, maskUnits, patternUnits

Clipping in CSS and SVG: The clipPathUnits attribute

gradient filled text


  
    <defs>
      <linearGradient id="fire">
        <stop stop-color="hotpink" offset="0%"/>
        <stop stop-color="goldenrod" offset="100%"/>
      </linearGradient>
    </defs>
    Wow!
  
  
http://codepen.io/brenna/full/mybQVx/
4

text
filled
with images

Let's talk about...


  • <image>

  • <pattern>

  • <clipPath>

<image> vs <img>

  

  
    
    <image preserveAspectRatio="xMidYMid slice"
      xlink:href="img/moon.jpg" width="200" height="100" />
  
  

<pattern>


  • turns any SVG element into a fill

  • most fun with <image>

image fills with <pattern>


  
    
      <pattern id="moon" width="200" height="60"
        patternUnits="userSpaceOnUse">
        
      </pattern>
    
    moon
  
  

Image fill hot tips


  • <image> needs a width and height

  • preserveAspectRatio to fill viewBox

  • patternUnits="userSpaceOnUse" to size image viewBox



A Look At preserveAspectRatio in SVG

<clipPath>


restricts the visible area of another SVG element

image fills with <clipPath>


  
    
      
        mars
      
    
    <image clip-path="url(#mars-text)" xlink:href="img/mars2.jpeg"
    width="200" height="60" preserveAspectRatio="xMidYMax slice"/>
  
  

Why not text filled with gifs?

http://codepen.io/brenna/full/vEBQra/
5

knockout text

http://codepen.io/brenna/full/XmeRqb/

Let's talk about...


  • <mask>

  • <rect>

  • text-anchor

<mask>


  • like <clipPath> but with more control

  • black fill = opaque mask
    white fill = transparent mask

knockout text with <mask>


    
      
      
         Buy 2 hams $20
      
    
  

knockout text with <mask>


  
    <rect fill="#000" fill-opacity=".75" mask="url(#ham-text)"
    x="0" y="0" width="200" height="50" />
    
      
      
         Buy 2 hams $20
      
    
  
  
6

self typing
text

Let's talk about...


<animate>

<animate>


animate (almost) any attribute, from within the SVG



Animatable SVG Attributes

<animate>



  
    <line stroke="goldenrod" stroke-width="10"
      x1="0" y1="50" x2="0" y2="50">
      <animate attributeName="x2"
      from="0" to="800"
      dur="2s" repeatCount="indefinite"/>
    </line>
  
  

self-typing text with <textPath> and <animate>


  
    
      
        <animate attributeName="d" from="m0,50 h0" to="m0,50 h800" dur="2s" repeatCount="indefinite"/>
      
    
    
      <textPath xlink:href="#animatedLine">
        hack the planet</textPath>
    
  
  

self-typing text with <textPath> and <animate>


  
    
      
        <animate attributeName="d" from="m0,50 h0" to="m0,50 h400" dur="1s" repeatCount="indefinite"/>
      
    
    
      <textPath xlink:href="#animatedLine">
        loading...</textPath>
    
  
  

Q: Why not just <animate>
with CSS & JS?


A:

7

ani-
morphing
text

<animate> can morph glyphs!

http://codepen.io/NinjaCoffee/full/JoJZrB/

converting text to paths

morphing text paths


  
    
      <animate class="yes" attributeName="d" dur="1s"
        begin="indefinite" fill="freeze"
        to="M7.27,5.416 h26.127  l16.5,34.2 l16.5-34.2  h26.1 l-31.1,53.1  l0,32.107 l-11.35,0 l-11.35,0 l0-31.9z"/>
      <animate attributeName="fill" dur="1s"
        begin="indefinite" fill="freeze"
        to="goldenrod"/>
    
  
  

morphin' hot tips


  • paths must have the exact same number and type of anchor points

  • fill="freeze" to hold end state

  • duration="indefinite" and .beginElement()to trigger with JS



How SVG Shape Morphing Works

paths can be made accessible


<title>, <desc> and ARIA



Tips for Creating Accessible SVG

8

self drawing
text

Let's talk about...


  • stroke-dasharray

  • stroke-dashoffset

self-drawing <text>


  
    <text stroke-dasharray="700 700" stroke-dashoffset="700" fill="none" stroke="#fff" dy="1em" font-size="70">
      cool
      <animate dur="2s" repeatCount="indefinite"
        attributeName="stroke-dashoffset"
        values="700;0" />
    <text>
    
   

self-drawing <path>


long
stroke-dasharray

+

animated
stroke-dashoffset

How SVG Line Animation Works

self-drawing <path>


  
    <path stroke-dasharray="200 200" stroke-dashoffset="200" fill="none" stroke="#fff"
      d="M26.325,31.255c0.623-2.608-1.089-8.703-1.089-11.383c0-2.863-0.255-5.876,0.028-8.725c1.533,3.676,4.99,6.807,7.303,9.998c1.781,2.457,3.374,4.643,4.075,7.623c2.356-0.13,4.568-1.057,7.044-0.652c1.929,0.315,4.543,1.057,6.155,2.174c0.737-1.115,1.155-2.605,1.626-3.831c1.263-3.285,2.666-6.38,4.499-9.385c0.839-1.375,1.635-2.99,2.583-4.26c0.104,5.004,1.526,9.846,1.548,14.827c0.004,0.896-0.126,1.903,0,2.79c0.134,0.947,0.079,0.708,0.49,1.458c0.772,1.411,2.459,2.691,3.478,3.954c1.379,1.711,2.333,3.192,2.921,5.313c0.97,3.497,1.53,8.9,0.375,12.37c-1.624,4.879-4.688,7.727-8.488,10.109C51.7,68.133,47.63,68.824,39.28,65.737c-6.503-2.404-12.196-6.026-15.273-12.438c-1.965-4.096-2.422-9.251-2.118-13.737C22.035,37.402,23.517,31.44,26.325,31.255">
      <animate dur="2s" repeatCount="indefinite"
        attributeName="stroke-dashoffset"
        values="200;0" />
    </path>
    
   

self-drawing text


  
    <path stroke-dashoffset="170" stroke-dasharray="170 170" d="M85.829,53.281C79.831,43.719,68.859,28.49,55,31.392c-14.211,2.976-24.931,16.44-22.009,31.469C36.657,81.72,51.87,88.245,65.286,98.974c9.447,7.554,20.266,14.968,16.728,27.692">
      <animate dur="2.5s" repeatCount="indefinite"
        attributeName="stroke-dashoffset"
        values="170;0;0;0;0;0"/>
    </path>
    
      <animate dur="2.5s" repeatCount="indefinite"
        attributeName="stroke-dashoffset"
        values="170;170;0;0;0;0" />
    
    
      <animate dur="2.5s"repeatCount="indefinite"
      attributeName="stroke-dashoffset"
      values="720;720;720;360;0;0" />
    
  
  

<text>

<tspan>

<textPath>

<defs>

<linearGradient>

<radialGradient>

<stop>

<image>

<pattern>

<clipPath>

<mask>

<rect>

<animate>

<line>

<path>

d

fill

stroke

x, y

dx, dy

textLength

lengthAdjust

font-size

font-weight

xlink:href

alignment-baseline

x1, x2

y1, y2

cx, cy, r

stop-color

offset

gradientUnits

clipPathUnits

maskUnits

patternUnits

preserveAspectRatio

text-anchor

fill-opacity

attributeName

to, from

values

begin, dur

repeatCount

stroke-dasharray

stroke-dashoffset

<a>

<altGlyph>

<altGlyphDef>

<altGlyphItem>

<animate>

<animateColor>

<animateMotion>

<animateTransform>

<circle>

<clipPath>

<color-profile>

<cursor>

<defs>

<desc>

<ellipse>

<feBlend>

<feColorMatrix>

<feComponentTransfer>

<feComposite>

<feConvolveMatrix>

<feDiffuseLighting>

<feDisplacementMap>

<feDistantLight>

<feFlood>

<feFuncA>

<feFuncB>

<feFuncG>

<feFuncR>

<feGaussianBlur>

<feImage>

<feMerge>

<feMergeNode>

<feMorphology>

<feOffset>

<fePointLight>

<feSpecularLighting>

<feSpotLight>

<feTile>

<feTurbulence>

<filter>

<font>

<font-face>

<font-face-format>

<font-face-name>

<font-face-src>

<font-face-uri>

<foreignObject>

<g>

<glyph>

<glyphRef>

<hkern>

<image>

<line>

<linearGradient>

<marker>

<mask>

<metadata>

<missing-glyph>

<mpath>

<path>

<pattern>

<polygon>

<polyline>

<radialGradient>

<rect>

<script>

<set>

<stop>

<style>

<svg>

<switch>

<symbol>

<text>

<textPath>

<title>

<tref>

<tspan>

<use>

<view>

<vkern>

MDN: SVG element reference

accent-height

accumulate

additive

alignment-baseline

allowReorder

alphabetic

amplitude

arabic-form

ascent

attributeName

attributeType

autoReverse

azimuth

baseFrequency

baseline-shift

baseProfile

bbox

begin

bias

by

calcMode

cap-height

class

clip

clipPathUnits

clip-path

clip-rule

color

color-interpolation

color-interpolation-filters

color-profile

color-rendering

contentScriptType

contentStyleType

cursor

cx

cy

d

decelerate

descent

diffuseConstant

direction

display

divisor

dominant-baseline

dur

dx

dy

edgeMode

elevation

enable-background

end

exponent

externalResourcesRequired

fill

fill-opacity

fill-rule

filter

filterRes

filterUnits

flood-color

flood-opacity

font-family

font-size

font-size-adjust

font-stretch

font-style

font-variant

font-weight

format

from

fx

fy

g1

g2

glyph-name

glyph-orientation-horizontal

glyph-orientation-vertical

glyphRef

gradientTransform

gradientUnits

hanging

height

horiz-adv-x

horiz-origin-x

id

ideographic

image-rendering

in

in2

intercept

k

k1

k2

k3

k4

kernelMatrix

kernelUnitLength

kerning

keyPoints

keySplines

keyTimes

lang

lengthAdjust

letter-spacing

lighting-color

limitingConeAngle

local

marker-end

marker-mid

marker-start

markerHeight

markerUnits

markerWidth

mask

maskContentUnits

maskUnits

mathematical

max

media

method

min

mode

name

numOctaves

offset

onabort

onactivate

onbegin

onclick

onend

onerror

onfocusin

onfocusout

onload

onmousedown

onmousemove

onmouseout

onmouseover

onmouseup

onrepeat

onresize

onscroll

onunload

onzoom

opacity

operator

order

orient

orientation

origin

overflow

overline-position

overline-thickness

panose-1

paint-order

path

pathLength

patternContentUnits

patternTransform

patternUnits

pointer-events

points

pointsAtX

pointsAtY

pointsAtZ

preserveAlpha

preserveAspectRatio

primitiveUnits

r

radius

refX

refY

rendering-intent

repeatCount

repeatDur

requiredExtensions

requiredFeatures

restart

result

rotate

rx

ry

scale

seed

shape-rendering

slope

spacing

specularConstant

specularExponent

speed

spreadMethod

startOffset

stdDeviation

stemh

stemv

stitchTiles

stop-color

stop-opacity

strikethrough-position

strikethrough-thickness

string

stroke

stroke-dasharray

stroke-dashoffset

stroke-linecap

stroke-linejoin

stroke-miterlimit

stroke-opacity

stroke-width

style

surfaceScale

systemLanguage

tableValues

target

targetX

targetY

text-anchor

text-decoration

text-rendering

textLength

to

transform

type

u1

u2

underline-position

underline-thickness

unicode

unicode-bidi

unicode-range

units-per-em

v-alphabetic

v-hanging

v-ideographic

v-mathematical

values

version

vert-adv-y

vert-origin-x

vert-origin-y

viewBox

viewTarget

visibility

width

widths

word-spacing

writing-mode

x

x-height

x1

x2

xChannelSelector

xlink:actuate

xlink:arcrole

xlink:href

xlink:role

xlink:show

xlink:title

xlink:type

xml:base

xml:lang

xml:space

y

y1

y2

yChannelSelector

z

zoomAndPan

MDN: SVG attribute reference

go on
a code adventure

SVG on MDN

jenkov.com SVG Tutorials

You'll probably learn something useful

thank you!



#SVGType 5 wow!

(504) 229-6828