API 參考

主要

styled

這是預設匯出。這是一個低階工廠,我們用它來創建 styled.tagname 輔助方法。

參數說明
  1. component / tagname

一個有效的 React 組件或像 'div' 這樣的標籤名稱。

返回一個函式,該函式接受一個標籤樣板字面值並將其轉換為 StyledComponent


您可以在入門章節中看到此方法的介紹。

TaggedTemplateLiteral

這就是您傳遞給 styled 呼叫的內容 - 一個標籤樣板字面值。這是一個 ES6 語言特性。您可以在標籤樣板字面值章節中了解更多資訊。

輸入說明
規則任何 CSS 規則(字串)
插值

這可以是字串或函式。字串會按原樣與規則組合。函式將接收 styled component 的 props 作為第一個也是唯一的參數。

根據 props 調整樣式章節中閱讀更多關於如何根據 props 調整樣式的資訊。

傳遞給插值函式的屬性會附加一個特殊屬性 theme,該屬性由更高級別的 ThemeProvider 組件注入。查看主題章節以了解更多關於此資訊。

✨ Magic

您也可以從插值返回物件或直接輸入物件,它們將被視為內聯樣式。但是強烈建議不要這樣做,因為 CSS 語法支援偽選擇器、媒體查詢、嵌套等,而物件語法不支援。

StyledComponent

一個 styled 的 React 組件。當您使用樣式呼叫 styled.tagnamestyled(Component) 時,會返回此組件。

此組件可以接受任何 prop。如果它是有效的屬性,它會將其傳遞給 HTML 節點,否則它只將其傳遞給插值函式。(請參閱標籤樣板字面值

您可以將任意類名傳遞給 styled component,而不會出現問題,它將被應用於 styled 呼叫定義的樣式旁邊。(例如 <MyStyledComp className="bootstrap__btn" />

.attrs

這是一個可鏈式方法,它將一些 props 附加到 styled component。第一個也是唯一的參數是一個物件,它將被合併到組件其餘的 props 中。 attrs 物件接受以下值

說明
Prop 值

這些可以是任何類型,除了函式。它們將保持靜態,並將被合併到現有的組件 props 中。

Prop 工廠

一個接收傳遞給組件的 props 並計算值的函式,然後該值將被合併到現有的組件 props 中。

返回另一個 StyledComponent

附加額外 Props章節中了解更多關於此建構函式的資訊。

"as" 多型 prop
v4

如果您想保留已應用於組件的所有樣式,但只想切換最終渲染的內容(無論是不同的 HTML 標籤還是不同的自定義組件),您可以使用 "as" prop 在執行時執行此操作。

這種情況在導航欄等用例中非常有用,其中某些項目應該是連結,而有些只是按鈕,但都以相同的方式設定樣式。

"forwardedAs" prop
v4.3

如果您選擇使用也接受 "as" prop 的 styled() 高階組件來包裝另一個組件,請使用 "forwardedAs" 將所需的 prop 傳遞給被包裝的組件。

暫態 props
v5.1

如果您想防止將要由 styled components 使用的 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

一個用於主題的輔助組件。透過 context API 將主題注入到組件樹中其下方的所有 styled components 中。查看主題章節。

Props說明
theme

一個物件(或返回物件的函式),它將作為 theme 注入到提供者下方 styled components 的所有插值中。

簡單用法

I'm mediumseagreen!

使用巢狀的 ThemeProvider 新增或替換外部主題

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

css 屬性
v4

有時您不想僅僅為了套用一些樣式就建立額外的組件。 css 屬性是一種方便的方式,讓您可以在不確定組件邊界的情況下迭代組件。它適用於普通的 HTML 標籤和組件,並支援任何樣式化組件支援的所有功能,包括根據 props、主題和自定義組件進行調整。

注意事項

要啟用對 css 屬性的支援,您必須使用 Babel 插件

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

在底層,Babel 插件會將任何具有 css 屬性的元素轉換為樣式化組件。例如,上面的程式碼會變成

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 />

請注意,您甚至不需要新增 import 語句,Babel 插件會自動執行!(除非您正在使用 Babel 巨集,請參見下文)

與 Babel 巨集一起使用

注意事項

此功能已在 v6.1 中移除,因為使用率低且對其他使用者造成不必要的負擔。 更多資訊

您可以使用 Babel 巨集 使其在 create-react-app 中運作。不幸的是,Babel 巨集僅在導入時運行,因此**無法自動新增 import 語句。**如果您手動將 import 語句新增到巨集中,則上述程式碼可以完美運作

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 語句一次

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

一個輔助組件,用於修改樣式的處理方式。對於涉及 styled-components 的給定子樹,您可以自定義各種行為,例如 CSS 運行時處理器 (stylis) 如何透過使用者級插件和選項覆蓋來處理樣式。

Props說明
disableCSSOMInjection (v5+)

切換到較慢的基於文字節點的 CSS 注入系統,用於將樣式新增到 DOM。適用於與尚未升級以使用 CSSOM API 中樣式的第三方工具整合。

disableVendorPrefixes (v5,在 v6 中移除)選擇讓給定的子樹不為渲染的組件新增舊版 CSS 屬性。
enableVendorPrefixes (v6+)選擇讓給定的子樹為渲染的組件新增舊版 CSS 屬性。
sheet

*前方有龍*。如有必要,請為進階 SSR 情境建立並提供您自己的 StyleSheet。

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 中有效的任何內容在樣式化組件中都有效!

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};
`;

使用自定義屬性

如果您正在 根據屬性調整樣式,並且這些屬性不是基本標籤/組件屬性的一部分,您可以使用類型參數,例如這樣告訴 TypeScript 這些額外的自定義屬性是什麼(需要 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 不會傳遞自定義屬性(以避免 未知屬性警告)。

但是,它會將所有屬性傳遞給自定義 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 組件,您可以利用 transient 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

根據您的使用情況,您可以通過自行提取自定義屬性來達到類似的結果

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;
`;

函數組件的注意事項

要使用函數組件並對屬性進行類型檢查,您需要定義組件及其類型。這不是 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 定義或 body 樣式。

"innerRef" 屬性

注意事項

在 styled-components v4 中移除了 "innerRef" 屬性,改用 React 16 forwardRef API。只需使用普通的 ref 屬性即可。

ref 屬性傳遞給樣式化組件將為您提供 StyledComponent 包裝器的實例,但不會提供底層 DOM 節點。這是由於 refs 的工作方式所致。無法直接在我們的包裝器上調用 DOM 方法,例如 focus

要獲取對實際包裝的 DOM 節點的引用,請將回調傳遞給 innerRef 屬性。

注意事項

我們不支持字串 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" 屬性 取代,並在 v6 中完全移除。

這是一個建立新的 StyledComponent 的方法,它應用不同的標籤或組件,但所有規則都與調用它的組件相同。

參數說明
  1. component / tagname
一個有效的 React 組件或像 'div' 這樣的標籤名稱。

返回一個新的 StyledComponent,在使用它時應用新的標籤/組件。

繼續閱讀下一頁

工具