安装 yarn add styled-components
引入 import styled from 'styled-components'
先来个最基础的例子
// 创建一个 Title 组件,它将渲染一个附加了样式的
标签 const Title = styled.h1` font-size: 1.5em; text-align: center; color: palevioletred; `; // 创建一个 Wrapper 组件,它将渲染一个附加了样式的
标签 const Wrapper = styled.section` padding: 4em; background: papayawhip; `; // 就像使用常规 React 组件一样使用 Title 和 Wrapper render(
); Hello World! 先解析第一行
styled
是引入的styled,.
后面的是你要创建的标签名,` `
中间包裹的就是正常的CSS样式(可以写变量,传props值,后面会讲到),然后你这些复制给一个大写开头的Title变量,那么Title在styled的作用下就变成了一个组件,直接把组件渲染出来就可以了基于属性的适配
const Button = styled.button` /* Adapt the colors based on primary prop */ background: ${props => props.primary ? "palevioletred" : "white"}; color: ${props => props.primary ? "white" : "palevioletred"}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; render(
);样式继承
const Button = styled.button` color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; // 一个继承 Button 的新组件, 重载了一部分样式 const TomatoButton = styled(Button)` color: tomato; border-color: tomato; `; render(
);Tomato Button 多态 "as" polymorphic prop
const Button = styled.button` display: inline-block; color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; const TomatoButton = styled(Button)` color: tomato; border-color: tomato; `; render(
);Link with Tomato Button styles 这也完美适用于自定义组件:
const Button = styled.button` display: inline-block; color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; const ReversedButton = props => );
给任何组件添加样式
styled方法适用于任何最终向 DOM 元素传递 className 属性的组件,当然也包括第三方组件. 注意 在 react-native 中,请使用 style 而不是 className. // 下面是给 react-router-dom Link 组件添加样式的示例 const Link = ({ className, children }) => ( {children} ); const StyledLink = styled(Link)` color: palevioletred; font-weight: bold; `; render(
Unstyled, boring Link);
Styled, exciting Link 也可以传递标签给styled(), 比如: styled("div"). 实际上styled.tagname的方式就是 styled(tagname)`的别名.
属性传递
const Input = styled.input` padding: 0.5em; margin: 0.5em; color: ${props => props.inputColor || "palevioletred"}; background: papayawhip; border: none; border-radius: 3px; `; // 渲染两个样式化的 text input,一个标准颜色,一个自定义颜色 render(
);注意, inputColor prop并没有传递给 DOM, 但是type和defaultValue 都传递了. styled-components足够智能,会自动过滤掉所有非标准 attribute.
styled-components 如何在组件中工作?
Styled Component 是 HTML 元素和作用在元素上的样式规则的组合, 我们可以这样编写Counter:
import React from 'react' import styled from 'styled-components' const StyledCounter = styled.div` /* ... */ ` const Paragraph = styled.p` /* ... */ ` const Button = styled.button` /* ... */ ` export default class Counter extends React.Component { state = { count: 0 } increment = () => this.setState({ count: this.state.count + 1 }) decrement = () => this.setState({ count: this.state.count - 1 }) render() { return (
) } } {this.state.count} 伪元素,伪类选择器和嵌套
styled-component
所使用的预处理器stylis支持自动嵌套的 scss-like 语法,示例如下:
const Thing = styled.div` color: blue; `
伪元素和伪类无需进一步细化,而是自动附加到了组件:
const Thing = styled.button` color: blue; ::before { content: '🚀'; } :hover { color: red; } ` render(
Hello world! )对于更复杂的选择器,可以使用与号(&)来指向主组件.以下是一些示例:
const Thing = styled.div.attrs({ tabIndex: 0 })` color: blue; &:hover { color: red; //
when hovered } & ~ & { background: tomato; // as a sibling of , but maybe not directly next to it } & + & { background: lime; // next to } &.something { background: orange; // tagged with an additional CSS class ".something" } .something-else & { border: 1px solid; // inside another element labeled ".something-else" } ` 如果只写选择器而不带&,则指向组件的子节点.
const Thing = styled.div` color: blue; .something { border: 1px solid; // an element labeled ".something" inside
display: block; } ` render( ) 附加额外的属性 (v2)
为了避免仅为传递一些props来渲染组件或元素而使用不必要的wrapper, 可以使用
.attrs
constructor. 通过它可以添加额外的 props 或 attributes 到组件.举例来说,可以通过这种方式给元素添加静态 props,或者传递第三方 prop 给组件(比如传递
activeClassName
给 React Router 的Link
). 此外也可以将dynamic props 添加到组件..attrs
对象也接收函数,返回值也将合并进 props.示例如下:
source-js-jsx const Input = styled.input.attrs({ // static props type: "password", // dynamic props margin: props => props.size || "1em", padding: props => props.size || "1em" })` color: palevioletred; font-size: 1em; border: 2px solid palevioletred; border-radius: 3px; /* dynamically computed props */ margin: ${props => props.margin}; padding: ${props => props.padding}; `; render(
);
动画
虽然使用@keyframes的 CSS 动画不限于单个组件,但我们仍希望它们不是全局的(以避免冲突). 这就是为什么 styled-components 导出 keyframes helper 的原因: 它将生成一个可以在 APP 应用的唯一实例:
// Create the keyframes const rotate = keyframes` from { transform: rotate(0deg); } to { transform: rotate(360deg); } `; // Here we create a component that will rotate everything we pass in over two seconds const Rotate = styled.div` display: inline-block; animation: ${rotate} 2s linear infinite; padding: 2rem 1rem; font-size: 1.2rem; `;