跳转到内容

样式库的互通性

虽然你可以使用 Material-UI 提供的基于 emotion 的样式解决方案来自定义你的应用程序,但你也可以使用你已知和喜欢的方案(从普通的 CSS 到 styled-components)。

本指南旨在归档当前比较流行的一些替代方案,但是您会发现在这里运用的法则,也可以在其他库里适用。 我们为以下的样式方案提供了一些示例:

纯 CSS

没有什么特别花哨的,只是纯 CSS。

编辑按钮

PlainCssSlider.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

PlainCssSlider.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import './PlainCssSlider.css';

export default function PlainCssSlider() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider defaultValue={30} className="slider" />
    </div>
  );
}

CSS 注入顺序⚠️

注意: 大多数的 CSS-in-JS 解决方案是在 HTML <head> 的底部注入它们的样式,这会导致你的自定义样式被 Material-UI 的样式规则所覆盖。 如果你有移除 !important 的需求,那么就需要改变 CSS 注入顺序。 Here's a demo of how it can be done in Material-UI:

import * as React from 'react';
import { StylesProvider } from '@material-ui/core';

export default function GlobalCssPriority() {
  return (
    <StylesProvider injectFirst>
      {/* Your component tree. 现在你可以覆盖 Material-UI 的样式。 */}
    </StylesProvider>
  );
}

Note: If you are using emotion and have a custom cache in your app, that one will override the one coming from Material-UI. In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例: In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例:

import * as React from 'react';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';

const cache = createCache({
  key: 'css',
  prepend: true,
});

export default function PlainCssPriority() {
  return (
    <CacheProvider value={cache}>
      {/* Your component tree. 现在你可以覆盖 Material-UI 的样式。 */}
    </CacheProvider>
  );
}

Note: If you are using styled-components and have StyleSheetManager with a custom target, make sure that the target is the first element in the HTML <head>. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package.

更深层的元素

如果你试图自定义滑块的样式,那么很可能会影响到滑块的一些子元素,例如滚动条的箭头(thumb)。 在 Material-UI 中,所有的子元素都增加了两层的特定类:.parent .child {}。 所以在编写覆盖样式的时候,你也需要这样做。

以下示例除了覆盖滑块本身的自定义样式外,还覆盖了滑块的 thumb 样式。

PlainCssSliderDeep1.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

.slider .MuiSlider-thumb {
  border-radius: 1px;
}

PlainCssSliderDeep1.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import './PlainCssSliderDeep1.css';

export default function PlainCssSliderDeep1() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider defaultValue={30} className="slider" />
    </div>
  );
}

上面的演示依赖于 默认的className,但是你也可以使用 componentsProps API 来提供你自己的类名。

PlainCssSliderDeep2.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

.slider .thumb {
  border-radius: 1px;
}

PlainCssSliderDeep2.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import './PlainCssSliderDeep2.css';

export default function PlainCssSliderDeep2() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider
        defaultValue={30}
        className="slider"
        componentsProps={{ thumb: { className: 'thumb' } }}
      />
    </div>
  );
}

全局 CSS

明确向提组件提供类名是不是太大费周章了? 您可以定位到由 Material-UI 生成的类名

编辑按钮

GlobalCssSlider.css

.MuiSlider-root {
  color: #20b2aa;
}

.MuiSlider-root:hover {
  color: #2e8b57;
}

GlobalCssSlider.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import './GlobalCssSlider.css';

export default function GlobalCssSlider() {
  return <Slider defaultValue={30} />;
}

CSS 注入顺序⚠️

注意: 大多数的 CSS-in-JS 解决方案是在 HTML <head> 的底部注入它们的样式,这会导致你的自定义样式被 Material-UI 的样式规则所覆盖。 如果你有移除 !important 的需求,那么就需要改变 CSS 注入顺序。 Here's a demo of how it can be done in Material-UI:

import * as React from 'react';
import { StylesProvider } from '@material-ui/core';

export default function GlobalCssPriority() {
  return (
    <StylesProvider injectFirst>
      {/* Your component tree. 现在你可以覆盖 Material-UI 的样式。 */}
    </StylesProvider>
  );
}

Note: If you are using emotion and have a custom cache in your app, that one will override the one coming from Material-UI. In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例: In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例:

import * as React from 'react';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';

const cache = createCache({
  key: 'css',
  prepend: true,
});

