[1]基本用法 [2]組件樣式 [3]擴展樣式 [4]更換標簽 [5]傳遞屬性 [6]attrs函數 [7]動畫 [8]添加類名 ...
前面的話
使用jsx語法可以實現HTML in JS,使用svgr可以實現svg in JS,使用styled-components可以實現CSS in JS。這樣,使用react開發,就變成了使用JS開發,統一且方便。本文將詳細介紹styled-components的用法
基本用法
【安裝】
$ npm install styled-components
使用非常簡單,下麵的代碼片段展示了 React 項目中使用 styled-components,定義了 Wrapper 和 Button 兩個組件,包含了 html 結構和對應的 css 樣式,從而將樣式和組件之間的 class 映射關係移除
import styled from 'styled-components'; const Wrapper = styled.section` margin: 0 auto; width: 300px; text-align: center; `; const Button = styled.button` width: 100px; color: white; background: skyblue; `; render( <Wrapper> <Button>Hello World</Button> </Wrapper> );
組件樣式
如果要為組件設置樣式,則需要使用小括弧語法,而且需要在組件上設置className和children
const Link = ({ className, children }) => ( <a className={className}> {children} </a> ) const StyledLink = styled(Link)` color: palevioletred; font-weight: bold; `; render( <div> <Link>Unstyled, boring Link</Link> <br /> <StyledLink>Styled, exciting Link</StyledLink> </div> );
擴展樣式
使用擴展樣式,可以基於已經存在的樣式進行擴展
const Button = styled.button` color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; const TomatoButton = Button.extend` color: tomato; border-color: tomato; `; render( <div> <Button>Normal Button</Button> <TomatoButton>Tomato Button</TomatoButton> </div> );
更換標簽
在某些情況下,可以在復用樣式的基礎上更換標簽
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 Link = Button.withComponent('a') const TomatoLink = Link.extend` color: tomato; border-color: tomato; `; render( <div> <Button>Normal Button</Button> <Link>Normal Link</Link> <TomatoLink>Tomato Link</TomatoLink> </div> );
傳遞屬性
通過props可以從父組件向子組件傳遞屬性
const GlassModal = ({ children, className, backgroundColor, padding }) => ( <Wrap backgroundColor={backgroundColor}> <Main padding={padding} className={className}> {children} </Main> </Wrap> ) export default GlassModal const Wrap = styled.section` background-color: ${props => props.backgroundColor || BLUE_DARK}; ` const Main = styled.main` padding: ${props => props.padding || '0'}; background-color: ${OPACITY_LIGHT}; `
const StyledGlassModal = styled(GlassModal)` padding: 20px 10px; text-align: center; `
或者,基於prop來定製主題
const Button = styled.button` 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( <div> <Button>Normal</Button> <Button primary>Primary</Button> </div> );
attrs函數
通過使用attrs函數,可以用來設置其他屬性
const Input = styled.input.attrs({ type: 'password', margin: props => props.size || '1em', padding: props => props.size || '1em' })` color: palevioletred; border-radius: 3px; margin: ${props => props.margin}; padding: ${props => props.padding}; `; render( <div> <Input placeholder="A small text input" size="1em" /> <Input placeholder="A bigger text input" size="2em" /> </div> );
或者引入第三方庫的樣式,如activeClassName
const Button = styled.button.attrs({ className: 'small', })` background: black; color: white; `;
編譯後的 html 結構如下:
<button class="sc-gPEVay small gYllyG"> Styled Components </button>
動畫
styled-components 同樣對 css 動畫中的 @keyframe 做了很好的支持
import { keyframes } from 'styled-components';
const rotate360 = keyframes` from {transform: rotate(0deg);} to {transform: rotate(360deg);} `; const Rotate = styled.div` display: inline-block; animation: ${rotate360} 2s linear infinite; `; render( <Rotate><