sara soueidan: styling and animating scalable vector graphics with css [cssconfus2014]

Post on 29-Nov-2014

233 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Scalable Vector Graphics, or SVGs, are the new "big thing" in web design today, and for a good reason. With the proliferation of retina screens and high resolution displays, we need to adopt techniques that allow us to serve graphics that look good on all screens in all circumstances, and because SVGs offer resolution-independent, fully scalable and crystal clear graphics, it is safe to say that they are the future graphics format of the web. In this talk we're going to see how SVGs can be styled in CSS, and how they can be animated using CSS animations and transitions. We're also going to cover "responsifying" SVGs using CSS media queries, and how we can control the size and looks of SVGs allowing them to adapt to different screen sizes. We'll cover a short workflow from a vector graphics editor to a responsive animated graphic on screen.

TRANSCRIPT

Styling & Animating Scalable Vector

Graphics with CSS

CSSConf - May 27th 2014, Florida @SaraSoueidan / sarasoueidan.com

Hello,I’m Sara.

Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.

Why SVGs?

➔ SVGs are accessible

➔ Scalable & Resolution Independent

➔ Very Good Browser Support

➔ Smaller sizes (can be gzipped)

➔ Built-in Graphics Effects (Blend Modes, Filters, etc.)

➔ Interactive and Styleable (CSS and Javascript)

➔ SVGs Have Tools

Creating SVGs

Adobe Illustrator Inkscape (Free) Sketch (Mac OS X only)

Optimize Exported Code (Standalone Tools)

http://goo.gl/0XvzHs

SVG Editor by Peter Collingridge (Online)

Optimize Exported Code (Standalone Tools)

SVG O (NodeJS-Based + GUI)

Peter’s SVG Editor

Clean Up & Give Classes

bird.svg

Replace generic class names with semantic ones that describe your illustration.

Styling SVGs with

CSS

SVG Presentation Attributes

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">

<polygon

fill = "#FF931E"

stroke = "#ED1C24"

stroke-width = "5"

points = "279.1,160.8 195.2,193.3 174.4,280.8 117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/>

</svg> star.svg

Shared with CSS SVG-onlyfont

font-family

font-size

font-size-adjust

font-stretch

font-style

font-variant

font-weight

direction

letter-spacing

text-decoration

unincode-bidi

word-spacing

visibility

text-rendering

writing-mode

clip-path

mask opacity

filter

pointer-events

image-rendering

clip

color

cursor

display

overflow

clip-ruleflood-colorflood-opacitystop-opacitykerningtext-anchorcolor-profile color-rendering

fill fill-opacityfill-rulemarkermarker-end marker-mid marker-start

strokestroke-width

stroke-opacitystroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitalignment-baselinebaseline-shiftshape-renderingglyph-orientation-horizontalglyph-orientation-verticalcolor-interpolationcolor-interpolation-filtersdominant-baselinelighting-colorstop-colorenable-background

http://goo.gl/LVkevr

Inline Styles (style=” ”)

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style=”width: 300px; height: 300px;” viewBox="0 0 300 300">

<polygon

style = ”fill: #FF931E; stroke: #ED1C24; stroke-width: 5;”

points = "279.1,160.8 195.2,193.3 174.4,280.8 117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/>

</svg>star.svg

Embedded Styles (<style>) Inside svg

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">

<style type=”text/css”><![CDATA[

selector {/* styles */}]]>

</style><g id=”..”> … </g>

</svg> filename.svg

Embedded Styles (<style>) Outside svg

<!DOCTYPE html><!-- HTML5 document --><html> <head> ... </head> <body><style type=”text/css”>

/* style rules */</style><!-- xmlns is optional in an HTML5 document --><svg version="1.1" viewBox="0 0 300 300">

<!-- SVG content --></svg></body> </html>

filename.html

External Style Sheets

<?xml version="1.0" standalone="no"?><?xml-stylesheet

type="text/css" href="style.css"?>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1"

width=".." height=".." viewBox="..">

<!-- SVG content -->

</svg> filename.svg

