跳转到内容

Breakpoints 断点

API 解锁了各种情况下断点的使用。

为了获得最佳的用户体验,在不同的断点下,material design 的接口需要适应它们的布局。 Material-UI 使用了原先 specification简化 实现。

不同组件内部也使用了断点来实现响应式的布局,同时借助于 GridHidden 组件,你也可以用其来控制应用的布局。

默认的断点

每个断点(一个键)匹配一个固定的屏幕宽度(一个值):

  • ** xs, ** 超小:0px
  • ** sm, **小:600px
  • ** md, **中等:960px
  • ** lg, **大:1280px
  • ** xl, **超大:1920px

这些值可以是 定制 的。

CSS 媒体查询(Media queries)

CSS media queries 是一种做出响应式的用户界面的特有方法。 而 theme 提供了四种样式的辅助方式:

在下面的演示中,我们根据屏幕宽度来更改背景颜色 (红色、蓝色和绿色)。

const styles = (theme) => ({
  root: {
    padding: theme.spacing(1),
    [theme.breakpoints.down('md')]: {
      backgroundColor: theme.palette.secondary.main,
    },
    [theme.breakpoints.up('md')]: {
      backgroundColor: theme.palette.primary.main,
    },
    [theme.breakpoints.up('lg')]: {
      backgroundColor: green[500],
    },
  },
});

down(sm): red

up(md): blue

up(lg): green

<Root>
  <Typography>{'down(sm): red'}</Typography>
  <Typography>{'up(md): blue'}</Typography>
  <Typography>{'up(lg): green'}</Typography>
</Root>

JavaScript 媒体查询

有的时候,仅使用 CSS 是远远不够的。 您可能会有基于 JavaScript 中的断点值来更改 React 渲染树的需求。

useMediaQuery hook

您可以在 userMediaQuery 页面上了解更多信息。

withWidth()

⚠️ 有了 useMediaQuery hook,这个高阶组件(higher-order component)将被弃用。

import withWidth from '@material-ui/core/withWidth';

function MyComponent(props) {
  return <div>{`当前宽度: ${props.width}`}</div>;
}

export default withWidth()(MyComponent);

您可以在 userMediaQuery 页面上了解更多信息。

⚠️ Missing demo `pages/customization/breakpoints/WithWidth.js` ⚠️

自定义断点

您可以选择在 theme 中的 theme.breakpoints 部分定义项目的断点。

  • theme.breakpoints.values:默认为 以上值。 键值(key)为屏幕的名字(screen names),而值(values)是该断点应开始的最小宽度。
  • theme.breakpoints.unit:默认为 px。 这个用于断点值的单位。
  • theme.breakpoints.step:默认为 5 (0.05px)。 这个增量用于实现专用的断点。

如果您需要更改断点的默认值,则需要提供所有的断点值:

const theme = createTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 600,
      md: 960,
      lg: 1280,
      xl: 1920,
    },
  },
});

您可以随意设置任意数量的断点,并且也可以在项目中以您喜欢的任何方式为断点命名。

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

如果您使用的是 TypeScript,您还需要使用 module augmentation 来让主题接受上述值。

declare module "@material-ui/core/styles/createBreakpoints" {
  interface BreakpointOverrides {
    xs: false; // 移除 `xs` 断点
    sm: false;
    md: false;
    lg: false;
    xl: false;
    tablet: true; // 添加 `tablet` 断点
    laptop: true;
    desktop: true;
  }
}

API

theme.breakpoints.up(key) => media query

参数

  1. keyString | Number ):断点键(xssm等等)或以像素为单位的屏幕宽度数。

返回结果

如果您使用的是 TypeScript,您还需要使用 module augmentation 来让主题接受上述值。

例子

const styles = (theme) => ({
  root: {
    backgroundColor: 'blue',
    // Match [md, ∞)
    //       [960px, ∞)
    [theme.breakpoints.up('md')]: {
      backgroundColor: 'red',
    },
  },
});

theme.breakpoints.down(key) => media query

