Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline vs External SVG #1

Open
ryelle opened this issue Jan 15, 2015 · 8 comments

Comments

@ryelle
Copy link
Owner

commented Jan 15, 2015

Came in up chat: how should we include the SVG?

Currently using this method (but without the JS fallback): http://css-tricks.com/svg-use-external-source/

@chriscoyier

This comment has been minimized.

Copy link

commented Mar 12, 2015

This is what I think is the best way...

1. Folder full of SVG icons as the base.

screen shot 2015-03-12 at 1 27 10 pm

2. A build step of some kind to smoosh them into a file

Probably like icon-symbols.svg. Class build tool is like grunt-svgstore, but there are many.

<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" class="visually-hidden">

 <symbol id="icon-whatever" viewBox="0 0 100 100">
    <!-- Not putting <title> or <desc> here on purpose, will use on case-by-case basis --?
    <path d="M6-0.076-0.02 …
    <path d="M16-0.36-1.09 …
  <symbol>

  <!-- and so on... put all of them in here -->

</svg>

This same build process should probably build PNG versions as well. Like star.svg should be processed into a star.png for use as a fallback. Possibly just use Grunticon?

3. Test for inline SVG support.

Best method:

var supportsSvg = function() {
  var div = document.createElement('div');
  div.innerHTML = '<svg/>';
  return (div.firstChild && 
    div.firstChild.namespaceURI) == 
      'http://www.w3.org/2000/svg';
};

4. Logic for support or non-support

Probably put this in the <head> - blocking but fast.

if (supportsSvg()) {

  // Ajax for the  icon-symbols.svg file

} else {

  // We’re going to need a fallback

}

5. If supported, Ajax...

Grab the file and drop it in body. The point of this is that it's browser cached. But... that depends on proper headers, can you count on that in WordPress land?

var ajax = new XMLHttpRequest();
ajax.open("GET", "icons-symbols.svg", true);
ajax.responseType = "document";
ajax.onload = function(e) {
  document.body.insertBefore(
    ajax.responseXML.documentElement,
    document.body.childNodes[0]
  );
}
ajax.send();

Alternative is to PHP include the icon-symbols.svg right onto the page. The only issue there is it's a bit bloaty for non-supporting browsers that

6. If NOT supported, fallback...

There are a variety of fallback methods...

  1. Grunticon method - set a background-image on the <svg> element itself, load a CSS file that has all the .png icons in Data URI's in that stylesheet. Apply that class to the SVG's, like <svg class="icon-star" ... > - Grunticon builds the CSS file and provides a loading mechanism for it (e.g. grunticon([])). This really only works for IE 8 though, and IE 8 doesn't have background-size, so you have to be super careful to create the .png versions the exact size you need them.
  2. Grunticon with deeper fallback - insert the SVG's like <div class="icon-star"><svg ... ></svg></div> and apply the background-image to the div instead. Works back to IE 6 even, with the Grunticon loader detecting for Data URI support
  3. Trickery - insert the SVG like: <svg ...> ... <image src="star.png" /></svg> - supporting browsers ignore that (even prefetcher), non-supporting browsers ignore the SVG part but load the img. Bonus here is you can resize the PNG's. Negative is every single icon is a separate request.

Alternative to that whole setup...

Just use Grunticon wholesale. It would be simpler, it's just not my favorite because it locks you into that setup forever. You're using a meaningless <span> in the markup that requires Grunticon (both the build and the JS) to work.

It's probably best to define some more goals for this project. Like clearly defined browser support requirements, build tool possibilities, whether you need to support no-js or not, etc.

@ryelle

This comment has been minimized.

Copy link
Owner Author

commented Mar 19, 2015

Our browser support etc are determined by WP core. Pulled from our autoprefixer settings, we say we support Chrome 21+, Firefox 17+, IE7+, Opera 12.1+, Safari 6.0+, Android 2.1+ – But for the older browsers, like IE7, I know we can get away with "not broken".

I think we've had the no-js conversation for fallbacks before, I'll see if I can look that up.

@joemcgill

This comment has been minimized.

Copy link

commented Mar 19, 2015

Here's the exhaustive compatibility list for SVGs: http://caniuse.com/#feat=svg (click 'show all')

@Dechowmedia

This comment has been minimized.

Copy link

commented Mar 20, 2015

How about using SVGInjector by the Iconic team?

This inlines the SVG (making the styleable) using only an IMG tag - and it utilise a PNG fallback :)

https://github.com/iconic/SVGInjector

@chriscoyier

This comment has been minimized.

Copy link

commented Mar 20, 2015

The issue with SVGInjector is that the markup you use is:

<img class="inject-me" src="image-one.svg">

Which means that the prefetcher will trigger HTTP requests for each of those images individually. 20 icons on the page, 20 HTTP requests. It's kinda nice when building an icon system to get that down to 1.

@Dechowmedia

This comment has been minimized.

Copy link

commented Mar 23, 2015

First of SVGInjector is cacheable
Secondly SVGInjector can utilise a data-src attribute:

Any DOM element, or array of elements, passed to SVGInjector with an SVG file src or data-src attribute will be replaced with the full SVG markup inline. The async loaded SVG is also cached so multiple uses of an SVG only requires a single server request.

This is one of the examples that they also show on the page

<style>
  .thumb-green {fill: #A6A93C;}
</style>
<img class="thumb-green inject-me" data-src="svg/thumb-up.svg" data-fallback="png/thumb-up-green.png">

So it does not make a subsequent request if that's what you are referring to?

However, there are some kickbacks from using a SVG spritesheet.
Which is for one responsive, how can we trigger they correct icons on the different screen states?
Also how are we letting plugin developers attaching their own icons to an example a menu item in the dashboard?

@chriscoyier

This comment has been minimized.

Copy link

commented Mar 26, 2015

That looks better for sure. It kinda seems like it doesn't address spriting though (like making sure only 1 request is made for all icons). Maybe that's not a big deal for WordPress? I dunno. It's always a big deal to me, but your icon system I think needs to be author-extendable, so maybe it's better if it's not sprited. There are kind of a lot of icons on any given WP admin page though, plus the current icon font system is essentially a one-request sprite, so probably best to be at least that performant.

@melchoyce

This comment has been minimized.

Copy link

commented May 13, 2015

Also how are we letting plugin developers attaching their own icons to an example a menu item in the dashboard?

This is actually already possible (but apparently is a little janky?): http://mannieschumpert.com/blog/using-wordpress-3-8-icons-custom-post-types-admin-menu/

Right now plugin authors can add their own svgs, set of pngs, or an icon from the Dashicons font.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.