Coding Hero

We solve your problems

React Style 各種CSS使用方式 Part1 - inline style

2019-10-16 Stevenreact

Banner

HI, I’m Steven

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

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



Inline style

這個方法相信只要寫過 React 或任何 HTML 相關程式碼的大家一定都不陌生
下面就簡單示範一下,相信只要看過就馬上知道在寫什麼

HTML

<div style="background-color:red">

React Component

const Panel = () => (
    <div style={{backgroundColor:'red'}}>
)

從上面這兩行,我相信大家也明顯發現不一樣的地方了 簡單整理一下 React inline style 的基本規則。
然後就來看看可以怎麼在 React 裡面撰寫 CSS 吧

  1. React 中的 inline style 是使用 JS 的物件來表示
  2. CSS 的關鍵字是使用駝峰命名的方式宣告為物件屬性
  3. 屬性的數值一律為字串


Code sample version 1

那麼知道規則後,我們就開始寫幾個範例試試看吧
這邊我想要簡單做一個 Panel Box 樣式
再來看看寫法上可以有什麼不同的變化

const Version1 = () => (
  <div
    style={{
      width: "250px",
      height: "250px",
      boxShadow: "2px 2px 12px -1px rgba(0,0,0,0.3)",
      padding: "5px",
      boxSizing: "border-box",
      position: "absolute",
      backgroundColor: "#ffc125",
      color: "#fff",
      left: "50%",
      top: "50%",
      transform: "translateX(-50%) translateY(-50%)",
      borderRadius: "10px"
    }}
  >
    Version1 Version1 Version1
  </div>
)

OK 這邊應該沒什麼問題,使用了幾個常見的 CSS 樣式設計一個 Panel Box
並且以 javascript 物件傳入到 div style 裡面
比較值得一提的應該只有垂直置中的方式
這邊使用的是透過 top,left 偏移量的方式
而非使用上相較好用的 flex 樣式來處理而已

panel

效果大概是這樣


Code sample version 2

到這邊我就開始在想,那如果我的畫面有很多個 Panel Box
難道我需要到處複製貼上這整串的 CSS 物件嗎
(正常情況當然是 export import component 做使用就好,這邊就先假裝一下吧 🤣🤣🤣)
於是就想到竟然都是 JS 物件,那我就可以將樣式拆成獨立物件(檔案)來使用
於是乎版本 2 就誕生了

// style object
const panel = {
  width: "250px",
  height: "250px",
  boxShadow: "2px 2px 12px -1px rgba(0,0,0,0.3)",
  padding: "5px",
  boxSizing: "border-box",
  position: "absolute",
  backgroundColor: "#fcfcfc",
  left: "50%",
  top: "50%",
  transform: "translateX(-50%) translateY(-50%)",
  borderRadius: "10px"
}
// component
const Version2 = () => (
  <div style={{ ...panel, backgroundColor: "rgba(255,193,37,0.4)" }}>
    Version2 Version2 Version2
  </div>
)

(或是使用檔案 export object 的方式)

export const panel = {
  width: "250px",
  height: "250px",
  boxShadow: "2px 2px 12px -1px rgba(0,0,0,0.3)",
  padding: "5px",
  boxSizing: "border-box",
  position: "absolute",
  backgroundColor: "#fcfcfc",
  left: "50%",
  top: "50%",
  transform: "translateX(-50%) translateY(-50%)",
  borderRadius: "10px"
}

除了可以將物件抽離出 component 外,如果想要在添加額外的 CSS style 也可以透過 Javascript 解構賦值的方式直接在後面繼續添加即可 是不是很方便啊 😎😎

什麼 ⁉️ 你說不知道可以怎麼應用 🙀🙀🙀
好吧,那我們就寫一個最簡單應用方式看看吧
相信看完之後應該就有點 feel 了~~~~~

// style object
const flexCenter = {
  display: "flex",
  justifyContent: "center",
  alignItems: "center"
}
// component
const Version2 = () => <div style={{ ...flexCenter }}>Version2</div>


