` | 用来控制开启关闭自动加不同浏览器厂商的前缀 |
+
+#### 3.2 示例
+
+属性动态控制:
+
+```tsx
+const Button = styled.button<{ $primary?: boolean }>`
+ background: ${(props) => (props.$primary ? "#BF4F74" : "white")};
+ color: ${(props) => (props.$primary ? "white" : "#BF4F74")};
+
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border: 2px solid #bf4f74;
+ border-radius: 3px;
+`;
+
+render(
+
+
+
+
+);
+```
+
+扩展样式组件:
+
+```tsx
+const Button = styled.button`
+ color: #bf4f74;
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border: 2px solid #bf4f74;
+ border-radius: 3px;
+`;
+
+const TomatoButton = styled(Button)`
+ color: tomato;
+ border-color: tomato;
+`;
+
+render(
+
+
+ Tomato Button
+
+);
+```
+
+强制指定不同 DOM 渲染:
+
+```tsx
+const Button = styled.button`
+ display: inline-block;
+ color: #bf4f74;
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border: 2px solid #bf4f74;
+ border-radius: 3px;
+ display: block;
+`;
+
+render(
+
+
+
+
+);
+```
+
+可指定 自定义 的组件:
+
+```tsx
+const Button = styled.button`
+ display: inline-block;
+ color: #bf4f74;
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border: 2px solid #bf4f74;
+ border-radius: 3px;
+ display: block;
+`;
+
+const ReversedButton = (props) => (
+
+);
+
+render(
+
+
+
+
+);
+```
+
+被包装的 自定义组件 可以通过 `props.className` 来关联:
+
+```tsx
+const Link = ({ className, children }) => (
+ {children}
+);
+
+const StyledLink = styled(Link)`
+ color: #bf4f74;
+ font-weight: bold;
+`;
+
+render(
+
+ Unstyled, boring Link
+
+ Styled, exciting Link
+
+);
+```
+
+可用 `&` 来替代当前组件的 className,编译后会被替换:
+
+```tsx
+onst Thing = styled.div`
+ 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"
+ }
+`
+
+render(
+
+ Hello world!
+ How ya doing?
+ The sun is shining...
+ Pretty nice day today.
+ Don't you think?
+
+ Splendid.
+
+
+)
+
+```
+
+通过多个 `&` 来提升 CSS 选择器权重,来避免使用 `!important`:
+
+```tsx
+onst Thing = styled.div`
+ && {
+ color: blue;
+ }
+ `
+
+ const GlobalStyle = createGlobalStyle`
+ div${Thing} {
+ color: red;
+ }
+ `
+
+ render(
+
+
+
+ I'm blue, da ba dee da ba daa
+
+
+ )
+```
+
+注入默认属性:
+
+```tsx
+const Input = styled.input.attrs<{ $size?: string }>((props) =>
+ // 此处属性会注入到 DOM 中
+ ({
+ // 静态类型不会被复写
+ type: "text",
+ // 动态类型会可被外层复写
+ $size: props.$size || "1em",
+ })
+)`
+ color: #bf4f74;
+ font-size: 1em;
+ border: 2px solid #bf4f74;
+ border-radius: 3px;
+
+ /* here we use the dynamically computed prop */
+ margin: ${(props) => props.$size};
+ padding: ${(props) => props.$size};
+`;
+
+render(
+
+
+
+
+
+);
+```
+
+可通过 styled(Component) 的方式来覆盖静态属性:
+
+```tsx
+const Input = styled.input.attrs<{ $size?: string }>((props) => ({
+ type: "text",
+ $size: props.$size || "1em",
+}))`
+ border: 2px solid #bf4f74;
+ margin: ${(props) => props.$size};
+ padding: ${(props) => props.$size};
+`;
+
+const PasswordInput = styled(Input).attrs({
+ type: "password",
+})`
+ border: 2px solid aqua;
+`;
+
+render(
+
+
+
+ {/* Notice we can still use the size attr from Input */}
+
+
+);
+```
+
+动画:
+
+```tsx
+const rotate = keyframes`
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+`;
+
+const Rotate = styled.div`
+ display: inline-block;
+ animation: ${rotate} 2s linear infinite;
+ padding: 2rem 1rem;
+ font-size: 1.2rem;
+`;
+
+render(< 💅🏾 >);
+```
+
+要写动画片段的话,必须 `styled.css` 包裹:
+
+```tsx
+const rotate = keyframes``;
+
+// ❌ This will throw an error!
+const styles = `
+ animation: ${rotate} 2s linear infinite;
+`;
+
+// ✅ This will work as intended
+const styles = css`
+ animation: ${rotate} 2s linear infinite;
+`;
+```
+
+主题:
+
+```tsx
+const Button = styled.button`
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border-radius: 3px;
+
+ /* Color the border and text with theme.main */
+ color: ${(props) => props.theme.main};
+ border: 2px solid ${(props) => props.theme.main};
+`;
+
+Button.defaultProps = {
+ theme: {
+ main: "#BF4F74",
+ },
+};
+
+const theme = {
+ main: "mediumseagreen",
+};
+
+render(
+
+
+
+
+
+
+
+);
+```
+
+`theme` 支持函数类型,如果多层嵌套,可以通过函数中的参数获取上一个主题的值:
+
+```tsx
+/ Define our button, but with the use of props.theme this time
+const Button = styled.button`
+ color: ${props => props.theme.fg};
+ border: 2px solid ${props => props.theme.fg};
+ background: ${props => props.theme.bg};
+
+ font-size: 1em;
+ margin: 1em;
+ padding: 0.25em 1em;
+ border-radius: 3px;
+`;
+
+// Define our `fg` and `bg` on the theme
+const theme = {
+ fg: "#BF4F74",
+ bg: "white"
+};
+
+// This theme swaps `fg` and `bg`
+const invertTheme = ({ fg, bg }) => ({
+ fg: bg,
+ bg: fg
+});
+
+render(
+
+
+
+
+
+
+
+
+
+);
+```
+
+动态 CSS 属性名:
+
+```tsx
+onst EqualDivider = styled.div`
+ display: flex;
+ margin: 0.5rem;
+ padding: 1rem;
+ background: papayawhip;
+ ${props => props.$vertical && "flex-direction: column;"}
+
+ > * {
+ flex: 1;
+
+ &:not(:first-child) {
+ ${props => props.$vertical ? "margin-top" : "margin-left"}: 1rem;
+ }
+ }
+`;
+
+const Child = styled.div`
+ padding: 0.25rem 0.5rem;
+ background: #BF4F74;
+`;
+
+render(
+
+
+ First
+ Second
+ Third
+
+
+ First
+ Second
+ Third
+
+
+);
+```
+
+#### 3.3 注意
+
+避免将 styled-compoents 生成的组件放在 render 中:
+
+```tsx
+// 🚫
+const Header = () => {
+ const Title = styled.h1`
+ font-size: 10px;
+ `;
+
+ return (
+
+
+
+ );
+};
+```
+
+```tsx
+// ✅
+const Title = styled.h1`
+ font-size: 10px;
+`;
+
+const Header = () => {
+ return (
+
+
+
+ );
+};
+```