API 参考

主要

styled

这是默认导出。这是一个我们用来创建 styled.tagname 帮助器方法的底层工厂。

参数描述
  1. component / tagname

一个有效的 React 组件或一个像 'div' 这样的标签名。

返回一个接受标记模板字面量并将其转换为 StyledComponent 的函数。


您可以在 入门 部分中看到此方法的介绍。

TaggedTemplateLiteral

这就是您传递到 styled 调用中的内容 - 一个标记模板字面量。这是一个 ES6 语言特性。您可以在 标记模板字面量 部分中了解更多信息。

输入描述
规则任何 CSS 规则(字符串)
插值

这可以是字符串或函数。字符串将按原样与规则合并。函数将接收 styled 组件的 props 作为第一个也是唯一的参数。

有关如何根据 props 调整样式的更多信息,请阅读 根据 props 调整 部分。

传递到插值函数中的属性会附加一个特殊属性 theme,该属性由更高层的 ThemeProvider 组件注入。查看关于 主题 的部分,以获取有关此内容的更多信息。

✨ Magic

您也可以从插值中返回对象或直接输入对象,它们将被视为内联样式。但是,强烈建议不要这样做,因为 CSS 语法支持伪选择器、媒体查询、嵌套等,而对象语法不支持这些。

StyledComponent

一个 styled React 组件。当您使用样式调用 styled.tagnamestyled(Component) 时,将返回此组件。

