2017-02-10 25 views
11

我知道如何让SVG图标装上我的网站,但我想不通的是如何满足所有的下列限制:如何在避免FOMI的同时在外部CDN上缓存SVG图标?

  1. 能够使用SVG图标CSS
  2. 的无闪光缺少的图标(FOMI)
  3. 最小的初始页面大小
  4. 缓存SVGs
  5. 能够使用CDN
  6. 必须能够使用fill: currentColor,使图标匹配当前TEX吨颜色,就像图标的字体
  7. 加成:Pixel-align the SVGs所以它们总是看起来尖锐

1,2,3和4可以通过使用外部精灵地图像这样满足:

<svg viewBox="0 0 100 100"> 
    <use xmlns:xlink="http://www.w3.org/1999/xlink" 
     xlink:href="/assets/sprite-4faa5ef477.svg#icon-asterisk-50af6"></use> 
</svg> 

但是,我们不能在浏览器修复CORS issue之前使用CDN。

我们可以patch in支持外部域,但我敢肯定,这不会为CSS工作,因为它只监视DOM(对不起,尚未测试),并且它也会导致您的浏览器做出一大堆失败的请求到它无法获取的文件(页面上的每个图标都有一个)。

我们可以使用CDN,而不是内联整个SVG(增加页面大小,无缓存),或者我们AJAX它(导致FOMI)。

那么,有什么解决方案可以满足所有约束吗?

基本上我希望SVG像图标字体一样方便或者没有切换点。 SVG支持多种颜色,并且更易于访问,但我无法让它们看起来很好,或者有效地加载。

+0

你可以把你的SVGs成一个图标字体http://fontello.com/ –

+0

@HolgerWill没错。我目前正在使用图标字体w/icomoon,但是每个人都在说SVG现在都是风靡一时,我正试图弄清楚它们究竟有多好。他们支持多种颜色,当然,但[它们看起来并不脆](http://stackoverflow.com/q/42081449/65387),并且它们不适用于CDN,所以现在SVG看起来像它们吸。由于[FontCustom](https://github.com/FontCustom/fontcustom/issues/321)似乎已经死亡,所以使用webpack构建起来更容易一些。 – mpen

+1

我猜聚合物做了什么...把你的图标放在一个html文件中,并使用html-includes与自定义元素结合,也许 –

回答

1

我最好的猜测是使用data uris,它有pretty great browser support。通过类似Grunticon或其网络应用程序Grumpicon

输出是2 css文件和1 js应该与您的CDN无缝工作。

rendered output是非常灵活和可定制的。

+0

数据URI不可缓存。在CSS中使用可能会好,但我不希望在我的初始页面加载HTML中重复200次1000字节的数据URI。 – mpen

+1

够公平的,希望你能想出一些东西。 :) –

3

我能得到加载在图像元素的SVG,然后使用它像一个“老式” image sprite最接近的一次。据我所知,这可以满足你所有的限制条件。我能想到的唯一缺点是你失去了使用CSS修改SVG特定部分的能力。然而,这不是你的约束之一(如果我错了,请纠正我),并且仍然可以修改所有图标,如您在演示中看到的。我创建了一个fiddle并且完整性还包括一个代码片段。

为了模拟一个CDN,我创建了一个SVG文件并将其上传到一些图像托管服务。如果这项服务现在停止,我向未来的读者致歉。SVG文件简单地包含所有图标(我现在创建了一个黑色正方形,圆形和三角形)。与SVG雪碧贴图的区别在于图标在SVG本身中,而不是在defs中。将多个SVG合并为一个应该很容易,我还没有找到可以自动执行此过程的工具。

.icon { 
 
    display: inline-block; 
 
    vertical-align: top; 
 
    width: 30px; /* can be anything */ 
 
    height: 30px; 
 
    background-image: url('http://imgh.us/icons_36.svg'); 
 
    
 
    border: 1px solid #000; /* just to see where the icon is */ 
 
} 
 

 
/* sizes */ 
 
.icon.large { 
 
    width: 50px; 
 
    height: 50px; 
 
    background-size: 150px auto; 
 
} 
 

 
/* icons */ 
 
.icon.circle { background-position: -30px 0; } 
 
.icon.large.circle { background-position: -50px 0; } 
 
.icon.triangle { background-position: -60px 0; } 
 
.icon.large.triangle { background-position: -100px 0; } 
 

 
/* styles */ 
 
.icon.info { 
 
    /* based on http://stackoverflow.com/a/25524145/962603, 
 
    * but you can of course also use an SVG filter (heh) */ 
 
    filter: invert(100%) sepia(100%) saturate(50000%) hue-rotate(90deg) brightness(70%); 
 
} 
 
.icon.highlight { 
 
    /* based on http://stackoverflow.com/a/25524145/962603, 
 
    * but you can of course also use an SVG filter (heh) */ 
 
    filter: invert(100%) sepia(100%) saturate(10000%) hue-rotate(30deg) brightness(50%); 
 
}
<span class="icon square"></span> 
 
<span class="icon circle"></span> 
 
<span class="icon triangle"></span> 
 
<span class="icon circle highlight"></span> 
 
<span class="icon triangle large info"></span>

+0

Aww快照。我只是假设我会做'fill:currentColor'等等。这是一个秘密要求,但我没有列出,所以我会给你赏金,但我会更新这个问题。创造性思维! – mpen

+0

这真是太棒了!非常感谢你。我会试着想出一个解决方案,让你做到这一点。我想一种方法是做我建议的,然后使用AJAX加载所有内容并在加载时替换图标?这会很麻烦,虽然... –

+0

我现在正在做类似于现在的事情,但我不喜欢它,因为在AJAX请求完成后,图标会改变颜色。我必须做更多的实验;也许如果我立即在'async'脚本中启动一个AJAX请求来立即加载spritemap,那么FOMI不会那么糟糕。 – mpen

相关问题