带有SVG精灵的图标系统

我一直是图标字体的拥护者。 许多站点确实需要图标系统,而图标字体则提供了一个很好的系统。 但是,我认为假设您对IE 9+很好 ,使用内联SVG和<use>元素引用图标是一个很好的系统。

首先让我们介绍一下它是如何工作的。

处理图标的一种不错的方法是将一个文件夹包含.svg文件。

这是使用SVG的很酷的事情之一-它们源文件。

它们可以是彩色的,而不是彩色的,可以是多种形状,大小,无论如何。

您可以让Illustrator(或其他任何方式)将它保存起来,并将所有附带的内容保存下来:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
	<path d="M50.049,0.3c14.18,0.332,25.969,5.307,35.366,14.923S99.675,36.9,100,51.409c-0.195,11.445-3.415,21.494-9.658,30.146 - yadda yadda yadda"/>
</g>
</svg>

合并.svg文件

您可以根据需要手动执行此操作。 我做完了 您甚至不必查看最终文件。 只需将其命名为svg-defs.svg

它应该只是一个<svg>标记,带有一个<defs>标记(这意味着您正在定义要在以后使用的东西),然后是一堆<g> (组)标记。 每个<g>标签将具有唯一的ID,并将包装每个图标的所有路径和其他内容。

<svg>
  <defs>

    <g id="shape-icon-1">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>

    <g id="shape-icon-2">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>

    <!-- etc -->

  </defs>
</svg>
事实证明, <symbol>可能比<g>更好。 阅读所有关于它的内容!

同样,您可以手动执行此操作,但是这当然有点费力。 Fabrice Weinberg创建了一个名为grunt-svgstore的Grunt插件,可以自动执行此操作。

如果您从未使用过Grunt,则可以这样做。 这是帮助您入门的截屏视频

您可以使用以下方法安装它:

npm install grunt-svgstore --save-dev

确保任务可用于:

grunt.loadNpmTasks('grunt-svgstore');

然后在配置中:

svgstore: {
  options: {
    prefix : 'shape-', // This will prefix each <g> ID
  },
  default : {
      files: {
        'dest/svg-defs.svg': ['svgs/*.svg'],
      }
    }
  }
},

在输出文件svg-defs.svg ,每个图标(无论源.svg文件中的路径和内容如何)都将包装在<g>标记中,并带有唯一的前缀ID和文件名(减去。 svg)。 喜欢:

<g id="shape-codepen">

在文档顶部插入SVG

从字面上包括它,例如:

<!DOCTYPE html>
<html lang="en">

<head>
  ...
</head>

<body>
  <?php include_once("processed/svg-defs.svg"); ?>

或者,但是您想要这样做。

遗憾的是,它必须位于顶部,因为有一个Chrome错误 ,如果稍后定义,它将无法正常工作。 尽管...这个故事还有更多内容,因为在我键入这些单词时,该站点正在使用的主题在文档底部定义了图标,并且可以正常工作。 令人困惑。

随处使用图标

现在您可以在任何地方使用它们了! 喜欢:

<svg viewBox="0 0 100 100" class="icon shape-codepen">
  <use xlink:href="#shape-codepen"></use>
</svg>
注意grunt-svgstore现在正在使用<symbol>因此您甚至不需要使用viewBox!

确保在svg上使用这些类名来调整大小。

/* Do whatever makes sense here.
   Just know that the svg will be an 
   enormous 100% wide if you don't 
   reign in the width. */
.icon {
  display: inline-block;
  width: 25px;
  height: 25px;
}

是的:您可以使用CSS为它们(及其零件)设置样式

我们喜欢图标字体的原因之一是能够使用CSS设置样式。 这种技术的优势在于,我们尽一切所能,甚至更多,因为:

  1. 我们可以为所有单独的部分设置样式
  2. SVG有更多可以控制的功能,例如特殊的滤镜和笔触

svg在DOM中是(kinda),所以JavaScript也是如此。 以下是一些样式化的可能性以及所有这些演示的示例:

请参阅CodePen上的Chris Coyier@chriscoyier )的Pen EBHlD

另一种方式:IcoMoon