export default function GlobalCssPriority() {
  return (
    <CacheProvider value={cache}>
      {/* 这里编写你的组件树。 现在你可以覆盖 Material-UI 的样式。 */}
    </CacheProvider>
  );
}

Note: If you are using styled-components and have StyleSheetManager with a custom target, make sure that the target is the first element in the HTML <head>. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package.

更深层的元素

如果你试图自定义滑块的样式,那么很可能会影响到滑块的一些子元素,例如滚动条的箭头(thumb)。 在 Material-UI 中,所有的子元素都增加了两层的特定类:.parent .child {}。 所以在编写覆盖样式的时候,你也需要这样做。

以下示例除了覆盖滑块本身的自定义样式外,还覆盖了滑块的 thumb 样式。

GlobalCssSliderDeep.css

.MuiSlider-root {
  color: #20b2aa;
}

.MuiSlider-root:hover {
  color: #2e8b57;
}

.MuiSlider-root .MuiSlider-thumb {
  border-radius: 1px;
}

GlobalCssSliderDeep.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import './GlobalCssSliderDeep.css';

export default function GlobalCssSliderDeep() {
  return <Slider defaultValue={30} />;
}

Styled Components

stars npm

改变默认的样式引擎

默认情况下,Material-UI 组件使用 emotion 来作为它们的样式引擎。 但是,如果你想使用 styled-components 的话,那么你可以参考这个 示例项目 来配置你的应用程序。 按照这种方法来配置的话,则可以减少捆绑包的大小,并且无需配置 CSS 注入顺序。

在正确配置了样式引擎之后,你可以使用 @material-ui/core/styles 中的 experimentalStyled() 工具集来直接访问主题。

编辑按钮

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import { experimentalStyled as styled } from '@material-ui/core/styles';

const CustomizedSlider = styled(Slider)`
  color: #20b2aa;

  :hover {
    color: #2e8b57;
  }
`;

export default function StyledComponents() {
  return <CustomizedSlider defaultValue={30} />;
}

更深层的元素

如果你试图自定义滑块的样式,那么很可能会影响到滑块的一些子元素,例如滚动条的箭头(thumb)。 在 Material-UI 中,所有的子元素都增加了两层的特定类:.parent .child {}。 所以在编写覆盖样式的时候,你也需要这样做。

以下示例除了覆盖滑块本身的自定义样式外,还覆盖了滑块的 thumb 样式。

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import { experimentalStyled as styled } from '@material-ui/core/styles';

const CustomizedSlider = styled(Slider)`
  color: #20b2aa;

  :hover {
    color: #2e8b57;
  }

  & .MuiSlider-thumb {
    border-radius: 1px;
  }
`;

export default function StyledComponentsDeep1() {
  return (
    <div>
      <Slider defaultValue={30} />
      <CustomizedSlider defaultValue={30} />
    </div>
  );
}

上面的演示依赖于 默认的className,但是你也可以使用 componentsProps API 来提供你自己的类名。

import * as React from 'react';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import Slider from '@material-ui/core/Slider';

const CustomizedSlider = styled((props) => (
  <Slider componentsProps={{ thumb: { className: 'thumb' } }} {...props} />
))`
  color: #20b2aa;

  :hover {
    color: #2e8b57;
  }

  & .thumb {
    border-radius: 1px;
  }
`;

export default function StyledComponentsDeep2() {
  return (
    <div>
      <Slider defaultValue={30} />
      <CustomizedSlider defaultValue={30} />
    </div>
  );
}

主题

通过使用 Material-UI 主题提供者(theme provider),该主题也可以在样式引擎的主题上下文中可用(emotion 或 styled-components,取决于你的配置)。

⚠️如果你已经使用了 styled-component 或 emotion 驱动的自定义主题,那么它可能会不兼容 Material-UI 的主题规范。 如果它不兼容,那么你需要渲染 Material-UI 的 ThemeProvider。 这样做就可以确保主题结构的隔离。 这对于想要在代码库中渐进式地使用 Material-UI 组件是非常理想的。

我们鼓励你在 Material-UI 和你项目的其他部分之间共享相同的主题对象。

const CustomizedSlider = styled(Slider)(
  ({ theme }) => `
  color: ${theme.palette.primary.main};

  :hover {
    color: ${darken(theme.palette.primary.main, 0.2)};
  }
`,
);
<ThemeProvider theme={customTheme}>
  <CustomizedSlider defaultValue={30} />
