跳到主要內容
+

圖示

搭配 Material UI 使用圖示的指南與建議。

Material UI 提供三種圖示支援方式

  1. 透過 Material 圖示 以 React 組件(SVG 圖示)匯出。
  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';
    

對於套件大小而言,選項 1 最安全,但有些開發人員偏好選項 2。在使用第二種方法之前,請務必遵循最小化套件大小指南

每個 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
  • Twotone 主題匯出為 @mui/icons-material/DeleteTwoTone
  • Sharp 主題匯出為 @mui/icons-material/DeleteSharp

Filled

Outlined

Rounded

Two Tone

Sharp

邊緣案例

SvgIcon

如果您需要自訂 SVG 圖示(在 Material 圖示 中不可用),您可以使用 SvgIcon 包裝器。此組件擴展了原生 <svg> 元素

  • 它內建了無障礙功能。
  • SVG 元素應針對 24x24 像素的視窗縮放,以便產生的圖示可以直接使用,或包含為使用圖示的其他 Material UI 組件的子項。可以使用 viewBox 屬性自訂此設定。若要從原始圖片繼承 viewBox 值,可以使用 inheritViewBox 屬性。
  • 預設情況下,組件會繼承目前的顏色。或者,您可以使用 color 屬性套用其中一個主題顏色。
  • 它支援 <svg> 元素作為子項,因此您可以直接複製並貼上 SVG 到 SvgIcon 組件。
按下 Enter 開始編輯
按下 Enter 開始編輯
按下 Enter 開始編輯

Component 屬性

即使您的圖示儲存為 .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> 元素或 SVG 路徑,這些元素或路徑作為子項傳遞給SvgIcon 組件。

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 圖示字型。若要使用圖示,只需使用 Icon 組件包裝圖示名稱(字型連字),例如

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

<Icon>star</Icon>;

預設情況下,Icon 將繼承目前的文字顏色。或者,您可以使用其中一個主題顏色屬性設定圖示顏色:primarysecondaryactionerrordisabled

字型 Material 圖示

Icon 預設會為 Material 圖示字型(filled 變體)設定正確的基底類別名稱。您只需要載入字型,例如透過 Google Web Fonts

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
按下 Enter 開始編輯

自訂字型

對於其他字型,您可以使用 baseClassName 屬性自訂基底類別名稱。例如,您可以使用 Material Design 顯示雙色調圖示

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',
      },
    },
  },
});

然後,您可以直接使用雙色調字型

<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',
        },
      },
    },
  },
});
Call me
Call me
按下 Enter 開始編輯

字型 vs. 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

請參閱以下文件,以取得此處提及的組件可用的所有屬性和類別的完整參考。