前言
Styled Components 的寫法十分多元,剛開始接觸時只會將 CSS 放進去,完全不知道如何將 CSS 內容元件化,還有如何利用 props 改變樣式。
此筆記是實作影片的簡易 RWD 網頁,藉由實作來紀錄學習到的知識點與風格。
Demo/Code
Styled Components 的一些基礎
安裝
安裝完成後,在 src 資料夾中新增 componets 資料夾,在 componets 資料夾中,新增 styles 資料夾。
styles 資料夾裡面檔案是元件的 css,以 Container.styled.js 來說,裡面呈現的內容會像是這個樣子。
特別要注意的是:
- 在檔案開頭要加上
import styled from 'styled-components'
。
- 在宣告的 components 前,要加上
export
。
1 2 3 4 5 6 7 8
| import styled from "styled-components";
export const Container = styled.div` width: 1000px; max-width: 100%; padding: 0 20px; margin: 0 auto; `;
|
在寫完樣式後,我們將在 app.js 使用到,因此在 app.js 這隻檔案中,我們在開頭引入 Container。
1
| import { Container } from './components/styles/Container.styled'
|
就可以在 app.js 使用 Container 的 styled 了!
建立元件
在 componets 的資料夾中新增 header.js 建立元件。
在一個新的檔案中,可以打_rfc
,就會自動生成元件所需要的格式(如下)。
1 2 3 4 5 6 7
| export default function Header() { return ( <div>
</div> ) }
|
內容比較多,在標題直接放上 code 連結。
需特別注意的地方是,當我們將 theme 傳入之後,可以使用花括號解構賦值。
1 2 3 4
| export const StyledHeader = styled.header` background-color: ${({ theme }) => theme.colors.header}; padding: 40px 0; `;
|
Header 元件再引入 style 的時候,要將檔案內每一個寫好的 components 一起引入。
1
| import { StyledHeader,Nav,Logo,Title,Content,Image } from "./styles/Header.styled"
|
在檔案前引入 ThemeProvider
1
| import { ThemeProvider } from "styled-components";
|
引入後,再將 設定好的 theme 值傳入。
1 2 3 4 5 6 7 8
| const theme = { colors: { header: '#ebfbff', body: '#fff', footer: '#003333', }, mobile: '768px', }
|
在 App.js 中,將變數寫好,再利用 props 傳值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <ThemeProvider theme={theme}> <> // GlobalStyles放在最上層 <GlobalStyles /> <Header /> <Container> {content.map((item, index) => <Card key={index} item={item} /> )} </Container> <Footer /> </> </ThemeProvider >
|
如何使用 ThemeProvider 裡的值
以 Header.styled.js 為例,解構賦值就可以將值傳入。
1 2 3 4
| export const StyledHeader = styled.header` background-color: ${({ theme }) => theme.colors.header}; padding: 40px 0; `;
|
宣告全域變數,需特別注意在檔案前 import createGlobalStyle
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import { createGlobalStyle } from "styled-components";
export const GlobalStyles = createGlobalStyle` @import url('https://fonts.googleapis.com/css2? family=Poppins:wght@300;400;600;700&display=swap');
* { box-sizing: border-box; } body { background: ${({ theme }) => theme.colors.body}; color: hsl(192, 100%, 9%); font-family: 'Poppins', sans-serif; font-size: 1.15em; margin: 0; } p { opacity: 0.6; line-height: 1.5; } img { max-width: 100%; } `;
|
寫好 GlobalStyle 後,放到 App.js 的最上層。
實作
引入圖片
Header.js
1
| <Logo src='./images/logo.svg' alt="" />
|
Header.styled.js
1 2 3 4 5
| export const Logo = styled.img` @media(max-width:${({ theme }) => theme.mobile}){ margin-bottom: 40px; } `;
|
Button.styled.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import styled from 'styled-components'
export const Button = styled.button` border-radius: 50px; border: none; box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); cursor: pointer; font-size: 16px; font-weight: 700; padding: 15px 60px; background-color: ${({ bg }) => bg || '#fff'}; color: ${({ color }) => color || '#333'}; &:hover { opacity: 0.9; transform: scale(0.98); } `
|
這邊使用到了邏輯運算子,&&
和 ||
當 ||
前面的值為 false 時,就取後面的值。
1 2 3
| const a = 0 || 'iPhone';
const b = true || "不會輪到我";
|
當 &&
前面的值為 true 時,就取後面的值。
1 2 3
| const a = 0 && 'iPhone';
const b = true && "會輪到我";
|
App.js 使用到 Button 的地方,直接將顏色傳入。
1 2 3
| <Button bg='#ff0099' color='#fff'> Get Started For Free </Button>
|
使用 props 改變資料流
Card.js
當 id 是偶數時,就使用 row-reverse
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import { StyledCard } from "./styles/Card.styled"
export default function Card({ item: { id, title, body, image } }) { return ( <StyledCard layout={id % 2 === 0 && 'row-reverse'}> <div> <h2>{title}</h2> <p>{body}</p> </div>
<div> <img src={`./images/${image}`} alt="" /> </div> </StyledCard> ) }
|
Card.styled.js
當 layout 沒有傳值得時候,就是使用預設的row
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import styled from "styled-components";
export const StyledCard = styled.div` display: flex; align-items:center; background-color: #fff; border-radius: 15px; box-shadow: 0 0 10px rgba(0,0,0,0.15); margin: 40px 0; padding: 60px; flex-direction: ${({ layout }) => layout || 'row'};
img{ width: 80%; }
&>div{ flex:1; }
@media(max-width: ${({ theme }) => theme.mobile}){ flex-direction: column; } `;
|
使用 StyledSocialIcons 新增 Icon
1 2
| import { FaTwitter, FaLinkedin, FaFacebook } from 'react-icons/fa' import { StyledSocialIcons } from './styles/SocialIcons.styled'
|
直接使用標籤的方式加上 Icon。
遇到的問題
將專案部屬到 github 時,部屬完成卻顯示頁面錯誤。最後的解決方法是,只需要將 page->Settings->GitHub Pages->Source->改成 docs 就好。