Coding Hero

We solve your problems

React Style 各種CSS使用方式 Part2 - import style file

2019-11-03 Stevenreact

Banner

HI, I’m Steven

這系列主要想整理一下
自己在開始開發 React 專案之後幾個常用來撰寫 styling 方式
主要會分為幾個系列

今天就來講講 在 React 專案中我自己最常使用撰寫樣式的方式
就是  Import Style File ,直接透過載入 .css(.scss) 樣式檔的方式將樣式加載至專案
也點單介紹一下關於 CSS、SASS、LESS 這幾種目前較常看到撰寫 CSS 的方法
在這篇最後也會簡單整理一下自己在載入 Bootstrap 時及覆寫樣式的方式

那廢話不多說就開始進入今天的正題吧 🤓🤓🤓



CSS 、 (SASS) SCSS、LESS 的差別是什麼

🔸CSS:詠春

🔸SASS(SCSS):詠春-葉問

🔸LESS:詠春-張天志

沒錯,就是這麼簡單 (謎:🤔🤔🤔🤔)
其實不管是 CSS、SASS(SCSS)、LESS 歸根究都算是 CSS(詠春)
只不過  SASS(SCSS) 除了基本的撰寫方式(招式)外,還擁有其他的撰寫方式(拳路)
同樣的  LESS 也是一樣的意思,只是撰寫方式(拳路)與 SASS(SCSS)略有不同
而這些撰寫方式(拳路)可以更方便我們開發專案,讓你可以 1 個打 10 個
當然各個使用方式,語法等等都還是有些許差別

但這並不是今天主題,所以就暫時略過
主要是希望能以最簡單明瞭的方式,讓大家可以理解彼此的區別與關係
(如果有誤也請歡迎留言討論 🤣🤣)



在 React Project 如何使用呢

接下來就來說說在 React Project 到底該如何使用
以及我自己在使用上會去注意的幾個的重點
同樣完整的範例程式碼會放在 Codesanbox 上面
今天只會做一個簡單的明信片樣式作為示範
再來一探各種不同在撰寫方式,那就開始吧 🚀🚀🚀

CSS - Code sample1

用方式其實很簡單,只要將.css、.sass 檔案 import 到.js 檔案即可
但比較要注意的一點是,因為是當專案建置時才進行編譯
所以 import “./style.css” 這段程式碼,不管是放在專案下哪一隻 .js 都會被編譯出來
並沒有說一定要在使用到的 Component 檔案內做 import 才有效果

反之,當專案規模開始變大,樣式變得越來越多越來越複雜時
就要特別注意 import 檔案得位置,才不會出現樣式一直被互相影響得情況

CSS File (style.css)

.card {
  width: 330px;
  height: 200px;
  padding: 20px;
  border: solid 1px #ccc;
  border-radius: 15px;
  background-color: #fff;
  box-shadow: 0 2px 9px -2px rgba(0, 0, 0, 0.3);
}

.card .images-block {
  width: 60px;
  height: 60px;
  border-radius: 10px;
  display: inline-block;
  background-color: rgb(243, 228, 187);
}

.card .name {
  display: inline-block;
  margin-left: 30px;
  color: #5e5e5e;
}

.card .skill {
  background-color: rgba(235, 222, 189, 0.3);
  border-radius: 10px;
  padding: 13px 10px;
  margin: 0;
  margin-top: 10px;
}

.card .skill .skill-item {
  list-style: none;
  margin-bottom: 5px;
  color: #3e3e3e;
  letter-spacing: 1.2px;
}

Component (use-css-sample-1.js)

import React from "react"

import "./style.css"

const UseCssSample1 = () => (
  <>
    <div className="card">
      <div className="images-block" />
      <div className="name">Hi I'm Steven</div>

      <ul className="skill">
        <li className="skill-item">Vue</li>
        <li className="skill-item">React</li>
        <li className="skill-item">Angular</li>
      </ul>
    </div>
  </>
)

export default UseCssSample1

基本用法就是這樣而已,可以想像成只是把原本 HTML 的 < link > 改成 import 的方式而已

Card 畫面得部分大概是這樣



CSS - Code sample2

這邊再來講講另外一引用方式,css module
css 的部分剛上面程式碼內容一模一樣,我們要做的只是將檔名改成 style.module.css
再來就是 component 引用的方式不一樣

