圖示
搭配 Material UI 使用圖示的指南與建議。
Material UI 提供三種圖示支援方式
- 透過 Material 圖示 以 React 組件(SVG 圖示)匯出。
- 透過 SvgIcon 組件,自訂 SVG 圖示的 React 包裝器。
- 透過 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
組件。
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',
);
Font Awesome
如果您在使用 @fortawesome/react-fontawesome
中的 FontAwesomeIcon 時發現版面配置問題,您可以嘗試將 Font Awesome SVG 資料直接傳遞給 SvgIcon。
以下是 FontAwesomeIcon
組件和包裝的 SvgIcon
組件的比較。
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 將繼承目前的文字顏色。或者,您可以使用其中一個主題顏色屬性設定圖示顏色:primary
、secondary
、action
、error
和 disabled
。
字型 Material 圖示
Icon
預設會為 Material 圖示字型(filled 變體)設定正確的基底類別名稱。您只需要載入字型,例如透過 Google Web Fonts
<link
rel="stylesheet"
href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
自訂字型
對於其他字型,您可以使用 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 ^^^^^^^^
/>;
全域基底類別名稱
為每個組件用法修改 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
組件搭配使用,如下所示
請注意,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',
},
},
},
},
});
字型 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>