跳到内容
+

图标

使用 Material UI 图标的指南和建议。

Material UI 通过三种方式提供图标支持

  1. 通过导出为 React 组件(SVG 图标)的 Material 图标
  2. 通过 SvgIcon 组件,一个用于自定义 SVG 图标的 React 包装器。
  3. 通过 Icon 组件,一个用于自定义字体图标的 React 包装器。

Material SVG 图标

Google 创建了超过 2,100 个官方 Material 图标,每个图标有五种不同的“主题”(见下文)。对于每个 SVG 图标,我们从 @mui/icons-material 包中导出相应的 React 组件。您可以搜索这些图标的完整列表

安装

运行以下命令之一来安装它并将其保存到您的 package.json 依赖项中

npm install @mui/icons-material

这些组件使用 Material UI SvgIcon 组件来渲染每个图标的 SVG 路径,因此对 @mui/material 具有对等依赖。

如果您的项目中尚未使用 Material UI,您可以按照安装指南添加它。

用法

使用以下两个选项之一导入图标

  • 选项 1

    import AccessAlarmIcon from '@mui/icons-material/AccessAlarm';
    import ThreeDRotation from '@mui/icons-material/ThreeDRotation';
    
  • 选项 2

    import { AccessAlarm, ThreeDRotation } from '@mui/icons-material';
    

对于 bundle 大小而言,选项 1 是最安全的,但一些开发者更喜欢选项 2。在使用第二种方法之前,请确保您遵循最小化 bundle 大小指南

每个 Material 图标也都有一个“主题”:Filled(默认)、Outlined、Rounded、Two-tone 和 Sharp。要导入具有默认主题以外主题的图标组件,请将主题名称附加到图标名称。例如,具有以下主题的 @mui/icons-material/Delete 图标:

  • Filled 主题(默认)导出为 @mui/icons-material/Delete,
  • Outlined 主题导出为 @mui/icons-material/DeleteOutlined,
  • Rounded 主题导出为 @mui/icons-material/DeleteRounded,
  • Two-tone 主题导出为 @mui/icons-material/DeleteTwoTone,
  • Sharp 主题导出为 @mui/icons-material/DeleteSharp

Filled

Outlined

Rounded

Two Tone

Sharp

边缘情况

SvgIcon

如果您需要自定义 SVG 图标(在 Material 图标中不可用),您可以使用 SvgIcon 包装器。此组件扩展了原生 <svg> 元素

  • 它具有内置的可访问性。
  • SVG 元素应缩放为 24x24px 视口,以便生成的图标可以直接使用,或作为子元素包含在其他使用图标的 Material UI 组件中。可以使用 viewBox 属性自定义此设置。要从原始图像继承 viewBox 值,可以使用 inheritViewBox 属性。
  • 默认情况下,组件继承当前颜色。可选地,您可以使用 color 属性应用主题颜色之一。
  • 它支持 <svg> 元素作为子元素,因此您可以直接将 SVG 复制并粘贴到 SvgIcon 组件中。
Enter 开始编辑
Enter 开始编辑
Enter 开始编辑

组件属性

即使您的图标以 .svg 格式保存,您也可以使用 SvgIcon 包装器。svgr 具有加载器,用于导入 SVG 文件并将它们用作 React 组件。例如,使用 webpack

// webpack.config.js
{
  test: /\.svg$/,
  use: ['@svgr/webpack'],
}

// ---
import StarIcon from './star.svg';

<SvgIcon component={StarIcon} inheritViewBox />

也可以将其与“url-loader”或“file-loader”一起使用。这是 Create React App 使用的方法。

// webpack.config.js
{
  test: /\.svg$/,
  use: ['@svgr/webpack', 'url-loader'],
}

// ---
import { ReactComponent as StarIcon } from './star.svg';

<SvgIcon component={StarIcon} inheritViewBox />

createSvgIcon

createSvgIcon 实用程序组件用于创建 Material 图标。它可用于包装 <svg> 元素或作为子元素传递给 SvgIcon 组件的 SVG 路径。

const HomeIcon = createSvgIcon(
  <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />,
  'Home',
);

// or with custom SVG
const PlusIcon = createSvgIcon(
  <svg
    xmlns="http://www.w3.org/2000/svg"
    fill="none"
    viewBox="0 0 24 24"
    strokeWidth={1.5}
    stroke="currentColor"
    className="h-6 w-6"
  >
    <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
  </svg>,
  'Plus',
);
Enter 开始编辑

Font Awesome

如果您发现从 @fortawesome/react-fontawesome 使用 FontAwesomeIcon 时存在布局问题,您可以尝试将 Font Awesome SVG 数据直接传递给 SvgIcon。