🔸 檔名改為 *.module.css
🔸import 方式變更

Component (use-css-sample-2.js)

import React from "react"

import classes from "./style.module.css"

const UseCssSample1 = () => (
  <>
    <div className={classes["card"]}>
      <div className={classes["images-block"]} />
      <div className={classes["name"]}>Hi I'm Steven</div>

      <ul className={classes.skill}>
        <li className={classes["skill-item"]}>Vue</li>
        <li className={classes["skill-item"]}>React</li>
        <li className={classes["skill-item"]}>Angular</li>
      </ul>
    </div>
  </>
)

export default UseCssSample1

可以看到除了 import 方式不同外,包含 className 使用上也不一樣
從原先的字串,修改成使用物件的方式

那麼這麼做的好處到底是什麼呢,明明第一種方式程式碼還寫比較少啊
這麼做最大好處在於可以避免出現相同樣式命名時導致樣式互相覆寫的情況
可以看到在專案建置後執行得效果 class 的部分多了很多前綴詞
這樣當 component 要復用的時候
就可以竟可能避免與其他 component 因樣式命名相同吃到相同樣式設定

html-render-result



使用 SCSS、SASS

接下來我們就再來說說如果要寫 SASS(SCSS)這種預處理樣式該如何使用
在使用 SASS(SCSS)之前,最重要的一件事情就是晏先安裝 node-sass 套件
這樣專案在打包的時候,Webpack 才有辦法辨識.scss 的檔案內容

> npm i node-sass --save

若沒有安裝可能會出現下面錯誤訊息

Warning: unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.

SCSS - Code sample 1

其實使用方式跟使用 CSS 時是一模一樣的,這邊就簡單記錄一下對應到 SCSS 時方式
基本上 SASS 與 SCSS 其實是一樣的東西,只是寫法上的不同
(主要不同一個是使用縮排,一個是使用大括弧)

SCSS File (style.scss)

.card {
  width: 330px;
  height: 200px;
  padding: 20px;
  border: solid 1px #ccc;
  border-radius: 15px;
  background-color: #fff;
  box-shadow: 0 2px 9px -2px rgba(0, 0, 0, 0.3);

  .images-block {
    width: 60px;
    height: 60px;
    border-radius: 10px;
    display: inline-block;
    background-color: rgb(243, 228, 187);
  }

  .name {
    display: inline-block;
    margin-left: 30px;
    color: #5e5e5e;
  }

  .skill {
    background-color: rgba(235, 222, 189, 0.3);
    border-radius: 10px;
    padding: 13px 10px;
    margin: 0;
    margin-top: 10px;

    .skill-item {
      list-style: none;
      margin-bottom: 5px;
      color: #3e3e3e;
      letter-spacing: 1.2px;
    }
  }
}

Component (use-css-sample-1.js)

import React from "react"

import "./style.scss"

const UseScssSample1 = () => (
  <>
    <div className="card">
      <div className="images-block" />
      <div className="name">Hi I'm Steven</div>

      <ul className="skill">
        <li className="skill-item">Vue</li>
        <li className="skill-item">React</li>
        <li className="skill-item">Angular</li>
      </ul>
    </div>
  </>
)

export default UseScssSample1


Component 的部分基本上與使用 CSS 的時候ㄧ模一樣,只是載入檔案從.css 變為 .scss
而在 SCSS File 的部分,由於使用的 SCSS,所以巢狀的結構可以不需要再自己添加了
當然寫過 SCSS 的人一定都知道,SCSS 的格式是可以完全支援 CSS 的
也就是說,即使原本寫好的 CSS 不做任何變更也使可以執行的喔!!

那如果你真的很想把一些舊專案的 CSS 都改為 SCSS 的方式開發
網路也有很多不同的轉換的工具可以使用,譬如

https://www.sass.hk/css2sass/

最後使用 SCSS 的方式,一樣可以使用 *.module.scss 的方式載入
來避免樣式互相干擾的情況喔
用法跟 CSS 的方式一模一樣,所以就在不在多做示範了 😂😂😂



使用 Bootstrap

最後我們來講一下前端好朋友 Bootstrap 的使用方式吧
這邊記錄的主要是我自己本身在開發習慣的用法分享給大家
主要是直接將 Bootstrap scss 的原始碼直接載入
藉此就可以更輕鬆的去覆蓋或是修改 Bootstrap 的預設樣式

