artsy / artsy-iconfont

3 stars 1 forks source link

@broskoski: Font -> SVG #17

Closed dzucconi closed 9 years ago

dzucconi commented 9 years ago

I'd wait on merging this until I work through some of the implementation inside of Force.

Feedback requested.


This implements a pipeline that optimizes our SVGs then uses grunticon to process them. Rather than embedding base64 data URIs, it inlines them directly which compresses better (the final embedded SVG stylesheet weighs in at 8kb gzipped). Since you can't change the color of SVG background images using CSS, it pre-processes all the specified colors (in this case black, white, artsy-purple).

This also outputs plain versions of the optimized SVGs for situations when you do want to embed them directly (but understand the reasons you'd actually want to do that and the tradeoffs you make).

(Things we probably don't want/need are the PNG fallbacks and the grunitcon loader—we can separate this stuff out and use the underlying libs instead)


It wouldn't be hard at all to integrate this process into Force/Microgravity directly. But I'm thinking it'd make most sense to keep it separate and expose the build artifact via NPM?


icons

broskoski commented 9 years ago

Looks good to me. I'm mostly curious what a real world implementation looks like. What would sizing and positioning look like?

I don't have any opinions about the png fallback, other than it seems like a safe idea.

Do you see any downsides to this background-image / embedded if we need it approach?

dzucconi commented 9 years ago
? Iconfont Background SVG Inline SVG
Style color w/ CSS Yes No Yes
Position & size w/ CSS Really annoying Simplest Simple
Can compress and share a single, cacheable file Yes Yes No
Animation No No Yes

You would use backgrounded SVGs by just appending the class icon-foo or icon-foo-color to the thing you want; it gives you a background that can be sized using background-size: contain & positioned like background-position: center center.

The main downside to using backgrounded SVGs is not being able to arbitrarily color them using CSS. In practice we very rarely do this and I think it's easier to deal with the issues surrounding that than for people to have to learn how line-height works.

To do a different color hover state you'd have to turn on and off some layered icons. Take an example from The Guardian (the photo expand icon on the right):

The problem with inlining all the SVGs is you're all of a sudden adding a bunch of uncacheable data to each page load for no reason. Take for instance the show page:

The artworks there are rendered server-side so if you want to inline all those SVGs then here's the differences in document size (not any external assets, just the markup on the page):

slug without inline SVG with inline SVG
new-museum-1-2015-triennial-surround-audience 297kb 415kb
tambaran-tambaran-at-aoa-tribal-fair 44.4kb 61.3kb
taschen-bizarre-life-the-art-of-elmer-batters-and-eric-stanton 774kb 1.1mb

(It's also probably worth considering trying to reduce the size of the JSON that is used to bootstrap the client, but that's a different story)

This isn't to say it's a bad thing to use inlined SVG if need be—but it probably is if you're going to be including 50 of them on every page of the site.

dzucconi commented 9 years ago

Another idea for dealing with changing out colors in CSS is to try what http://www.lonelyplanet.com/ is doing which is to generate sprites that contain each color, embed those, then adjust coloring using background-position which could probably be made palattable with some Stylus helpers or just modifier classes.

dzucconi commented 9 years ago

Also it IS worth mentioning given the above comparison. https://css-tricks.com/svg-use-external-source/ is another option. I haven't explored that much yet.

dzucconi commented 9 years ago

Ah right

But, the external resource way doesn't work in any version (up to 11 tested) of Internet Explorer.

broskoski commented 9 years ago

The goal here is to switch to an icon implementation that isn't cumbersome to:

And we want to do both of these things without sacrificing page performance.

Seems to me like your background SVG (with additional color classes) makes the most sense. Is that how you're feeling?

dzucconi commented 9 years ago

Yah. And that's what I did. I'm just also including the optimized SVGs from this so that they could potentially be used if there's a good reason (animation, etc).

I suppose next steps here are just wrap this up into a module for NPM distribution, opening up a branch of Force and work through the replacement of them using it.

broskoski commented 9 years ago

A+ :clap: