小天同学

怎样构建自己的Icon图标系统

小天同学 · 2017-06-09翻译 · 307阅读 原文链接

有一天我遇到一个问题?

在一个复杂的单页应用中你会选择icon fonts 还是 内联 SVGs 呢?对于这两种方式又有哪些具体的可访问性问题呢?可访问性对我们来说至关重要,因为我们的产品用户是学校。我这样问的目的是,我们正在统一和构建一个Icon图标系统。

我觉得我们不应该根据建设什么样的网站来做出选择,那么我们在做出选择时就忽略我们要建设什么样的项目。

我同样认为SVG图标系统比Icon字体图标 更好 ,我们先这样假设。

可访问性的问题是很有趣的一个点,让我们来看一下。

使用图标有如下两种方式:

  1. 独立的: 图标本身传达想要表达的意思来(就是我们看到一个图标不用文字描述就能知道这个图标的意思)。

  2. 装饰性的: 图标只是一个装饰性的视觉糖(让排版视觉更好看)—— 图标周围的文字去传达想要表达的意思。

独立图标的模式

我用Heather Migliorisi编写的可访问的SVGs来说明这种模式。如下所示:

<!-- role="img" 为了SVG不会被将SVG映射到“组”角色的浏览器遍历 -->
<!-- aria-labelledby 指向 标题和描述的id, 因为我们不这样做的话有些浏览器不能正确的使用它们 -->
<!-- 如果你基于图标系统使用了 <use>标签,你觉得应该在下面生成一个<symbol id="unique-id">标签,其实并不是这样的。 -->
<svg role="img" viewBox="0 0 100 100" aria-labelledby="unique-title-id unique-desc-id">

  <!-- 标题会变成一个阅读辅助技术的工具 -->
  <!-- 必须是第一个子元素! -->
  <title id="unique-title-id">Short Title (e.g. Add to Cart)</title>

  <!-- 如果需要,这里可以写很长的描述信息 -->
  <desc id="unique-desc-id">A friendly looking cartoon cart icon with blinking eyes.</desc>

  <!-- 所有的SVG元素都在这里绘制 -->
  <path d="..." />
</svg>

装饰性图标的模式

对于装饰性的图标你要知道,即使图标不存在也没有任何的影响。所以,我们来把图标隐藏:

<button>
  <svg aria-hidden="true" viewBox="0 0 100 100">
    <!-- 或者是 <use>, 如果基于Icon图标系统使用<symbol>标签的话 -->
    <path d="..." />
  </svg>
  Add to Cart
</button>

但是... 图标应该还有其他的用法吧

恭喜你答对了! 所以你可能要提前准备好一些随时能够被以独立的方式使用的有意义的图标。然后,如果他们被当做装饰性的方式使用时,你需要在<svg>标签上拿掉aria-hidden="true"属性。

所以你的图标系统看起来可能像下面这样...

<Icon icon="icon-cart.svg" standalone="true" />

或者这样

<?php
  $standalone = false;
  include("icon-cart.php"); // PHP逻辑上的SVG
?>

或者这样

<%= render "icon/cart", :locals => {:standalone => true} %>

或者其他样子.

假设你必须要使用字体图标

好戏开场了….

很多的字体图标的用法就像这样:

<i data-icon="a"></i>

或者上面方法的变异,像使用“专用区”的属性值一样或者为每个图标生成一个唯一的类名:

.icon-camera:before {
  content: "\e90f";
}

制作一个独立的图标是很容易的一件事情,你只需要把aria-hidden="true"这个属性加到元素上就可以了。

如果你要制作一个有意义的独立图标。那你就要写更多的HTML了。来自于 Bulletproof Icon Fonts,这是被推荐的一种结构:

<span class="icon-fallback-glyph">
  <span class="icon icon-hamburger" aria-hidden="true"></span>
  <span class="text">Menu</span>
</span>

现在图标本身是被隐藏起来的(因为它用了一种奇怪的无意义的字体),但是那里有可被AT(非传统技术)按预期读取的真实文本存在。你也可以在视觉上隐藏文本。假设你有一些功能测试,下面的CSS是根据需要隐藏/显示的:

.icon-fallback-text .icon {
  display: none;
}
supports-fontface.supports-generatedcontent.icomoon .icon-fallback-text .icon {
  display: inline-block;
}
.supports-fontface.supports-generatedcontent.icomoon .icon-fallback-text .text {
  clip: rect(0 0 0 0);
  overflow: hidden;
  position: absolute;
  height: 1px;
  width: 1px;
}

还记得链接图标吗?

如果一个图标(不管什么类型的图标)是一个链接,你要确保在那里有一个正常的HTML文本,并清楚的知道他要链接到哪,或者你提供一个aria-label

<a href="link" aria-label="See Picked Pens">
  <svg> 
    <use xlink:href="#icon-codepen"></use>
  </svg>
</a>
相关文章