mat-icon 让你在应用中使用矢量图标变得更容易。 该指令支持字体图标和 SVG 图标,但不支持位图格式(png、jpg 等)。

MatIconRegistry 是一个可注入的服务,它允许你把图标名称和 SVG 的 URL、HTML 字符串 关联起来,还可以为 CSS 字体类定义别名。 具体方式稍后会进行讨论,并列在 API 摘要中。

有些字体是设计来用合字的方式显示图标的,比如把文本格式的 "home" 显示为家的图标。要使用合字图标,请把它对应的文本放进 mat-icon 组件的内容中。

默认情况下, <mat-icon> 预期使用 Material 图标字体。 (你仍然需要包含 HTML 来加载字体及其 CSS,如链接中所述)。

你可以指定不同的字体,例如 Material 的最新图标, Material Symbols,方法是将 fontSet 输入设置为要应用的 CSS 类以使用所需的字体,或设置为之前使用 MatIconRegistry.registerFontClassAlias 注册的别名。或者,你可以使用 MatIconRegistry.setDefaultFontSetClass 为应用程序的所有图标设置默认值。

字体还可以通过为每个图标字符定义 CSS 类来显示图标,它通常使用 :before 选择器来显示图标。 FontAwesome 就是通过这种方式显示图标的。 要使用这类字体,请把输入属性 fontSet 设置为该字体的 CSS 类(或者它本身的定义类或者通过 MatIconRegistry.registerFontClassAlias 注册的别名),并且把输入属性 fontIcon 设置为要显示的图标的专有类。

无论对于哪种字体图标,你都可以通过调用 MatIconRegistry.setDefaultFontSetClass 来指定一个默认字体类。当没有指定 fontSet 时就会使用它。

<mat-icon> 会把 SVG 内容直接内联到 DOM 中,作为自己的子级,来显示 SVG 图标。这种方法比 <img> 标签或 CSS background-image 更有优势,因为它允许使用 CSS 来为 SVG 指定样式。例如,SVG 内容的默认颜色是 CSS 的 currentColor 值。这会使 SVG 图标默认使用与周围文本相同的颜色,并让你能通过设置 mat-icon 元素 color 样式来改变其颜色。

为了防范 XSS 漏洞,传给 MatIconRegistry 的 SVG URL 和 HTML 字符串都必须使用 Angular 的 DomSanitizer 服务标记为可信的。

MatIconRegistry 通过 Angular 的 HttpClient 服务获取所有的远程 SVG 图标。如果你没有在 NgModuleimports 里包含 @angular/common/http 包里 HttpClientModule,那么运行时就会出错。

注意,HttpClient 要借助 XmlHttpRequest 来获取通过 URL 注册的 SVG 图标,它必须遵循同源策略。这意味着图标的 URL 必须与容器页面具有相同的源,或者必须将该应用服务器配置为允许跨域请求。

要把一个名字和图标的 URL 关联起来,请使用 MatIconRegistryaddSvgIconaddSvgIconInNamespaceaddSvgIconLiteraladdSvgIconLiteralInNamespace 方法。 在注册了图标之后,它可以通过设置输入属性 svgIcon 进行显示。 对于默认命名空间中的图标,可以直接使用其名字。对于非默认命名空间,可以使用 [namespace]:[name] 格式。

图标集允许把多个图标分组到一个单一的 SVG 文件中。它可以通过创建一个单根 <svg> 标记来完成,该标记在其 <defs> 部分包含多个内嵌的 <svg> 标记。 每个内嵌标记都带有一个 id 属性,该属性就会用作图标的名字。

图标集使用 MatIconRegistryaddSvgIconSetaddSvgIconSetInNamespaceaddSvgIconSetLiteraladdSvgIconSetLiteralInNamespace 方法进行注册。 当注册了图标集之后,每个内嵌的图标都可以通过它们的 id 属性进行访问。要显示图标集中的某个图标, 只要像单独注册的图标那样使用输入属性 svgIcon 就可以了。

多个图标集可以注册进同一个命名空间。如果一个图标的 id 出现在多个图标集中,就会使用最近注册的图标集中的图标。

默认情况下,图标会使用当前字体颜色(currentColor)。该颜色可以使用 color 属性设置为当前主题中的颜色。 它可以修改为 'primary''accent''warn' 之一。

像任何 <img> 元素一样,图标本身并不会想屏幕阅读器用户传达任何有用的信息。 <mat-icon> 的使用者必须提供一些关于本图标用途的额外信息。根据稍后描述的用例,mat-icon 默认标记为 aria-hidden="true",但是可以通过网元素上添加 aria-hidden="false" 来覆盖默认行为。

在考察无障碍性时,可以将图标归入下面三种类别之一:

  1. 装饰性的:该图标不传达有意义的信息,是个纯粹的点缀。
  2. 交互式的:用户会点击它或用其它方式与此图标互动以执行某些操作。
  3. 指示符:该图标不是交互式的,但传达某些信息,比如状态。这种情况也包括在大型消息的文本中使用图标。

当该图标纯粹是点缀,并且没有传达有意义的信息时,<mat-icon> 元素要标记为 aria-hidden="true"

图标本身对屏幕阅读器用户不是交互式元素。当用户要和页面中的某个图标交互时,应该让更合适的元素来负责交互:

如果某个图标的存在是为了给用户传达一些信息,那么无论它是作为指示符还是内联到文本块中,该信息都必须可以供屏幕阅读器使用。最直接的实现方式有:

  1. <mat-icon> 元素添加一个相邻的兄弟 <span>,用它传达与图标相同的信息。
  2. <span> 添加一个 cdk-visually-hidden 类,这会导致在屏幕上看不见该信息,但屏幕阅读器用户仍然可以读取它。

默认情况下,在 RTL 布局下的图标和 LTR 布局下是完全一样的,不过某些图标必须为 RTL 用户进行镜像处理。 如果你只想在 RTL 布局下镜像某个图标,可以使用 mat-icon-rtl-mirror 类。

<mat-icon class="mat-icon-rtl-mirror" svgIcon="thumb-up"></mat-icon>