iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
自我挑戰組

React 30 天學習歷程系列 第 8

【Day 8】CSS 處理方案(二)

postcss

postcss 是一款允許使用 JS 套件來轉換 CSS 的工具集合,例如 autoprefixer(會添加一些瀏覽器的前綴)、cssnext(可以寫一些較新的 css 語法)、postcss-modules (其實跟 css-module 差不多功用,但是做成套件),這些都是由對應的 postcss 套件去實現的,這篇裡面會整理一些常用的插件。

autoPrefixer

autoPrefixer 是 postcss 相當流行的套件之一,會自動添加 CSS 屬性兼容瀏覽器的前綴,create-react-app 中默認支持 autoPrefixer。下面的範例中 .box 經過 autoPrefixer 編譯,會將原本的 transform 添加上 -webkit 的版本,這樣就能支援 chrome 以及 safari 瀏覽器上的渲染。

.box {
    transform: rotate(180deg);
}
// 經過編譯後轉為
.box {
    -webkit-transform: rotate(180deg); 
    transform: rotate(180deg);
}

postcss-cssnext

postcss-cssnext 讓使用者可以使用比較新的語法,例如 CSS4。這邊的範例是使用 var 變數來自定義 CSS 屬性,以方便調用,使用方式和 sass 中的變數用法很像。

// 自定義 --primaryColor
:root {
    --primaryColor: #939393;
}

// 使用 var 來調用 --primaryColor
.title {
    font-size: 18px;
    color: var(--primaryColor);
}

//編譯後
.title {
    font-size: 18px;
    color: #939393;
}

cssnano

cssnano 是一個壓縮 CSS 用的套件,會自動去除掉註解或是重複的 CSS 屬性。

css-in-js & styled-components

css-in-js 實際上就是用 js 來寫 CSS 代碼,目前已經有些套件在使用,如 styled-components、emotion 等。以 styled-components 為例,它結合了 css-module、autoprefixer 的精髓,甚至還可以模組化 CSS,是目前 css-in-js 中主流的方案之一,有著以下的特點:

  • 唯一 class 名:和 css-module 類似的方式,生成唯一的 class 名,避免汙染全域 CSS。
  • 沒有多餘的 CSS 代碼:styled-components 的樣式和組件是綁定的,如果沒有調用組件樣式就不會起作用,因此不用去擔心是否有多餘的 CSS 代碼。
  • 動態樣式:styled-components 可以很簡單的拓展並調整 CSS 樣式,不需要建立許多 class 來維持樣式。
  • 自動添加瀏覽器兼容性前綴,類似 autoprefixer。
  • 支持使用變數和繼承。

安裝 styled-components

styled-components 跟許多 JS 套件一樣,下載安裝即可使用,安裝指令如下

yarn add styled-components

styled-components 基本使用方法

styled-components 提供了一系列的標籤函式,例如 button, h1, h2, div, p 等等,標籤函式調用時會生成相應的標籤元件,如 Button, Div 等,並且可以賦給變數,任意命名。這其實是運用 ES6 中的標籤模板語法,函式有一種透過字串調用傳參數的方式,例如下面有一個函式,參數為 123

getPhone(123)

// 字串寫法
getPhone`123`

styled-components 基本的用法就是使用標籤函式,如其中的 styled,裡面就有許多標籤函式,下面的範例我們調用 h1 來使用

import styled from 'styled-components';

const Title = styled.h1`
    font-size: 22px;
    text-align: center;
    font-weight: 600;
`;

<App>
    <Title>這是標籤組件,會帶入 Title 中的 h1 和 css 屬性</Title>
</App>

最終當這個 Title 組件在網頁上渲染出來會像下面的範例,有 h1 標籤,並且裡面生成一個 hash class(不會有重複命名),同時這個 class 的屬性,就是我們上面看到的 Title 的 CSS 屬性。

<div>
    <h1 class="bzvmhr">這是標籤組件,會帶入 Title 中的 h1 和 css 屬性</h1>
</div>

CSS 巢狀寫法

styled-components 也支持 sass 的巢狀寫法,如下面在 Content 元件中去定義第一層 h1.description 的 CSS 屬性

import styled from 'styled-components';

const Content = styled.div`
    font-size: 14px;
    text-align: left;
    font-weight: 400;
    > h1 {
        font-size: 22px;
        text-align: center;
        font-weight: 600;
    }
    > .description {
        color: #939393;
    }
`;

<App>
    <Content>
        <h1>Title</h1>
        <div className="description">Description</div>
    </Content>
</App>

傳遞 props 屬性

由於 styled-components 使用的其實是 CSS 元件化的概念,因此也有 props 可以傳送參數,並且可以根據傳遞的參數去改變元件使用的 CSS 屬性

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

//  styled.button`` 相當於 styled.button() 函式調用的方式,但是在執行完之後,會得到一個 React 元件,裡面已經包含了 css 樣式,因為是元件,所以也有 props 屬性可以傳遞參數
//  props 會引用傳遞的參數,如果有該參數,就會執行後面的 css function, css function 是 styled-components 提供的一個方法
const Button = styled.button`
    background-color: blue;
    color: white;
    ${props => props.primary && css `
        background-color: ;
        color: ;
    `}
`
// 第二個 Button 透過 props 傳遞 primary 參數,得到 primary 樣式
const App = (props) => {
    return <div className="wrap">
        <Button>送出</Button>
        <Button primary>送出</Button>
    </div>
}

拓展樣式元件

若是原本已經有一個元件,在其他地方調用時想增加新的樣式或改變一些原有樣式,也可以利用 styled() 方法調用到新元件上做拓展,如下面的範例,我們在 ProductTitle 中調用 Title 元件,並更改新增 CSS 屬性

import styled from 'styled-components';

const Title = styled.h1`
    font-size: 22px;
    text-align: center;
    font-weight: 600;
`;

const ProductTitle = styled(Title)`
    font-size: 16px;
    color: #33333;
`;

<App>
    <Title>我是拓展前的 Title</Title>
    <ProductTitle>我是拓展後的 Title</ProductTitle>
</App>

拓展元件樣式

假如原本有一個普通的元件,在其他地方使用時想增加 CSS 屬性,也可以用 styled() 來調用並賦予 CSS 屬性

import styled from 'styled-components';

const Menu = () => {
    return (
        <ul>
            <li>link1</li>
            <li>link2</li>
        </ul>
    )
}

const PrimaryMenu = styled(Menu)`
    font-size: 16px;
    color: white;
    background: blue;
`;

<App>
    <Menu>我是拓展前的 Menu</Menu>
    <Menu>我是拓展樣式後的 Menu</Menu>
</App>

小結

這篇整理了 postcss 和 styled-components,下一篇開始會整理 React 中 class component 及 function component 的差異與使用方式。


上一篇
【Day 7】CSS 處理方案(一)
下一篇
【Day 9】React 元件寫法
系列文
React 30 天學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言