Style Rules (Selectors) Type Selectors:g {/* style a group */}circle, rect { fill: #009966; }

Class and ID Selectors:.arrow-head { /* styles */ }#bird { /* styles */ }

Dynamic Pseudo-Class Selectors:.icon:hover, .icon:active, .icon:focus { /* styles */ }

Pseudo-Class Selectors::first-child, :last-child, :nth-*-child(), :visited, :link and :lang, :last-of-type, :first-of-type, :not(), :nth-*-type(), :only-child, :only-of-type, ...

Children Selectors:g > circle {/* styles */}

Notes: Pseudo-elements/Generated Content don’t work.

Style Cascades

http://goo.gl/QHFp6w

Presentation attributes count as low level “author stylesheets” and are overridden by any other style definition (external stylesheets, document stylesheets and inline styles).

<circle cx="100" cy="100" r="75" fill="blue" style="fill:deepPink;" />

Example: Simple Hover Effect (Iconic)

Changing the stroke color and stroke width. Fading background in on hover.

http://goo.gl/Fofspo

Embedding

SVGs

http://goo.gl/oiYssv

1 <img src=”image.svg” alt=”Site Logo” />

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

<img src=”fallback.jpg”><!-- fallback -->

</object>

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

4<iframe src="image.svg">

<!-- fallback here -->

</iframe>

5 <svg> … </svg> <!-- XHTML/HTML5 Document -- >

6 #el { background-image: url(image.svg); }

SVG Embed Technique Links, External Styles, Interactivity, CSS Animations

<img src=”img.svg” alt=”” /> Nope*

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

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

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

Inline <svg> … </svg> Yep

background-image: url(image.svg); Nope*

* CSS animations won’t be played, but SVG (SMIL) animations will be preserved..

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="350px" height="400px” viewBox="0 0 350 400" >

<style type="text/css"><![CDATA[

.fish {transform-origin: 50%;animation: shake .4s linear infinite;

}@keyframes shake {

to {-webkit-transform: rotate(-10deg);}}

]]></style> <g id="bear" …> <!-- ... --></g></svg>

bear-css.svg

Example: CSS Animation

Example(Embedded)

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="350px" height="400px” viewBox="0 0 350 400" > <g id="bear" …>

<!-- … --><g class=”fish”>

<!-- ... --><animateTransform attributeName="transform"

type="rotate" begin="0s" dur=".4s" from="0 380 530" to="-10 380 530" repeatCount="indefinite" fill="freeze" />

</g></g></svg>

bear-smil.svg

Example: SVG (SMIL) Animation

Example (Embedded)

Responsifying

SVGs

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=”300px height=”300px” > <style type="text/css">

.eye{fill:#8B6A62;}

.face{fill:#F6E6E5;}

.head{fill:#F7A591;}/* ... */

</style> <path class="body" d=”...”> <!-- ... --></svg>

owl.svg

Example

1. Remove Width & Height, Add viewBox

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 300"> <style type="text/css">

/* ... */ </style> <path class="body" d=”...”> <!-- ... --></svg>

owl.svg

2. Preserve Aspect Ratio

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 300" preserveAspectRatio="xMinYMin meet"> <style type="text/css">

/* ... */ </style> <path class="body" d=”...”> <!-- ... --></svg>

owl.svg

Note: Without viewBox, preserveAspectRatio has no effect.

http://goo.gl/b50HY8

3. Embed & Wrap in a container<!DOCTYPE html><!-- HTML5 document --><html> <head> ... </head>

<body><div class=”my-svg-container”>

<object type="image/svg+xml" data="owl.svg" class=”my-svg”>

<!-- fallback here --> </object>

</div></body></html>

responsive-owl.html

SVG can be embedded as <object>, <img> or inline as an <svg>. The technique will work for all three embeds.

4. Padding Hack on Container

.my-svg-container {height: 0;position: relative; /* create positioning context for svg

*/width: width-value; padding-top: (SVG height / SVG width) * width-value;

}

responsive-owl.css

For owl.svg: padding-top = 300 / 300 * 100 = 1 * 100 = 100%;If width of container = 60%: padding-top = 300 / 300 * 60 = 1 * 60 = 60%;If owl.svg has width 250px, height 400px: padding-top = 400/250 * 100 = 1.6 * 100 = 160%;

4. Position SVG Inside Container

/* pull the svg to the top of the container */.my-svg {

position: absolute;top: 0;

left: 0;width: 100%; /* only required for <img /> */

}

responsive-owl.css

6. Resize!

Animating SVGs with CSS

Transforming

SVGs

Initial transform-origin on HTML & SVG

Box Model? transform-origin (default value)

HTML elements (div, etc.) Yes 50% 50%*

SVG elements (circle, rect, etc.) No 0 0**

*50% 50% = center of the HTML element itself** 0 0 is the top left corner of the SVG canvas, not the element itself

CSS Transforms on HTML & SVG<!DOCTYPE html>...<div style=”width: 100px; height: 100px; background-color: orange”> </div><svg style=”width: 150px; height: 150px; background-color: #eee”>

<rect width="100" height="100" x="25" y="25" fill="orange" /></svg>

Setting transform-origin on SVG Elements

1. Using Percentage Values: The value is set relative to the

element’s bounding box, which includes the stroke used to

draw its border.

2. Using absolute length values: The origin is set relative to the

SVG canvas.

CSS Transforms on HTML vs SVG (cont’d)<!DOCTYPE html><style>

div, rect {transform-origin: 50% 50%;

}</style>

Heads up: Transform-Origin Issue In Firefox With Percentage Values

Setting transform-origin using a percentage value currently doesn’t work in Firefox. That is a bug. (It shouldn’t be a problem if you’re not rotating anything.)

Setting it in absolute length values should be fairly simple using a graphics editor.

Example: PinWheel

PinWheel by http://pixeldoree.com/vector/free-vector-pinwheels-adobe-illustrator-and-png-files/

.wheel { -webkit-transform-origin: 50% 50%;

transform-origin: 193px 164px; animation:

spin 4s cubic-bezier(.49,.05,.32,1.04)infinite alternate;}

@keyframes spin { 50% { transform: rotate(360deg); }}

Zooming out (or in) in Webkit/Blink does not maintain the transform origin at the center of the rotating element. This is a bug.

This issue does not happen in Firefox, where the transform origin is set in absolute values (relative to the SVG canvas).

Heads up: Transform-Origin Issue In Chrome With Percentage Values

→ Just use absolute values (for the time being)!

Heads up: Hardware Acceleration In Chrome

CSS 3D transforms are hardware accelerated in Chrome when applied to HTML elements. However, they are not accelerated when used on SVG elements - they have the same performance profile as SVG transform attributes. They are accelerated in Firefox.

Animating SVG Paths

Animated Line DrawingTo Animate an SVG path you need to know its exact length. Then:

#path {

stroke-dasharray: pathLength;

stroke-dashoffset: pathLength;

/* transition stroke-dashoffset */

transition: stroke-dashoffset 2s linear;

}

svg:hover #path{

stroke-dashoffset: 0;

}

Example#cable {

stroke: #FFF2B1;stroke-dasharray: 4000 4000;stroke-dashoffset: 4000;stroke-width: 4;transition: stroke-dashoffset 8s

linear;}svg:hover #cable {

stroke-dashoffset: 0;}/* turn lamp on */.inner-lamp{

fill:grey; transition: fill .5s ease-in 6s;

}svg:hover .inner-lamp {

fill: #FBFFF8;}/* ... */

The animated path is positioned on top of the black path. When SVG is hovered path is animated, and the lamp is “turned on” after path finishes animation, using a delay that is equal to the animation (transition) time of the path.

Example 2

http://goo.gl/zII9p0

var path = document.querySelector('.drawing-path');path.getTotalLength();//set CSS properties uppath.style.strokeDasharray = length + ' ' + length;path.style.strokeDashoffset = length;//set transition uppath.style.transition = 'stroke-dashoffset 2s ease-in-out';// animatepath.style.strokeDashoffset = '0';//more: http://jakearchibald.com/2013/animated-line-drawing-svg/

Animated Line Drawing: Retrieving Path Length Using Javascript

#RecommendedReading

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

Animated Paths (Morphing Paths)

http://goo.gl/ri9nwU

Animated Paths (Morphing Paths)

The idea is to create a SVG with one path and to morph that path into another one.

You’ll need: the first path, the second path, and possibly intermediate paths (depending on your animation).

There is no way in CSS to animate one SVG path into another.

http://goo.gl/93gFYh

http://snapsvg.io/

Use Snap.svg

“ By using animated SVGs instead of GIFs we were able to reduce our page size from 1.6 mb to 389 kb, and reduce our page load time from 8.75 s to 412 ms. That’s a huge difference.”

Animated SVGs As GIFs Replacement

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

Don’t forget to..

Make SVGs Accessible

http://goo.gl/sG7G0j

#MustRead

Optimize & Degrade Gracefully

http://goo.gl/nhXtbu

#MustRead

Thank You!@SaraSoueidan / sarasoueidan.com

top related