Code sample version 2-1

接著我突然想到在 Jabascript 在 ES6 語法糖裏頭
如果物件定義的 key 與給予的變數 variables 名字相同,則可以省略不寫
什麼意思呢? 🧐🧐🧐 來看一下程式碼吧

// ES5
var cat = "Miaow"
var someObject = {
  cat: cat
}
// ES6
var cat = "Miaow"
var someObject = {
  cat
}

也就是說,在 Version2 裡面我所設定 backgroundColor 也可以拉出來宣告,在直接使用就好摟 於是乎就可以在改寫成這樣~~~

const backgroundColor = "rgba(255,193,37,0.4)"

const Version2_1 = () => (
  <div style={{ ...panel, backgroundColor }}>Version2_1 Version2_1 Version2_1</div>
)


Code sample version 3

這時候我突然想到,那如果我有很多個 Panel Box
而且我希望每個背景顏色都想要設定成不一樣
不就要寫一堆 const backgroundColor = “XXXXXX” 了嗎
所以我就想說那如果包成 function 帶入參數後回傳 Object 呢
於是乎版本 3 就出現了~~

// style function
const panel = backgroundColor => ({
  width: "250px",
  height: "250px",
  boxShadow: "2px 2px 12px -1px rgba(0,0,0,0.3)",
  padding: "5px",
  boxSizing: "border-box",
  borderRadius: "10px",
  backgroundColor
})
// component
const colors = ["#fff49c", "#0c2f39", "#ff7373", "#b7e0df"]
const Version3 = () => {
  return (
    <div style={{ ...container }}>
      {colors.map(color => {
        return (
          <div
            style={{
              ...panel(color),
              border: "solid 3px #aed6cf"
            }}
          >
            Version3 Version3 Version3
          </div>
        )
      })}
    </div>
  )
}

這邊主要是將原本的 object 改寫為 function 呼叫使用後回傳一個 object
於是我將色碼直接拉到一個陣列裡面
透過一個 array map() 迴圈讀取陣列的色碼帶入 panel() 方法裏頭
最後渲染出 4 個不同顏色的 Panel Box
並且在原本 CSS 中稍微挑整排版的方式



總結


優點 🎉

  • 基本上 Inline style 的 CSS 權重是最高的 (除了 important 跟 important)
  • 可以方便快速測試 CSS 效果是不是自己要的
  •  只要帶入物件即可 (意味者可以自己寫 Javscript 來處裡)

缺點 💩

  • 無法使用 Emmet 語法快速編輯 CSS 樣式表
    (Ex : background-color ==> bgc + tab 展開)
  • 給予的數值沒辦法透過編輯器的 autocomplete 來自動完成
    (因為全部都視為字串)
  • 無法撰寫 media screen 來達成 RWD 相應式網頁
    (這點我想目前不管是 HTML,或是 React Component 其實都是一樣的)


OK
那麼以上就是我目前在 React Project 內使用 inline-style 的筆記跟大家分享
雖然這個方法其實我自己在專案上真的滿少用的 (🙈🙈🙈 逃…
主要是因為本身寫 SCSS 已經非常習慣
不是不好,只是對我而言這種方式不是我最有效率的方式罷了
所以還是記錄一下,也算另類 練習一些對於 Javascript 物件上的使用技巧
在最下方的參考資料有附上 codesandbox 的完整範例

下一章就來講講我自己最常用(個人覺得最好用)的方式
➡️➡️➡️React Style 各種 CSS 使用方式 Part2 - include style file

有幫助的話也請記得多幫忙分享
當然有疑問或是內容有誤的地方也歡迎大家提出一起討論
👏👏👏👏👏



參考資料

codesanbox 完整範例 - http://bit.ly/31lFLk1

Youtube - http://bit.ly/35NZfBo

Javascript ES6 Object syntax - http://bit.ly/2MK1axX