此组件可以接受任何 prop。如果它是有效的属性,它会将其传递到 HTML 节点,否则它只会将其传递到插值函数中。(见 标记模板字面量

您可以毫无问题地将任意类名传递给 styled 组件,它将与 styled 调用定义的样式并排应用。(例如 <MyStyledComp className="bootstrap__btn" />

.attrs

这是一个可链接的方法,它将一些 props 附加到 styled 组件。第一个也是唯一的参数是一个将与组件剩余 props 合并的对象。attrs 对象接受以下值

描述
Prop 值

这些可以是任何类型,除了函数。它们将保持静态并将与现有组件 props 合并。

Prop 工厂

一个接收传递给组件的 props 并计算一个值,然后该值将与现有组件 props 合并的函数。

返回另一个 StyledComponent

附加额外 props 部分了解更多有关此构造函数的信息。

"as" 多态 prop
v4

如果您想保留应用于组件的所有样式,但只切换最终呈现的内容(无论是不同的 HTML 标签还是不同的自定义组件),您可以在运行时使用 "as" prop 来完成此操作。

这种方法在导航栏等用例中非常有用,其中某些项目应该是链接,而某些项目只是按钮,但所有项目都具有相同的样式。

"forwardedAs" prop
v4.3

如果您选择使用还接受 "as" prop 的 styled() HOC 包装另一个组件,请使用 "forwardedAs" 将所需的 prop 传递给包装的组件。

瞬态 props
v5.1

如果您想阻止旨在由 styled 组件使用的 props 传递给底层 React 节点或渲染到 DOM 元素,您可以将 prop 名称加一个美元符号 ($),将其转换为瞬态 prop。

在此示例中,$draggable 不会像 draggable 那样渲染到 DOM。

Drag me!

shouldForwardProp
v5.1

这是一种比瞬态 props 更动态、更细粒度的过滤机制。在多个高阶组件组合在一起并恰好共享相同 prop 名称的情况下,它非常方便。shouldForwardProp 的工作方式与 Array.filter 的谓词回调类似。一个未通过测试的 prop 不会像瞬态 prop 那样传递给底层组件。

请记住,正如在此示例中一样,其他可链接方法应始终在 .withConfig 之后执行。

Drag Me!

可选地,shouldForwardProp 可以接受第二个参数,该参数提供对默认验证器函数的访问。此函数可以用作后备,当然,它也像谓词一样工作,根据已知的 HTML 属性进行过滤。

ThemeProvider

用于主题的帮助器组件。通过上下文 API 将主题注入到组件树中它下面的所有 styled 组件中。查看关于 主题 的部分。

Props描述
theme

一个对象(或返回对象的函数),它将作为 theme 注入到提供者下面的所有 styled 组件中的插值中。

简单用法

I'm mediumseagreen!

使用嵌套的 ThemeProvider 添加或替换外部主题

I'm mediumseagreen with a white background!
I'm mediumseagreen with a black background!

css prop
v4

有时您不想只创建一个额外的组件来应用一点样式。css prop 是一种方便的方法,可以在不确定固定组件边界的情况下对组件进行迭代。它适用于普通 HTML 标签和组件,并支持任何 styled 组件支持的所有内容,包括根据 props 调整、主题和自定义组件。

注意

要启用对 css prop 的支持,您必须使用 Babel 插件

<div
  css={`
    background: papayawhip;
    color: ${props => props.theme.colors.text};
  `}
/>
<Button
  css="padding: 0.5em 1em;"
/>

在幕后,Babel 插件会将任何带有 css prop 的元素转换为 styled 组件。例如,上面的代码变成

import styled from 'styled-components';


const StyledDiv = styled.div`
  background: papayawhip;
  color: ${props => props.theme.colors.text};
`


const StyledButton = styled(Button)`
  padding: 0.5em 1em;
`


<StyledDiv />
<StyledButton />

注意,您甚至不必添加导入,Babel 插件会自动完成!(除非您使用 Babel 宏,请参阅下文)

Babel 宏的使用

注意

由于缺乏使用情况和对其他用户来说不必要的膨胀,此功能在 v6.1 中被移除。 更多信息

您可以在 create-react-app 中使用 Babel 宏 使其工作。不幸的是,Babel 宏仅在导入时运行,因此 **导入无法自动添加**。如果您手动将导入添加到宏,上面的代码将完美运行

import styled from 'styled-components/macro'


<div
  css={`
    background: papayawhip;
    color: ${props => props.theme.colors.text};
  `}
/>
<Button
  css="padding: 0.5em 1em;"
/>

TypeScript 的使用

为了防止 TypeScript 在任意元素的 css 属性上出现错误,请安装 @types/styled-components 并在您的项目中添加以下导入

import {} from 'styled-components/cssprop'

请参阅 https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31245#issuecomment-446011384 以获取更多信息。

如果您使用的是高于 v6 的版本,则无需安装 @types/styled-components。相反,您可以直接在您的项目中导入 CSSProp,如下所示

import {} from 'react'
import type { CSSProp } from 'styled-components'


declare module 'react' {
  interface Attributes {
    css?: CSSProp | undefined
  }
}

辅助函数

createGlobalStyle
v4仅限网络

一个辅助函数,用于生成一个特殊的 StyledComponent,它处理全局样式。通常,样式化组件会自动作用域到本地 CSS 类,因此与其他组件隔离。在 createGlobalStyle 的情况下,此限制被移除,并且可以应用诸如 CSS 重置或基本样式表之类的内容。

参数描述
  1. 标记模板字面量
一个标记模板字面量,包含您的 CSS 和插值。

返回一个 StyledComponent,它不接受子元素。将其放置在 React 树的顶部,全局样式将在组件“渲染”时注入。

import { createGlobalStyle } from 'styled-components'


const GlobalStyle = createGlobalStyle<{ $whiteColor?: boolean; }>`
  body {
    color: ${props => (props.$whiteColor ? 'white' : 'black')};
  }
`


// later in your app


<React.Fragment>
  <GlobalStyle $whiteColor />
  <Navigation /> {/* example of other top-level stuff */}
</React.Fragment>

由于 GlobalStyle 组件是一个 StyledComponent,这意味着它也可以访问来自 <ThemeProvider> 组件 的主题,如果提供的话。

import { createGlobalStyle, ThemeProvider } from 'styled-components'


const GlobalStyle = createGlobalStyle<{ $whiteColor?: boolean; }>`
  body {
    color: ${props => (props.$whiteColor ? 'white' : 'black')};
    font-family: ${props => props.theme.fontFamily};
  }
`


// later in your app


<ThemeProvider theme={{ fontFamily: 'Helvetica Neue' }}>
  <React.Fragment>
    <Navigation /> {/* example of other top-level stuff */}
    <GlobalStyle $whiteColor />
  </React.Fragment>
</ThemeProvider>

css

一个辅助函数,用于从包含插值的模板字面量生成 CSS。如果您在插值中返回一个包含函数的模板字面量,则需要使用它,因为 JavaScript 中的标记模板字面量的使用方法。

如果您正在插值一个字符串,则无需使用它,只有在插值一个函数时才需要使用它。

参数描述
  1. 标记模板字面量
一个标记模板字面量,包含您的 CSS 和插值。

返回一个插值数组,它是一个扁平化的数据结构,您可以将其作为插值本身传递。

import styled, { css } from 'styled-components'


interface ComponentProps {
  $complex?: boolean;
  $whiteColor?: boolean;
}


const complexMixin = css<ComponentProps>`
  color: ${props => (props.$whiteColor ? 'white' : 'black')};
`


const StyledComp = styled.div<ComponentProps>`
  /* This is an example of a nested interpolation */
  ${props => (props.$complex ? complexMixin : 'color: blue;')};
`

如果您省略 css,您的函数将被 toString() 处理,您将不会获得预期的结果。

keyframes
仅限网络

一个辅助方法,用于为动画创建关键帧。

参数描述
  1. 标记模板字面量
一个标记模板字面量,包含您的关键帧。

返回一个 Keyframes 模型,用于在动画声明中使用。如果您希望获取生成的动画名称,可以使用返回模型上的 getName() API。

注意

在 styled-components v3 及更低版本中,keyframes 辅助函数直接返回动画名称,而不是包含 getName 方法的对象。

import styled, { keyframes } from 'styled-components'


const fadeIn = keyframes`
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
`


const FadeInButton = styled.button`
  animation: 1s ${fadeIn} ease-out;
`

如果您将样式规则作为部分进行组合,请确保使用 css 辅助函数。

import styled, { css, keyframes } from 'styled-components'


interface AnimationProps {
  $animationLength: number;
}


const pulse = keyframes`
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
`


const animation = props =>
  css<AnimationProps>`
    ${pulse} ${props.$animationLength} infinite alternate;
  `


const PulseButton = styled.button<AnimationProps>`
  animation: ${animation};
`

您可以在 动画 部分了解更多关于在 styled-components 中使用动画的信息。

StyleSheetManager

一个辅助组件,用于修改样式的处理方式。对于涉及样式化组件的给定子树,您可以自定义各种行为,例如 CSS 运行时处理器(stylis)如何通过用户端插件和选项覆盖来处理样式。

Props描述
disableCSSOMInjection (v5+)

切换到较慢的基于文本节点的 CSS 注入系统,用于将样式添加到 DOM。对于与尚未升级以从 CSSOM API 使用样式的第三方工具集成很有用。

disableVendorPrefixes (v5,在 v6 中移除)将给定子树排除在为渲染的组件添加遗留 CSS 属性之外。
enableVendorPrefixes (v6+)将给定子树选择为为渲染的组件添加遗留 CSS 属性。
sheet

前方有龙。如果需要,请创建并提供您自己的 StyleSheet,以用于高级 SSR 场景。

stylisPlugins (v5+)

编译期间由 stylis 运行的插件数组。查看

npm 上有什么

.

target

前方有龙。提供一个备用 DOM 节点以注入样式信息。

例如,如果您的应用程序适用于遗留浏览器,您可能希望为您的样式启用供应商前缀

If you inspect me, there are vendor prefixes for the flexbox style.

另一个例子是通过用户端 stylis-plugin-rtl 插件为您的样式启用从右到左的翻译

My border is now on the right!

isStyledComponent

一个帮助识别样式化组件的实用程序。

参数描述
  1. 函数

任何可能被认为是样式化组件或包裹在样式化组件中的 React 组件的函数

如果传递的函数是有效的样式化组件包裹的组件类,则返回 true。它可以用来确定组件是否需要包裹,以便它可以用作组件选择器

import React from 'react'
import styled, { isStyledComponent } from 'styled-components'
import MaybeStyledComponent from './somewhere-else'


let TargetedComponent = isStyledComponent(MaybeStyledComponent)
  ? MaybeStyledComponent
  : styled(MaybeStyledComponent)``


const ParentComponent = styled.div`
  color: royalblue;


  ${TargetedComponent} {
    color: tomato;
  }
`

withTheme

这是一个高级组件工厂,用于从 ThemeProvider 获取当前主题,并将其作为 theme 属性传递给您的组件。

参数描述
  1. 组件

任何可以处理 theme 属性的有效 React 组件。

将传递的组件包装在包装器(高级组件)中返回。传递的组件将收到一个 theme 属性,其中包含当前主题对象。

import { withTheme } from 'styled-components'


class MyComponent extends React.Component {
  render() {
    console.log('Current theme: ', this.props.theme)
    // ...
  }
}


export default withTheme(MyComponent)
注意

所有样式化组件 自动接收主题作为属性,因此只有在您希望出于其他原因访问主题时,才需要这样做。

useTheme
v5

这是一个自定义钩子,用于从 ThemeProvider 获取当前主题。

import { useTheme } from 'styled-components'


function MyComponent() {
  const theme = useTheme()
  console.log('Current theme: ', theme)


  // ...
}
注意

所有样式化组件 自动接收主题作为属性,因此只有在您希望出于其他原因访问主题时,才需要这样做。

ThemeConsumer
v4

这是由 React.createContext 创建的 "消费者" 组件,作为 ThemeProvider 的配套组件。它使用 渲染属性模式 允许在渲染期间动态访问主题。

它将当前主题(基于您组件树中更高位置的 ThemeProvider)作为参数传递给子函数。从这个函数中,您可以返回更多 JSX 或不返回任何内容。

import { ThemeConsumer } from 'styled-components'


export default class MyComponent extends React.Component {
  render() {
    return (
      <ThemeConsumer>
        {theme => <div>The theme color is {theme.color}.</div>}
      </ThemeConsumer>
    )
  }
}
注意

所有样式化组件 自动接收主题作为属性,因此只有在您希望出于其他原因访问主题时,才需要这样做。

测试实用程序

find
v3

一个便利方法,用于在给定的 DOM 根节点中查找样式化组件渲染的 DOM 节点的单个实例。

import styled from 'styled-components'
import { find } from 'styled-components/test-utils'


const Foo = styled.div`
  color: red;
`


/**
 * Somewhere in your app:
 *
 * ReactDOM.render(
 *   <main>
 *     <Foo />
 *   </main>, document.body
 * );
 */


// retrieves the first instance of "Foo" in the body (querySelector under the hood)
find(document.body, Foo) // HTMLDivElement | null

findAll
v3

一个便利方法,用于在给定的 DOM 根节点中查找样式化组件渲染的 DOM 节点的所有实例。

import styled from 'styled-components'
import { findAll } from 'styled-components/test-utils'


const Foo = styled.div`
  color: ${props => props.color};
`


/**
 * Somewhere in your app:
 *
 * ReactDOM.render(
 *   <main>
 *     <Foo color="red" />
 *     <Foo color="green" />
 *   </main>, document.body
 * );
 */


// retrieves a NodeList of instances of "Foo" in the body (querySelectorAll under the hood)
findAll(document.body, Foo) // NodeList<HTMLDivElement> | null

enzymeFind
v4

一个便利方法,用于在 enzyme 包装器中查找特定样式化组件的实例。

import { mount } from 'enzyme'
import styled from 'styled-components'
import { enzymeFind } from 'styled-components/test-utils'


const Foo = styled.div`
  color: red;
`


const wrapper = mount(
  <div>
    <Foo>bar</Foo>
  </div>
)


enzymeFind(wrapper, Foo)

支持的 CSS

在样式化组件中,我们支持所有 CSS 以及嵌套。由于我们生成的是实际的样式表,而不是内联样式,因此在 CSS 中起作用的东西在 styled-components 中也能起作用!

Hello World!

与符号 (&) 将被我们为该样式化组件生成的唯一类名替换,从而使复杂的逻辑变得容易。

TypeScript
v6

styled-components 提供 TypeScript 定义,这增强了 IDE 中的编辑体验,并提高了 TypeScript 项目的类型安全性。

注意

对于较旧版本的 styled-components,可以通过 @types/styled-components NPM 包获得社区定义。

创建声明文件

自定义文件的 v4.1.4 版本起,可以通过使用 声明合并 扩展 styled-components 的 TypeScript 定义。

因此,第一步是创建一个声明文件。例如,我们将其命名为 styled.d.ts

// import original module declarations
import 'styled-components';


// and extend them!
declare module 'styled-components' {
  export interface DefaultTheme {
    borderRadius: string;


    colors: {
      main: string;
      secondary: string;
    };
  }
}

React-Native

import 'styled-components/native'


declare module 'styled-components/native' {
  export interface DefaultTheme {
    borderRadius: string;


    colors: {
      main: string;
      secondary: string;
    };
  }
}

DefaultTheme 默认用作 props.theme 的接口。默认情况下,接口 DefaultTheme 是空的,这就是为什么我们需要扩展它的原因。

创建主题

现在我们可以使用上面步骤中声明的 DefaultTheme 来创建主题。

// my-theme.ts
import { DefaultTheme } from 'styled-components';


const myTheme: DefaultTheme = {
  borderRadius: '5px',


  colors: {
    main: 'cyan',
    secondary: 'magenta',
  },
};


export { myTheme };

样式化组件

就这样!我们只需要使用任何原始导入就可以使用 styled-components。

import styled, { createGlobalStyle, css } from 'styled-components';


// theme is now fully typed
export const MyComponent = styled.div`
  color: ${props => props.theme.colors.main};
`;


// theme is also fully typed
export MyGlobalStyle = createGlobalStyle`
  body {
    background-color: ${props => props.theme.colors.secondary};
  }
`;


// and this theme is fully typed as well
export cssHelper = css`
  border: 1px solid ${props => props.theme.borderRadius};
`;

使用自定义 props

如果你要 根据 props 调整样式,并且这些 props 不属于基本标签/组件 props,你可以使用类型参数告诉 TypeScript 这些额外的自定义 props 是什么,例如这样(TypeScript v2.9+ 是必需的)。

import styled from 'styled-components';
import Header from './Header';


interface TitleProps {
  readonly $isActive: boolean;
}


const Title = styled.h1<TitleProps>`
  color: ${(props) => (props.$isActive ? props.theme.colors.main : props.theme.colors.secondary)};
`;

注意:如果你为一个标准标签(例如上面示例中的 <h1>)设置样式,styled-components 不会传递自定义 props(以避免 未知 Prop 警告)。

但是,它会将所有 props 传递给自定义 React 组件。

import styled from 'styled-components';
import Header from './Header';


const NewHeader = styled(Header)<{ customColor: string }>`
  color: ${(props) => props.customColor};
`;
// Header will also receive props.customColor

如果 customColor 属性不应该传递给 Header 组件,你可以利用 瞬态 props,通过在它前面加上一个美元符号 ($) 来实现。

import styled from 'styled-components';
import Header from './Header';


const NewHeader2 = styled(Header)<{ $customColor: string }>`
  color: ${(props) => props.$customColor};
`;
// Header does NOT receive props.$customColor

根据你的使用场景,你可以通过自己提取自定义 props 来实现类似的结果。

import styled from 'styled-components';
import Header, { Props as HeaderProps } from './Header';


const NewHeader3 = styled(({ customColor, ...rest }: { customColor: string } & HeaderProps) => <Header {...rest} />)`
  color: ${(props) => props.customColor};
`;

或者使用 shouldForwardProp

import styled from 'styled-components';
import Header from './Header';


const NewHeader4 = styled(Header).withConfig({
  shouldForwardProp: (prop) => !['customColor'].includes(prop),
})<{ customColor: string }>`
  color: ${(props) => props.customColor};
`;

className 的警告

定义组件时,你需要在 Props 接口中将 className 标记为可选的。

interface LogoProps {
  /* This prop is optional, since TypeScript won't know that it's passed by the wrapper */
  className?: string;
}


class Logo extends React.Component<LogoProps, {}> {
  render() {
    return <div className={this.props.className}>Logo</div>;
  }
}


const LogoStyled = styled(Logo)`
  font-family: 'Helvetica';
  font-weight: bold;
  font-size: 1.8rem;
`;

函数组件的警告

要使用函数组件并对 props 进行类型检查,你需要定义组件及其类型。这对 styled-components 来说并不特殊,这只是 React 的工作方式。

interface BoxProps {
  theme?: ThemeInterface;
  borders?: boolean;
  className?: string;
}


const Box: React.FunctionComponent<BoxProps> = (props) => <div className={props.className}>{props.children}</div>;


const StyledBox = styled(Box)`
  padding: ${(props) => props.theme.lateralPadding};
`;

之前的 API

.extend

注意

在 styled-components v4 中,.extend API 被移除,请使用 styled(StyledComponent) 代替。更多信息,请查看:https://github.com/styled-components/styled-components/issues/1546

这是一个创建新的 StyledComponent 并扩展其规则的方法。

参数描述
  1. 标记模板字面量
一个标记模板字面量,包含您的 CSS 和插值。
import styled from 'styled-components'


const Component = styled.div`
  color: red;
`


const Component2 = Component.extend`
  background: white;
  color: blue;
`

返回一个新的 StyledComponent,其新规则与调用此方法的组件的规则合并。

injectGlobal

注意

在 styled-components v4 中,injectGlobal API 被移除,并用 createGlobalStyle 代替。

一个用于编写全局 CSS 的辅助方法。它不返回组件,而是直接将样式添加到样式表中。

参数描述
  1. 标记模板字面量
一个带标签的模板字面量,其中包含你的全局样式。
import { injectGlobal } from 'styled-components'


injectGlobal`
  @font-face {
    font-family: "Operator Mono";
    src: url("../fonts/Operator-Mono.ttf");
  }


  body {
    margin: 0;
  }
`

我们不鼓励使用它。如果你必须使用,请尝试在应用程序中最多使用一次,并且将其包含在一个文件中。这是一个逃生舱口。只在极少数情况下使用它,例如 @font-face 定义或主体样式。

"innerRef" prop

注意

在 styled-components v4 中,"innerRef" prop 被移除,取而代之的是 React 16 forwardRef API。只需使用普通的 ref prop 即可。

ref prop 传递给样式化组件会给你一个 StyledComponent 包装器的实例,而不是底层的 DOM 节点。这是由于 refs 的工作方式。无法直接在我们的包装器上调用 DOM 方法,例如 focus

要获取对实际的、被包装的 DOM 节点的引用,请将回调传递给 innerRef prop。

注意

我们不支持字符串 refs(例如 innerRef="node"),因为它们在 React 中已经过时了。

此示例使用 innerRef 保存对样式化输入的引用,并在用户悬停其上时将其聚焦。

const Input = styled.input`
  padding: 0.5em;
  margin: 0.5em;
  color: #BF4F74;
  background: papayawhip;
  border: none;
  border-radius: 3px;
`


class Form extends React.Component {
  render() {
    return (
      <Input
        placeholder="Hover here..."
        innerRef={x => {
          this.input = x
        }}
        onMouseEnter={() => this.input.focus()}
      />
    )
  }
}

.withComponent

注意

在 styled-components v4 中,withComponent API 被 "as" prop 代替,并在 v6 中完全移除。

这是一个创建新的 StyledComponent 的方法,其中应用了不同的标签或组件,但所有规则都与调用它的组件相同。

参数描述
  1. component / tagname
一个有效的 React 组件或一个像 'div' 这样的标签名。

返回一个新的 StyledComponent,在使用时会应用新的标签/组件。

继续下一页

工具