以生产图标字体而闻名的IcoMoon实际上在生产SVG精灵方面也做得非常出色。 选择所需的所有字体后,单击底部的SVG按钮,您将获得该输出,包括带有嵌入式SVG方法的演示页。

浏览器支持

在浏览器支持方面,危险区域为IE 8和更低版本,Safari 5和更低版本,iOS 4.3和更低版本以及Android 2.3和更低版本。 但是,如果您的政策是“最后两个主要版本”,那么您将获得几乎100%的支持。

请记住,图标只能用作辅助角色,就像总是附有单词一样。 如果是这样,支持并不是一件大事。 如果它们是独立的,并且不显示将使该站点无法使用,那将是一件大事。

我可能会选择图标字体,因为那里的支持要深得多。 只要确保您做对了

这会变得更好

理想情况下,我们可以做到这一点:

<svg viewBox="0 0 100 100" class="icon shape-codepen">
  <use xlink:href="/images/svg-defs.svg#shape-codepen"></use>
</svg>

这在某些浏览器中确实有效,这意味着您可以跳过文档顶部的包含。 这种方式意味着一个额外的HTTP请求,但这意味着您可以更有效地利用缓存(而不是膨胀的文档缓存)。 在测试中,Jonathan Neal发现您需要在<svg>上具有xmlns属性才能使其工作:

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

但是即使如此,任何IE都没有支持。 除非您想用<object>交换整个<svg><use>否则它将起作用。 乔纳森·尼尔(Jonathan Neal)再次指出

/MSIE|Trident/.test(navigator.userAgent) && document.addEventListener('DOMContentLoaded', function () {
  [].forEach.call(document.querySelectorAll('svg'), function (svg) {
    var use = svg.querySelector('use'); 

    if (use) {
      var object = document.createElement('object');
      object.data = use.getAttribute('xlink:href');
      object.className = svg.getAttribute('class');
      svg.parentNode.replaceChild(object, svg);
    }
  });
});

现在, 他的演示还提供了一种方法,该方法对内容进行Ajax请求并注入,从而使填充可以在IE 9中工作。效率不高,但更像polyfill。

我想有朝一日,直接将<svg><use>链接到.svg会是正确的方法。 甚至<img>可以在SVG上使用URL片段标识符。


浏览器将<use>视为影子DOM:

现在,我们可以使用CSS定位单个<path> ,例如:

.targetting-a-path {
  fill: red;
}

但这将影响该路径的所有实例。 您认为可以做到:

svg.shape-version-2 .targetting-a-path {
  fill: red;
}

但这是行不通的。 它越过了阴影DOM边界。 理想情况下,您将使用“帽子”选择器来打破这一点:

svg.shape-version-2 ^ .targetting-a-path {
  fill: red;
}

但这还不被支持,而且还不清楚它到底是如何工作的。

“ Versus”图标字体

基于向量:领带

CSS样式: SVG精灵略有边缘(目标零件,SVG特定的样式,例如笔触)

奇怪的失败: SVG似乎可以正常工作(受支持时)。 图标字体似乎以奇怪的方式失败。 例如,将字符映射到普通字母,然后字体加载失败,并且随机字符很多。 或者,您映射到“私人使用区”,一些浏览器决定将它们重新映射到像玫瑰一样的真正奇怪的字符 ,但是很难复制。 或者您想将@ font-face文件托管在CDN上,但这是跨域的,Firefox对此很讨厌,因此您需要服务器提供正确的跨域标头,但是Nginx设置却没有正确的选择,SIGH。 SVG赢得了这一大奖。

语义:没什么大不了的,但是我认为<svg>对于图像比<span>更有意义。

辅助功能:也许有人可以告诉我? 我们可以/应该给<svg>一个title属性或其他东西吗? 还是我们在视觉上隐藏的<text>元素? 更新: <title>元素可能起作用 。 或者,可能是此SVG访问规范中使用的<desc>元素。

易于使用: FontelloIcoMoon之类的工具对于图标字体工作流程而言相当不错,但是我认为,带有Grunt的满文件夹的SVG可以更轻松地将 它们 压缩在一起。


伊恩·费瑟(Ian Feather) 发表了一篇文章,介绍了为什么它们也不再使用图标字体,我同意每一点。

翻译自: https://css-tricks.com/svg-sprites-use-better-icon-fonts/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值