你懂製程嗎?我懂CSS啦!-CSS快速導覽
你懂製程嗎?不不不…我懂CSS啦!!寫網頁的人,怎麼可以不懂CSS呢?
什麼?你不懂CSS?下面一位~(X
這次來跟大家分享的是,CSS從古至今的演化,儘管很多近代大家常用的技術,在早期其實很多人都已經提出來了。
但是有價值的技術需要在適當的時機才能發揮它最大的價值。
以下就來帶大家介紹分享一些CSS的知識吧!
石器時期的CSS
CSS reset
在早期的CSS2.0的時期,Eric Meyer釋出了一個CSS Reset解決了不同瀏覽器擁有各自預設CSS樣式的問題。
這是一個很簡短的CSS,但是初始化了大部分開發常用的tags。
1 | /* http://meyerweb.com/eric/tools/css/reset/ |
通常我們會先將CSS reset載入之後,才會開始開發自己的CSS。
是新手練習的最佳夥伴。
Normalize CSS
但是CSS reset載入之後,會衍生出一些問題。
例如:瀏覽器的Bug, 把需要用到的預設都清除了……
所以這個時候,Normalize CSS就是這些問題的solution。
其實有很多UI framework也是使用Normalize CSS在開發
例如:Antd, Bootstrap, ……
關於Bootstrap使用的CSS
我們可以從Bootstrap的主要SCSS中查看他們是使用CSS reset還是Normalize。
最後你會在reboot.scss裡面查看到他們是使用哪一個:
1 | // Reboot |
意思是,Boostrap是從Normalize fork出一份CSS去改寫的。
因此從原始碼可以得知,Bootstrap是使用Normalize CSS。
CSS specificity
在CSS中,CSS specificity是很重要的觀念,如果新手不熟CSS的話,很常會鬼打牆,覺得為什麼改了樣式卻沒有變化。
其實是因為CSS在使用上會有優先權的問題。
通常我們會記以下的順序:
1 | element < class < inline-style |
如果不好記的話,可以看圖像加深自己的記憶:
補充:
- 通常我們不會用ID來寫CSS,ID通常會被當作是anchor,因此在談CSS時,我們時常忽略它。
- 我們在寫CSS時,盡量會把CSS寫在CSS檔案裡面,盡量不使用inline-style。
除非你要覆蓋framework的Normalize CSS或是開發EDM的CSS才比較會用到inline-style開發。
關於EDM的CSS支援,請參考這邊
由於EDM有很多支援的限制,所以有些場合需要用比較土炮的方式去開發,以支援每個信件,例如:outlook。
(之後我會出一篇文章教大家如何開發支援各個信件的網頁) - 這邊你會看到important對吧?這個是最強大的殺手鐧,只要用下去,只有important才可以對抗important。
所以開發者也盡量不要用這個語法,不然當你要覆蓋相同class的時候,你會很痛苦,例如:手機版網頁。
這邊也要補充一下,其實Bootstrap的CSS事實上也用了不少important,因此當你改不動樣式的時候,需要用到它。
封建時期的CSS
當大家開發CSS開發到最後一定會發現,CSS每次寫都會一大坨,可能大到自己都懷疑人生了。
沒錯,開發CSS不再只是單純的開發出東西來而已,大家開始漸漸地意識到維護性, 整潔性……
以下的範例是石器時期所開發出來的CSS:
1 | .header { |
SASS/SCSS
這還只是一個header的CSS而已,如果是其他結構複雜的component,相信會更長的。
因此,SASS解決了CSS開發上的一些問題。
可以把相關的selector寫在一起,讓管理上更聚焦:
1 | .header { |
但是這個時期的人對很多開發體驗還有很多不滿,程式設計都有越來越多的設計樣式出來了,那麼CSS呢?
我們在設計CSS的時候,可能會遇到很多結構或是元件有重複的屬性,但是這些屬性有其共同的特徵,並且可以重複使用。
如果我們把這樣的概念帶到CSS上,不是可以大大的增加日後的維護性嗎?
這邊舉經典的OOCSS為例:
Object Oriented CSS
當我們把OO的概念帶到CSS上,基本上可以達到:
- 結構分離
- 樣式分離
其實OO用在CSS上是更容易詮釋OO的概念。
以下來看常見的例子:
1 | .button { |
我們在設計程式的時候,可能會有重複的邏輯,但是他們共通點就是具有相同的外觀。
因此我們可以把外觀給包裝起來共用:
1 | .button { |
感覺是不是清爽很多?不僅可以提升reuse,還能達到clean code的效果。
此外,補充一些使用OOCSS要注意的事情:
- 盡量少用後代選擇器(descendent selector)
- 不要使用ID選擇器
- 非必要,不要使用!important
- 可嘗試使用CSS grids
以下補充一些實用的資源:
近代時期的CSS
封建時期的CSS,會開始有很多工具和規範來讓整體的效益更完善,理論上看起來是已經有系統性的可以讓開發體驗更好了。
但是事實並非如此簡單,人們總是追求進步,無法滿足自己的。
網頁設計隨後經歷了各種套件與框架的出現,在現在大家習慣使用框架把HTML寫在JS的時代中,CSS的管理方式也跟著開始有所變化。
CSS的寫法在近代也分成了兩個派別:
- HTML與CSS分離
- HTML與CSS的code分離,比較好管理與分離檔案。
- CSS寫在HTML上
- 比較好管理每個元件的CSS,不會受到global的影響。
其實這兩者都有自己的特點,只是要看專案適合哪一種,大家的共識是什麼。
不管是上面哪一個,基本上只要注意一點,一定要把CSS的邏輯清楚的表達與分離出來,以下介紹。
CSS Modules
有經驗的同學在開發CSS,尤其是跟別人共同開發專案時,一定會遇到你設計的網頁莫名的跑板了。
奇怪,明明就沒有動過呀?怎麼會突然就位移了呢?
這個時候,請你把位移的那個class name拿去search,你會發現你的同伴跟你用了同樣的class selector
而且…還跟你用不一樣的樣式了呢……
這個時候,千萬不要去怪你的夥伴。
因為相信我,如果換作是你,你一定也會犯這種錯。
錯就錯在,CSS在import的時候,是global的!!
以下是範例:
1 | import React from 'react'; |
那該怎麼解決呢?其實很簡單!你只需要使用CSS Modules,而且方法很簡單!
只要包裝成一個模組,然後再分別到每個class去使用就行了:
1 | import React from 'react'; |
你一定會問,那這樣跟寫class有什麼兩樣?
厲害的地方就是在這邊啦!
請打開你的瀏覽器開發工具查看,你會發現class的名字不太一樣:
1 | <h1 class="title_yATCOkg"> |
CSS也會是長這樣:
1 | .title_yATCOkg { |
後面會自動夾帶一串hash,如此一來,只有這個頁面的hash會是一樣的,就不會影響到其他頁面的相同class了!
然後你一定會問一件事情,可是如果想要覆蓋掉global的selector不就沒辦法了嗎?
例如使用Bootstrap, Antd… 想要把樣式覆蓋掉該怎麼做?
答案是可以的!CSS Modules提供global的語法給大家使用:
1 | .title { |
或是你要覆蓋掉framework的Normalize:
1 | :global { |
CSS in JS
不過有另一派的人有不同的觀點,覺得每次都要管理範疇這麼大的CSS覺得心很累,為什麼不把每個元件的CSS都獨立呢?
因此CSS in JS使用的人數也不斷的增加了,流行框架可查看這裡
這邊介紹最具有代表性的 Styled Components。
你不需要再針對elements去設計,撰寫方式很像在做component一樣,把CSS都視為一組一組的概念。
使用方式需要安裝
1
npm install styled-components
使用方式
1
2
3
4
5
6
7import styled from 'styled-components';
const MyContaner = styled.div`
width: 100%;
height: 100%;
background: grey;
`
return <MyContaner>Hello World</MyContaner>;
這樣的好處當然是,讓你的code看起來更清爽,僅管CSS是寫在component裡面也不會影響到整潔與維護性。
而且還有提供props傳遞Attribute進去,以下是官方的範例:
1 | const Button = styled.button` |
結論
統整以上的幾個時期,大概是:
- 石器時期
- 大家開始已知用火,尋找與提出solution。
- 封建時期
- 開始學習制定規範,優化結構,不再只是單純的使用他們。
- 近代時期
- 大家知道使用工具與方法是沒有絕對的好壞與適合,只有適不適合把這幾套用在專案上。
你喜歡用什麼開發模式或是套件呢?歡迎跟我一起分享哦!
meme分享
因為最近看了這部影片,所以才想到要下這個標題:
你問我壓力是不是很大?沒錯,最近壓力真的蠻大的,而且寫這篇文章寫到快脫窗啦~