以下是 FontAwesomeIcon 组件和包装的 SvgIcon 组件的比较。

Enter 开始编辑

FontAwesomeIcon 的 fullWidth 属性也可用于近似正确的尺寸,但它并不完美。

其他库

MDI

materialdesignicons.com 提供了超过 2,000 个图标。对于所需的图标,复制他们提供的 SVG path,并将其用作 SvgIcon 组件的子元素,或与 createSvgIcon() 一起使用。

注意:mdi-material-ui 已经使用 SvgIcon 组件包装了这些 SVG 图标中的每一个,因此您无需自己进行操作。

Icon (字体图标)

Icon 组件将显示来自任何支持连字的字体图标的图标。作为先决条件,您必须包含一个,例如您项目中的 Material Icons 字体。要使用图标,只需使用 Icon 组件包装图标名称(字体连字),例如

import Icon from '@mui/material/Icon';

<Icon>star</Icon>;

默认情况下,Icon 将继承当前文本颜色。可选地,您可以使用主题颜色属性之一设置图标颜色:primarysecondaryactionerrordisabled

字体 Material 图标

Icon 默认情况下将为 Material Icons 字体(filled 变体)设置正确的基类名称。您所需要做的就是加载字体,例如,通过 Google Web Fonts

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
Enter 开始编辑

自定义字体

对于其他字体,您可以使用 baseClassName 属性自定义基线类名称。例如,您可以使用 Material Design 显示 two-tone 图标

import Icon from '@mui/material/Icon';

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Material+Icons+Two+Tone"
  // Import the two tones MD variant                           ^^^^^^^^
/>;
Enter 开始编辑

全局基类名称

为每个组件用法修改 baseClassName 属性是重复的。您可以使用主题全局更改默认属性

const theme = createTheme({
  components: {
    MuiIcon: {
      defaultProps: {
        // Replace the `material-icons` default value.
        baseClassName: 'material-icons-two-tone',
      },
    },
  },
});

然后,您可以直接使用 two-tone 字体

<Icon>add_circle</Icon>

Font Awesome

Font Awesome 可以与 Icon 组件一起使用,如下所示

Enter 开始编辑

请注意,Font Awesome 图标的设计方式与 Material 图标不同(比较之前的两个演示)。fa 图标被裁剪以使用所有可用空间。您可以使用全局覆盖来调整此设置

const theme = createTheme({
  components: {
    MuiIcon: {
      styleOverrides: {
        root: {
          // Match 24px = 3 * 2 + 1.125 * 16
          boxSizing: 'content-box',
          padding: 3,
          fontSize: '1.125rem',
        },
      },
    },
  },
});
呼叫我
呼叫我
Enter 开始编辑

字体与 SVG:应使用哪种方法?

两种方法都可以正常工作,但是,在性能和渲染质量方面存在一些细微的差异。在可能的情况下,首选 SVG,因为它允许代码拆分,支持更多图标,并且渲染速度更快、质量更高。

有关更多详细信息,请查看 GitHub 为什么从字体图标迁移到 SVG 图标

可访问性

图标可以传达各种有意义的信息,因此确保它们在适当的情况下可访问非常重要。您需要考虑两种用例

  • 装饰性图标仅用于视觉或品牌强化。如果从页面中删除它们,用户仍然可以理解并能够使用您的页面。
  • 语义图标是您用于传达含义的图标,而不仅仅是纯粹的装饰。这包括旁边没有文本的图标,这些图标用作交互式控件——按钮、表单元素、切换等。

装饰性图标

如果您的图标纯粹是装饰性的,那么您已经完成了!添加了 aria-hidden=true 属性,以便您的图标可以正确访问(不可见)。

语义图标

语义 SVG 图标

您应该包含具有有意义值的 titleAccess 属性。添加了 role="img" 属性和 <title> 元素,以便您的图标可以正确访问。

在可聚焦的交互式元素的情况下,例如当与图标按钮一起使用时,您可以使用 aria-label 属性

import IconButton from '@mui/material/IconButton';
import SvgIcon from '@mui/material/SvgIcon';

// ...

<IconButton aria-label="delete">
  <SvgIcon>
    <path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z" />
  </SvgIcon>
</IconButton>;

语义字体图标

您需要提供仅对辅助技术可见的文本替代方案。

import Box from '@mui/material/Box';
import Icon from '@mui/material/Icon';
import { visuallyHidden } from '@mui/utils';

// ...

<Icon>add_circle</Icon>
<Box component="span" sx={visuallyHidden}>Create a user</Box>

参考

API

请参阅下面的文档,以获取此处提及的组件可用的所有属性和类的完整参考。