跳到主要內容
+

用法

學習使用 MUI System 及其工具的基本知識。

為何使用 MUI System?

MUI System 的 sx 屬性讓您避免編寫不必要的 styled-component 程式碼,而是直接在元件本身內定義樣式。這對於具有自訂設計的一次性元件特別有用。

以下程式碼範例說明 styled-components 和 sx 之間的差異

工作階段
98.3 K
18.7%
與上週相比
  1. 使用 styled-components API
const StatWrapper = styled('div')(
  ({ theme }) => `
  background-color: ${theme.palette.background.paper};
  box-shadow: ${theme.shadows[1]};
  border-radius: ${theme.shape.borderRadius}px;
  padding: ${theme.spacing(2)};
  min-width: 300px;
`,
);

const StatHeader = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.secondary};
`,
);

const StyledTrend = styled(TrendingUpIcon)(
  ({ theme }) => `
  color: ${theme.palette.success.dark};
  font-size: 16px;
  vertical-alignment: sub;
`,
);

const StatValue = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.primary};
  font-size: 34px;
  font-weight: ${theme.typography.fontWeightMedium};
`,
);

const StatDiff = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.success.dark};
  display: inline;
  font-weight: ${theme.typography.fontWeightMedium};
  margin-left: ${theme.spacing(0.5)};
  margin-right: ${theme.spacing(0.5)};
`,
);

const StatPrevious = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.secondary};
  display: inline;
  font-size: 12px;
`,
);

return (
  <StatWrapper>
    <StatHeader>Sessions</StatHeader>
    <StatValue>98.3 K</StatValue>
    <StyledTrend />
    <StatDiff>18.77%</StatDiff>
    <StatPrevious>vs last week</StatPrevious>
  </StatWrapper>
);
  1. 使用 MUI System
<Box
  sx={{
    bgcolor: 'background.paper',
    boxShadow: 1,
    borderRadius: 1,
    p: 2,
    minWidth: 300,
  }}
>
  <Box sx={{ color: 'text.secondary' }}>Sessions</Box>
  <Box sx={{ color: 'text.primary', fontSize: 34, fontWeight: 'medium' }}>
    98.3 K
  </Box>
  <Box
    component={TrendingUpIcon}
    sx={{ color: 'success.dark', fontSize: 16, verticalAlign: 'sub' }}
  />
  <Box
    sx={{ color: 'success.dark', display: 'inline', fontWeight: 'medium', mx: 0.5 }}
  >
    18.77%
  </Box>
  <Box sx={{ color: 'text.secondary', display: 'inline', fontSize: 12 }}>
    vs. last week
  </Box>
</Box>

sx 屬性

MUI System 的核心工具是 sx 屬性,它為您提供了一種快速有效的方式,將正確的設計令牌直接應用於 React 元素。

此屬性提供 CSS 的超集(也就是說,它包含所有 CSS 屬性和選擇器,以及自訂的屬性和選擇器),這些值直接從主題對應而來,具體取決於使用的 CSS 屬性。它還通過參考主題中定義的斷點,簡化了定義響應式值的過程。

請訪問 sx 屬性頁面 了解完整詳細資訊。

響應式示範

以下示範展示了如何使用 sx 屬性來應用自訂樣式,並僅使用 Box 包裝器建立複雜的 UI 元件。調整視窗大小以查看響應式斷點

The house from the offer.
123 Main St, Phoenix AZ$280,000 — $310,000
信心評分:85%
按下 Enter 鍵開始編輯

何時使用 MUI System

sx 屬性最適合將一次性樣式應用於自訂元件。

這與 styled-components API 形成對比,後者非常適合構建需要在各種上下文中支援的元件。這些元件在應用程式的許多不同部分中使用,並支援不同的屬性組合。

效能權衡

MUI System 依賴 CSS-in-JS。它可以與 Emotion 和 styled-components 一起使用。

優點

  • 📚 sx 屬性使用 CSS 的超集,因此如果您已經了解 CSS,則語法會立即讓您感到熟悉。它還提供(可選的)速記定義,如果您花一些時間預先學習它們,可以節省您的時間。這些都記錄在左側主導航欄的樣式工具部分中。
  • 📦 System 自動清除,因此只有頁面上使用的 CSS 會發送到用戶端。初始捆綁包大小成本是固定的——隨著您添加更多 CSS 屬性,它不會變得更大。您需要支付 @emotion/react@mui/system 的成本。總大小約為 15 kB (gzip 壓縮)。但是,如果您已經在使用像 Material UI 這樣的 MUI Core 元件庫,那麼它不會帶來額外的開銷。

缺點

執行時效能會受到影響。

基準測試案例 程式碼片段 時間正規化
a. 渲染 1,000 個原始元件 <div className="…"> 100 毫秒
b. 渲染 1,000 個元件 <Div> 112 毫秒
c. 渲染 1,000 個 styled components <StyledDiv> 181 毫秒
d. 渲染 1,000 個 Box <Box sx={…}> 296 毫秒

請訪問 基準測試資料夾 以重現上述指標。

