React 有很多種方式可以寫 CSS
- inline-style,用
style={}
寫 - HTML 的 CSS link ,引入外部 CSS
- 使用 webpack 打包
- styled component 它是一個套件,比較主流用法
官方文件至少 Basics看完,有一些基本用法
安裝
# with npm
npm install --save styled-components
# with yarn
yarn add styled-components
import
import styled from 'styled-components'
舉例 :
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
宣告 Title = styled.h1,h1 就是 h1 標籤,後面用反引號,反引號除了用在樣板字串(template strings)以外,還可以用在標籤模版(tagged template),參考文章 :[筆記] JavaScript ES6 中的模版字符串(template literals)和標籤模版(tagged template)
一樣可以傳 props 進去
例如 tag 裡面加 size = "XL"
接收 props 用 ${}
,裡面要放 function,通常用箭頭函式比較方便
const TodoButton = styled.div`
color:rgba(2, 1, 23);
font-size: ${props => props.size === 'XL' ? '20px' : '12px'}
`
不一定要用三元運算子,可以用短路邏輯
const TodoButton = styled.div`
color:rgba(2, 1, 23);
font-size: 12px;
${props => props.size === 'XL' && `
font-size: 20px;
`}
`
如果是 XL ,那 font-size: 12px;
就會被蓋過去
restyle
對 style component 做 restyle
const RedButton = styled(Button)`
color: red;
`
如果是對一般的 component 進行 restyle,則需要在 component 傳入 className,用來接收class 屬性
// 繼承 TodoItem component,需要傳入 className
function TodoItem ({ className, size, content }) {
return (
<TodoItemWrapper className={className}>
<TodoContent size={size}>{content}</TodoContent>
<TodoButtonWrapper>
<Button>未完成</Button>
<GreenButton>刪除</GreenButton>
</TodoButtonWrapper>
</TodoItemWrapper>
);
}
// 繼承 TodoItem
const BlackTodoItem = styled(TodoItem)`
background: #000;
`
function App() {
const titleSize = "M"
return (
<div className="App">
<TodoItem content={123} />
<BlackTodoItem content={456} size="XL" />
</div>
);
}
@media
透過 Media Query 實作 RWD
const Button = styled.button`
font-size: 20px;
@media screen and (min-width: 768px) {
font-size 16px;
}
像 Media Query 重複率很高,所以可以額外開個資料夾像是 constants\style.js
檔案,以便重複使用
export const MEDIA_QUERY_MD = '@media screen and {min-width: 768px}'
export const MEDIA_QUERY_LG = '@media screen and {min-width: 1080px}'
便可以在其他檔案引入使用
import { MEDIA_QUERY_MD, MEDIA_QUERY_LG} from './constants/style';
const Button = styled.button`
font-size: 20px;
${MEDIA_QUERY_MD} {
font-size 16px;
}
${MEDIA_QUERY_LG} {
font-size: 12px;
}
`
向量變數
Advanced Usage裡面有個Theming,可以傳個 Global 變數,使用向量變數
index.js 引入 ThemeProvider
import { ThemeProvider } from 'styled-components';
// 提供 theme 的參數
const theme = {
colors: {
primary_300: '#ff7777',
primary_400: '#e33e3e',
primary_500: '#af0505',
}
}
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>,
document.getElementById('root')
);
App.js 中取用這些變數
const TodoContent = styled.div`
font-size: 20px;
color: ${props => props.theme.colors.primary_300};
${MEDIA_QUERY_MD} {
font-size: 16px;
color: ${props => props.theme.colors.primary_400};
}
${MEDIA_QUERY_LG} {
font-size: 12px;
color: ${props => props.theme.colors.primary_500};
}
`
component 越來越大可以獨立出去
export default function TodoItem() {...}
引入
import TodoItem from './TodoItem'