</ThemeProvider>

Portals(传送门组件)

代办:在使用新的样式引擎实现传送门(portal)后,将会填写这部分内容。

CSS Modules

stars

鉴于它全权依赖于大家使用的打包方案,我们很难得知 此种样式方案 的市场占有率。

编辑按钮

CssModulesSlider.module.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

CssModulesSlider.js

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
// webpack, parcel or else will inject the CSS into the page
import styles from './CssModulesSlider.module.css';

export default function CssModulesSlider() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider defaultValue={30} className={styles.slider} />
    </div>
  );
}

CSS 注入顺序⚠️

注意: 大多数的 CSS-in-JS 解决方案是在 HTML <head> 的底部注入它们的样式,这会导致你的自定义样式被 Material-UI 的样式规则所覆盖。 如果你有移除 !important 的需求,那么就需要改变 CSS 注入顺序。 Here's a demo of how it can be done in Material-UI:

import * as React from 'react';
import { StylesProvider } from '@material-ui/core';

export default function GlobalCssPriority() {
  return (
    <StylesProvider injectFirst>
      {/* Your component tree. 现在你可以覆盖 Material-UI 的样式。 */}
    </StylesProvider>
  );
}

Note: If you are using emotion and have a custom cache in your app, that one will override the one coming from Material-UI. In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例: In order for the injection order to still be correct, you need to add the prepend option. 下面是一个示例:

import * as React from 'react';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';

const cache = createCache({
  key: 'css',
  prepend: true,
});

export default function CssModulesPriority() {
  return (
    <CacheProvider value={cache}>
      {/* 这里编写你的组件 现在你可以覆盖 Material-UI 的样式。 */}
    </CacheProvider>
  );
}

Note: If you are using styled-components and have StyleSheetManager with a custom target, make sure that the target is the first element in the HTML <head>. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package. If you are curious to see how it can be done, you can take a look on the StylesProvider implementation in the @material-ui/styled-engine-sc package.

更深层的元素

如果你试图自定义滑块的样式,那么很可能会影响到滑块的一些子元素,例如滚动条的箭头(thumb)。 在 Material-UI 中,所有的子元素都增加了两层的特定类:.parent .child {}。 所以在编写覆盖样式的时候,你也需要这样做。

以下示例除了覆盖滑块本身的自定义样式外,还覆盖了滑块的 thumb 样式。

CssModulesSliderDeep1.module.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

.slider .MuiSlider-thumb {
  border-radius: 1px;
}

CssModulesSliderDeep1.js

import * as React from 'react';
// webpack, parcel or else will inject the CSS into the page
import styles from './CssModulesSliderDeep1.module.css';
import Slider from '@material-ui/core/Slider';

export default function CssModulesSliderDeep1() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider defaultValue={30} className={styles.slider} />
    </div>
  );
}

上面的演示依赖于 默认的className,但是你也可以使用 componentsProps API 来提供你自己的类名。

CssModulesSliderDeep2.module.css

.slider {
  color: #20b2aa;
}

.slider:hover {
  color: #2e8b57;
}

.slider .thumb {
  border-radius: 1px;
}

CssModulesSliderDeep2.js

import * as React from 'react';
// webpack, parcel or else will inject the CSS into the page
import styles from './CssModulesSliderDeep2.module.css';
import Slider from '@material-ui/core/Slider';

export default function CssModulesSliderDeep2() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider
        defaultValue={30}
        className={styles.slider}
        componentsProps={{ thumb: { className: styles.thumb } }}
      />
    </div>
  );
}

Emotion

stars npm

css 属性

Emotion 的 css() 方法与 Material-UI 无缝协作。

编辑按钮

/** @jsx jsx */
import { jsx, css } from '@emotion/react';
import Slider from '@material-ui/core/Slider';

export default function EmotionCSS() {
  return (
    <div>
      <Slider defaultValue={30} />
      <Slider
        defaultValue={30}
        css={css`
          color: #20b2aa;

          :hover {
            color: #2e8b57;
          }
        `}
      />
    </div>
  );
}

主题

它会像 styled components 一样起作用。 您可以 使用相同的指南

styled() API

它会像 styled components 一样起作用。 您可以 使用相同的指南