首先先在 src 底下新增一個資料夾 assets 並新增檔案 all.scss

src/assets/all.scss

//這個載入順序是不可以隨意變更的,不然會編譯時會報錯誤
//Bootstrap Required
@import "node_modules/bootstrap/scss/functions";
@import "./variables";
@import "node_modules/bootstrap/scss/mixins";

//Bootstrap
@import "node_modules/bootstrap/scss/bootstrap";

接下來可以在 node_modules/bootstrap/scss/ 找到 _variables.scss 的檔案
將他複製一份到 src/assets/ 底下,打開之後就可以看到如下的程式碼
// Variables
//
// Variables should follow the `$component-state-property-size` formula for
// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.

// Color system

$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-600: #6c757d !default;
$gray-700: #495057 !default;
$gray-800: #343a40 !default;
$gray-900: #212529 !default;
$black: #000 !default;

$grays: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
$grays: map-merge(
  (
    "100": $gray-100,
    "200": $gray-200,
    "300": $gray-300,
    "400": $gray-400,
    "500": $gray-500,
    "600": $gray-600,
    "700": $gray-700,
    "800": $gray-800,
    "900": $gray-900
  ),
  $grays
);

$blue: #007bff !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #e83e8c !default;
$red: #dc3545 !default;
$orange: #fd7e14 !default;
$yellow: #ffc107 !default;
$green: #28a745 !default;
$teal: #20c997 !default;
$cyan: #17a2b8 !default;

//another code.....


這時候可以幹嘛呢?? 😎😎😎😎
這時候我們舊可以大幅度修改 Bootstrap 的基本樣上,包含主色系,字體大小等等等
甚至最常使用的 grid system,是不是常常覺得 col 只有 12 欄不夠用不好用
你可以自己修改要以幾欄來作為區隔基準
這樣是不是就可以更方便快速做到更多客製化開發了呢

//盡量將原本的設定註解在後方,以防需要改回來時不知道原先設定
$grid-columns: 16 !default; //12 !default;


那如果你想修改的不只是基本的一些參數,是想要直接修改譬如 card 這個樣式設計呢
我自己的做法會在 src/assets/ 目錄下直接在新增一個 _card-rewrite.scss 的檔案
再將檔案加載到 all.scss 的最後一行來做複寫
這樣就可以簡單的來覆寫樣式,也可以簡單的做到管理及復原

/src/assets/_card-rewrite.scss

.card {
  background: red;
}

src/assets/all.scss

//這個載入順序是不可以隨意變更的,不然會編譯時會報錯誤
//Bootstrap Required
@import "node_modules/bootstrap/scss/functions";
@import "./variables";
@import "node_modules/bootstrap/scss/mixins";

//Bootstrap
@import "node_modules/bootstrap/scss/bootstrap";

//Style Rewrite
@import "./card-rewrite";

最後只要在專案入口處載入 all.scss 即可

index.js or App.js

import React from "react"
import "./assets/scss/all.scss"


總結

這篇就到這邊結束摟
從基本的 CSS 載入的使用,到 module 的方式來避免樣式命名重複可能會導致的問題
再到改用 SCSS 這樣的 CSS 預處理方式進行樣式的撰寫
最後也分享一下自己在使用 Bootstrap 時的引用方式

其實在撰寫樣式的時候,有時候都覺得比寫 JS 的程式碼還要更麻煩了
尤其是命名重複,調整對其位置,或是有些樣式一改就整個專案都大跑版
所以自己也是一直在嘗試各種不同方式,希望可以找到各種專案最合適的開發方式

下週沒意外的話,希望可以繼續分享 style component 的使用

因為這幾週負責的案子實在是幾番波折
從原本客戶自行發包後端,到後來人跑掉要交由我們處理另外找外包,到最後自己需要接手回來處理
加上又是要使用沒用過的 AWS Amplify 來架設後端各種服務,頓時真的是忙炸
不過這樣也不錯,剛好可以借客戶的帳號好好把玩一下 AWS 的各種服務
希望接下來也可以分享一些 AWS Amplify 和其他服務的使用心得



參考資料

codesanbox 完整範例 - http://bit.ly/2JLMsFY



#React #CSS #SASS #SCSS #Style #Css Module #Bootstrap