Closed dzucconi closed 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?
? | 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.
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.
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.
Ah right
But, the external resource way doesn't work in any version (up to 11 tested) of Internet Explorer.
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?
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.
A+ :clap:
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?