Skip to main content

什麼是 styled-components?

styled-components 允許你使用 JavaScript 來定義帶有樣式的 React 元件。它透過 標籤模板字面量(Tagged Template Literals) 將 CSS 樣式直接嵌入到 JavaScript 程式碼中,並將樣式綁定到特定的元件。這樣可以讓樣式與元件緊密結合,避免傳統 CSS 檔案中樣式可能造成的全局污染問題。

它的核心理念是:

  • 元件化樣式:每個元件的樣式都獨立封裝,不會影響其他元件。

  • 動態樣式:可以根據元件的 props 或 state 動態調整樣式。

  • 直觀語法:使用熟悉的 CSS 語法,但寫在 JavaScript 中,易於上手。

  • 自動優化:自動為樣式生成唯一的 class 名稱,減少命名衝突。


styled-components 的主要特點

  1. 元件化的樣式管理 你可以為每個 React 元件創建專屬的樣式,這些樣式只會套用到該元件,不會影響其他元件。這解決了傳統 CSS 中樣式可能意外互相干擾的問題。

  2. 支援 CSS 語法 styled-components 使用標準的 CSS 語法,像是 background-color、padding 等,對於熟悉 CSS 的前端工程師來說非常直觀。你甚至可以直接複製現有的 CSS 程式碼貼到 styled-components 中使用。

  3. 動態樣式(Props 支援) 你可以根據元件的 props 或 state 動態改變樣式。例如,根據按鈕的狀態(像是 disabled 或 active)來改變背景顏色。

  4. 主題(Theme)支援 styled-components 提供 ThemeProvider,讓你定義全局主題(例如顏色、字型等),並在所有元件中輕鬆引用,方便統一管理樣式。

  5. 自動處理瀏覽器前綴 它會自動為 CSS 屬性添加必要的瀏覽器前綴(例如 -webkit- 或 -moz-),省去手動處理的麻煩。

  6. 巢狀樣式與偽類 你可以像寫 SCSS 一樣,使用巢狀選擇器(&)來撰寫子元素樣式或偽類(如 :hover:focus),讓程式碼更簡潔。

  7. 伺服器端渲染(SSR)支援 styled-components 支援伺服器端渲染,能確保樣式在伺服器端正確渲染,適合用於 Next.js 等框架。


基本使用方式

以下是一個簡單的範例,展示如何使用 styled-components 來定義一個帶樣式的按鈕元件:

import styled from 'styled-components';

// 定義一個樣式化的按鈕元件
const Button = styled.button`
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;

/* 支援偽類 */
&:hover {
background-color: #0056b3;
}

/* 根據 props 動態改變樣式 */
background-color: ${props => (props.primary ? '#28a745' : '#007bff')};
`;

// 在 React 元件中使用
function App() {
return (
<div>
<Button>普通按鈕</Button>
<Button primary>主要按鈕</Button>
</div>
);
}

export default App;

程式碼說明

  • styled.button 創建了一個樣式化的 <button> 元素,樣式寫在反引號(`)中。

  • 樣式中可以使用標準 CSS 屬性,並支援偽類(如 :hover)。

  • 透過 props 可以動態改變樣式,例如當 primary 屬性為 true 時,背景顏色會變成綠色。


進階功能範例

1. 使用 ThemeProvider 管理主題

ThemeProvider 讓你定義全局主題,方便在多個元件中重複使用樣式。

import styled, { ThemeProvider } from 'styled-components';

// 定義主題
const theme = {
colors: {
primary: '#007bff',
success: '#28a745',
},
};

// 定義樣式化的元件
const Button = styled.button`
background-color: ${props => props.theme.colors.primary};
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;

&:hover {
background-color: ${props => props.theme.colors.success};
}
`;

// 在 React 元件中使用 ThemeProvider
function App() {
return (
<ThemeProvider theme={theme}>
<Button>主題按鈕</Button>
</ThemeProvider>
);
}

export default App;

程式碼說明

  • ThemeProvider 將 theme 物件傳遞給所有子元件。

  • 在樣式中透過 props.theme 存取主題中的值(如 colors.primary)。

2. 巢狀樣式

你可以使用 & 來表示當前元件,並撰寫巢狀樣式。

import styled from 'styled-components';

const Card = styled.div`
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;

& h2 {
color: #343a40;
font-size: 24px;
}

& p {
color: #6c757d;
font-size: 16px;
}
`;

function App() {
return (
<Card>
<h2>卡片標題</h2>
<p>這是一段卡片內容。</p>
</Card>
);
}

export default App;

程式碼說明

  • & h2 表示 Card 內部的 <h2> 元素,樣式只會套用到 Card 內的子元素。

3. 繼承樣式

你可以讓一個樣式化的元件繼承另一個元件的樣式,並加以修改。

import styled from 'styled-components';

const Button = styled.button`
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
`;

const LargeButton = styled(Button)`
padding: 15px 30px;
font-size: 18px;
`;

function App() {
return (
<div>
<Button>普通按鈕</Button>
<LargeButton>大型按鈕</LargeButton>
</div>
);
}

export default App;

程式碼說明

  • LargeButton 繼承了 Button 的樣式,並覆蓋了 padding 和 font-size。

優點與適用場景

優點:

  • 樣式封裝:樣式只作用於特定元件,避免全局樣式衝突。

  • 動態性:透過 props 和 state 輕鬆實現動態樣式。

  • 易於維護:樣式與元件寫在一起,方便追蹤和修改。

  • 與 React 高度整合:非常適合 React 專案,尤其是需要元件化開發的場景。

適用場景:

  • 適合用於中大型 React 專案,尤其是需要高度模組化的 UI 元件。

  • 當你需要動態樣式(例如根據使用者輸入或狀態改變樣式)。

  • 當你希望樣式與元件緊密結合,避免管理多個 CSS 檔案。


注意事項

  1. 學習曲線:如果你不熟悉 JavaScript 模板字面量或 React props,可能需要一點時間適應。

  2. 效能考量:在大型專案中,過多的動態樣式可能影響渲染效能,建議適度使用。

  3. 與其他 CSS 方案的比較

    • 相較於傳統 CSS/SCSS,styled-components 更適合元件化開發,但可能不適合需要大量靜態樣式的專案。

    • 相較於 Tailwind CSS,它更靈活於動態樣式,但語法不如 Tailwind 簡潔。


總結

styled-components 是一個強大且靈活的工具,特別適合用於 React 專案中管理元件樣式。它的語法直觀、支援動態樣式,且與 React 的元件化理念高度契合。透過簡單的學習,你可以快速上手,並打造出乾淨、可維護的 UI 元件。