参数

  1. keyString | Number ):断点键(xssm等等)或以像素为单位的屏幕宽度数。

返回结果

media query:一个媒体查询字符串,适用于大多数的样式解决方案,它匹配的屏幕宽度大于(包含)断点键给出的屏幕尺寸。

例子

const styles = (theme) => ({
  root: {
    backgroundColor: 'blue',
    // Match [0, md)
    //       [0, 960px)
    [theme.breakpoints.down('md')]: {
      backgroundColor: 'red',
    },
  },
});

theme.breakpoints.only(key) => media query

参数

  1. keyString):断点键(xssm等)。

返回结果

media query:一个媒体查询字符串,适用于大多数的样式解决方案,它匹配的屏幕宽度小于(不包含)断点键给出的屏幕尺寸。

例子

const styles = (theme) => ({
  root: {
    backgroundColor: 'blue',
    // Match [md, md + 1)
    //       [md, lg)
    //       [960px, 1280px)
    [theme.breakpoints.only('md')]: {
      backgroundColor: 'red',
    },
  },
});

theme.breakpoints.between(start, end) => media query

参数

  1. start (String): A breakpoint key (xs, sm, etc.) or a screen width number in pixels.
  2. end (String): A breakpoint key (xs, sm, etc.) or a screen width number in pixels.

返回结果

media query:一个媒体查询字符串,适用于大多数的样式解决方案,它会匹配屏幕宽度,并包括断点键给出的屏幕尺寸。

例子

const styles = (theme) => ({
  root: {
    backgroundColor: 'blue',
    // Match [sm, md)
    //       [600px, 960px)
    [theme.breakpoints.between('sm', 'md')]: {
      backgroundColor: 'red',
    },
  },
});

withWidth([options]) => higher-order component

注入 width 属性。 它不会修改传递给它的组件;相反,它会返回一个新组件。 这个 width 断点属性与当前屏幕宽度匹配。 它可以是以下断点之一:

type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

你可能会注意到一些有趣的细节:

  • 它将转发 非 React 的静态 属性,以便 HOC 更 "透明"。 例如,您可以用它来定义一个 getInitialProps() 的静态方法 (next.js)。

参数

  1. options (Object [optional]):
  • options.withTheme (Boolean [optional]): 默认值为 false。 将 theme 对象作为属性提供给组件。
  • options.noSSR (Boolean [optional]): 默认值为 false。 为了呈现服务器端渲染的协调性,我们需要将它渲染两次。 第一次什么也没渲染,第二次与子组件一起渲染。 这个双向渲染周期带有一个缺点。 UI 会有闪烁。 如果你不进行服务器端渲染,那么可以将此标志设置为 true
  • options.initialWidthBreakpoint [可选的]): 为window.innerWidth在服务器上不可用, 我们默认在第一次安装期间呈现空组件。 你可能需要使用一个启发式方法来估计客户端浏览器的屏幕宽度。 例如,你可以使用 user-agent 或 client-hints。 为了设置 initialWidth,我们需要传递一个类似于以下结构的自定义属性: 我们也可以在主题中使用 自定义属性 来设置全局的初始宽度。
const theme = createTheme({
  components: {
    // withWidth component ⚛️
    MuiWithWidth: {
      defaultProps: {
        // Initial width prop
        initialWidth: 'lg', // 断点的全局设置 🌎!
      },
    },
  },
});
  • options.resizeInterval (Number [optional]):默认为 166,对应于 60 Hz 的 10帧。 响应屏幕调整大小事件前等待的毫秒数。

返回结果

higher-order component:应用于包装组件。

例子

import withWidth, { isWidthUp } from '@material-ui/core/withWidth';

function MyComponent(props) {
  if (isWidthUp('sm', props.width)) {
    return <span />;
  }

  return <div />;
}

export default withWidth()(MyComponent);

默认值

您可以使用 主题资源管理器(theme explorer) 或通过打开此页面上的开发工具控制台(dev tools console)(window.theme.breakpoints)来探索断点的一些默认值。