我們相信對於大多數用例來說,它已經足夠快了,但是當效能變得至關重要時,有一些簡單的解決方法。例如,當渲染包含許多項目的列表時,您可以使用 CSS 子選擇器來擁有單個「樣式注入」點(wrapper 使用 d.,每個項目使用 a.)。

API 權衡

MUI System 統一的 sx 屬性有助於保持 CSS 工具和元件業務邏輯之間關注點的分離。

例如,按鈕上的 color 屬性會影響多個狀態(hover、focus 等),並且與 CSS color 屬性不同。

僅有 BoxStackTypographyGrid 元件出於此原因接受 MUI System 屬性作為 props。這些元件旨在解決 CSS 問題——它們是 CSS 元件工具。

何處使用 MUI System

sx 屬性可用於四個不同的位置

核心元件

所有 Material UI 和 Joy UI 元件都支援 sx 屬性。

Box

Box 是一個輕量級元件,可讓您存取 sx 屬性,並且可以用作實用元件,以及其他元件的包裝器。它預設渲染 <div> 元素。

自訂元件

除了 MUI System 元件之外,您也可以將 sx 屬性添加到您的自訂元件中,方法是使用 @mui/material/styles 中的 styled 工具。

import { styled } from '@mui/material/styles';

const Div = styled('div')``;

任何帶有 babel 插件的元素

請訪問 關於此主題的未解決 GitHub issue 以了解更多資訊。

如何使用 MUI System

主題中的設計令牌

請訪問 System 屬性頁面 了解不同的 CSS(和自訂)屬性如何映射到主題鍵。

速記

許多 CSS 屬性都有可用的速記。這些都記錄在其各自的樣式工具頁面上。以下是一些範例

<Box
  sx={{  boxShadow: 1, // theme.shadows[1]
    color: 'primary.main', // theme.palette.primary.main
    m: 1, // margin: theme.spacing(1)
    p: {
      xs: 1, // [theme.breakpoints.up('xs')]: { padding: theme.spacing(1) }
    },
    zIndex: 'tooltip', // theme.zIndex.tooltip
  }}
>

這些速記是可選的——它們非常適合節省時間,但並非必須使用

CSS 的超集

sx 屬性支援 CSS 語法,包括子選擇器和偽選擇器、媒體查詢、原始 CSS 值等等。以下是一些如何實作這些 CSS 功能的範例

  • 使用偽選擇器

    <Box
      sx={{    // some styles
        ":hover": {
          boxShadow: 6,
        },
      }}
    >
    
  • 使用媒體查詢

    <Box
      sx={{    // some styles
        '@media print': {
          width: 300,
        },
      }}
    >
    
  • 使用巢狀選擇器

    <Box
      sx={{    // some styles
        '& .ChildSelector': {
          bgcolor: 'primary.main',
        },
      }}
    >
    

響應式值

sx 屬性簡化了定義和實作響應式斷點的過程。您可以通過兩種不同的方式定義一組斷點:作為物件或作為陣列。

斷點作為物件

斷點的第一個選項是將它們定義為物件,使用斷點值作為鍵。請注意,給定斷點的每個屬性也適用於集合中所有更大的斷點。例如,width: { lg: 100 } 等同於 theme.breakpoints.up('lg')

以下示範展示了如何使用物件語法定義一組斷點

此方塊具有響應式寬度。
按下 Enter 鍵開始編輯

速記語法為 @{breakpoint}/{container}

  • breakpointpx 單位的數字或斷點鍵(例如 smmdlgxl 用於預設斷點)或有效的 CSS 值(例如 40em)。
  • container(可選):容器上下文 的名稱。
The house from the offer.
123 Main St, Phoenix AZ
$280,000 — $310,000
信心評分:85%

斷點作為陣列

第二個選項是將您的斷點定義為陣列,從最小到最大。以下是它的外觀

此方塊具有響應式寬度。
按下 Enter 鍵開始編輯

您可以使用 null 值跳過斷點

<Box sx={{ width: [null, null, 300] }}>This box has a responsive width.</Box>

自訂斷點

您還可以指定自己的自訂斷點,並在定義斷點物件時將其用作鍵。以下是如何執行此操作的範例

import * as React from 'react';
import Box from '@mui/material/Box';
import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  breakpoints: {
    values: {
      mobile: 0,
      tablet: 640,
      laptop: 1024,
      desktop: 1280,
    },
  },
});

export default function CustomBreakpoints() {
  return (
    <ThemeProvider theme={theme}>
      <Box
        sx={{
          width: {
            mobile: 100,
            laptop: 300,
          },
        }}
      >
        This box has a responsive width
      </Box>
    </ThemeProvider>
  );
}

如果您正在使用 TypeScript,您還需要使用 模組擴充,以便主題接受上述值。

declare module '@mui/material/styles' {
  interface BreakpointOverrides {
    xs: false; // removes the `xs` breakpoint
    sm: false;
    md: false;
    lg: false;
    xl: false;
    tablet: true; // adds the `tablet` breakpoint
    laptop: true;
    desktop: true;
  }
}

主題 getter

如果您希望將主題用於 MUI System 本身不支援的 CSS 屬性,那麼您可以使用函數作為值,您可以在其中存取主題物件。以下示範展示了其工作原理

帶有主題值的邊框顏色。
按下 Enter 鍵開始編輯