---
# System prepended metadata

title: CSS Scoped

---

# CSS Scoped

## :memo: Carco 安裝

### Step 1: 安裝 Carco
```
npm install @craco/craco --save
```
### Step 2: 安裝 craco-plugin-scoped-css 套件
```
npm i craco-plugin-scoped-css --dev
```
### Step 3: 根目錄新增`craco.config.js` 
```
module.exports = {
  plugins: [
    {
      plugin: require('craco-plugin-scoped-css')
    }
  ]
}
````
### Step 4: 修改`package.json`
> 用`crao`執行設定檔`craco.configs.js`來執行`react` [color=#ff871d]
>
![](https://i.imgur.com/2HYYRqf.png)
## :memo: 執行
```
npm start
```
## :memo: craco-plugin-scoped-css 使用說明
### 將 .css ( scss/sass ) 更改成 .scoped.css ( scss/sass ) 
![](https://i.imgur.com/udGhMg6.png)
### 用套件的效果
> 使用前 [color=#ff871d]

![](https://i.imgur.com/k6DBXDl.png)

![](https://i.imgur.com/s94nUY9.png)
> 使用後 [color=#ff871d]

![](https://i.imgur.com/KxSPJRf.png)

![](https://i.imgur.com/OF2YFx0.png)

可以看到有上`scoped`會增加一組唯一的`data-v-<hash>`屬性

## :memo: Css Scpoed 基礎用法
### 為什麼要使用 Css Scoped?
使用 Css Scoped 能讓 Css 有一個唯的`data-id`，再引入 scoped 的元件中，能不污染其他的元件，讓每個元件擁有屬於自己的 css 。

舉個例子：
假設有 A . B 各別有`.box`的元件
> 沒有使用 css scoped[color=#ff871d]

假如在 Ａ 沒有引入`a.scss`，而在 B 有引入。

![](https://i.imgur.com/FDq7CFJ.png)

![](https://i.imgur.com/Utip2i5.png)

> 輸出結果[color=#ff871d]

![](https://i.imgur.com/pexsCYl.png)
結果， A . B 都吃到`a.scss`。
### 為什麼會有這樣的結果?
因為目前的`a.scss`是`全域的`，只要引入整個檔案都吃得到。
### 解決辦法
這時候就是需要用到 Css Scoped。
> 有使用 css scoped[color=#ff871d]

在 A . B 元件各別引入 a 及 b `scoped.scss`。

![](https://i.imgur.com/etaqgrr.png)

![](https://i.imgur.com/TMZ4yXQ.png)

> 輸出結果 [color=#ff871d]

![](https://i.imgur.com/63YyHYi.png)
![](https://i.imgur.com/2OjbX2G.png)

這時候，可以看到上面的圖，A . B 就變擁有各別的`dada-id`，獨一無二的 Scoped Css ，不會互相影響。
## :memo: Css Scpoed 進階用法
假設有 Parent . Child 兩個元件，如果想讓父元件修改子元件的css，將其文字顏色由白色改成紅色，這時候怎做？

> 直接使用 css [color=#ff871d]

直接在父元件上引入`.scss`

![](https://i.imgur.com/NyStFmy.png)

![](https://i.imgur.com/K7sgYDs.png)

![](https://i.imgur.com/ZZVROF2.png)
> 輸出結果 [color=#ff871d]

![](https://i.imgur.com/0qjHsog.png)
可以看到，確實能修改子元件的 css ，但是這就會影響到一開始所說的，`css`會是`全域的`，會影響到其他的元件，這不是好的運用。
### 那直接改用 Css Scoped 可以解決問題？
> 在使用 css scoped [color=#ff871d]

直接在父元件上引入`.scoped.scss`

![](https://i.imgur.com/2n4My2q.png)

![](https://i.imgur.com/r5MfvIm.png)

![](https://i.imgur.com/PHxuf92.png)

> 輸出結果 [color=#ff871d]

![](https://i.imgur.com/75KwpKZ.png)

可以看到子元件並沒有使用到 css

### 為什麼會有這樣的結果?
因為使用`Css Scoped`只會再`當前的元件運行`，不會`滲透至子元件`，所以才導致子元件的 css 有運用卻沒有效果。
### 解決辦法
這時後要用的方式，就是以父元件的 `/deep/`強制讓他滲透至子元件。
> 在使用 /deep/[color=#ff871d]

在`.parentBox`上加上`/deep/`

![](https://i.imgur.com/ilZvDtN.png`)

:::danger
＊可以看到`.childBox`要寫在`.parentBox`裡面，因`/deep/`一定要有個父的 css 讓它流入子層的 css。
:::

> 輸出結果 [color=#ff871d]

![](https://i.imgur.com/q8CjMSS.png)
這時候輸出結果就有子元件的 css 效果了。
### 為什麼要學這個？
平時在使用 UI 框架(Bootstrap.Material...內部等)，想要`客製化內部樣式`，這時候就可以運用到上面的方法，既不影響其他元件，又能達到目的。

> 以 Material 為例[color=#ff871d]

舉個例子：
假如有個父元件`.parentCss`要修改`MaterialUI` `Button`元件中的 `.MuiButton-label`，想將其文字顏色從白色改成紅色。

![](https://i.imgur.com/0mjfZJY.png)

![](https://i.imgur.com/72ijhQa.png)

> 在沒使用 /deep/[color=#ff871d]

![](https://i.imgur.com/KFaBWuv.png)

> 輸出結果[color=#ff871d]

![](https://i.imgur.com/eV18xZc.png)

可以看到`Button`文字顏色並沒被改變。
> 在有使用 /deep/[color=#ff871d]

![](https://i.imgur.com/iCxMQAc.png)
> 輸出結果 [color=#ff871d]

![](https://i.imgur.com/bdapyyB.png)

可以看到，加入`/deep/`後，就可以`滲透至子元件`，將文字改成紅色，達成需要的效果。
## :memo: 資料來源
資料來源：
**[GitHub-Craco]:** https://github.com/gsoft-inc/craco/blob/master/packages/craco/README.md#installation
**[react-scoped-css]:** https://dev.to/viclafouch/how-to-scope-your-css-scss-in-react-js-271a
**[Css-Scoped demo]:** https://github.com/wheatCode/Css-Scoped


