現代CSS進化史

繆斯的情人發表於2018-04-09

  CSS一直被web開發者認為是最簡單也是最難的一門奇葩語言。它的入門確實非常簡單——你只需為元素定義好樣式屬性和值,看起來似乎需要做的工作也就這樣嘛!然而在一些大型工程中CSS的組織是一件複雜和凌亂的事情,你更改頁面上任意一個元素的一行CSS樣式都有可能影響到其他頁面上的元素。

  為了解決CSS錯綜複雜的繼承問題,開發者建立了各種不同的最佳實踐,問題是哪一個最佳實踐是最好的目前尚無定論,而且有些實踐相互之間是完全矛盾的。如果你第一次嘗試學習CSS,這對於你來說是相當迷惑的。

  這篇文章的目的是通過回顧CSS的歷史背景,介紹下時至2018年的今天CSS發展過程中的一些設計模式和工具的演變。通過對這些背景的理解,你將會更輕鬆的理解每個設計思想並且學以致用。接下來讓我們開始吧!

 CSS基本樣式使用

  我們從一個最簡單的網頁index.html 開始,這個檔案中包含一個獨立的樣式檔案index.css:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Modern CSS</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <header>This is the header.</header>
  <main>
    <h1>This is the main content.</h1>
    <p>...</p>
  </main>
  <nav>
    <h4>This is the navigation section.</h4>
    <p>...</p>
  </nav>
  <aside>
    <h4>This is an aside section.</h4>
    <p>...</p>
  </aside>
  <footer>This is the footer.</footer>
</body>
</html>

  上面的HTML標籤中沒用使用任何class或者id。

  在沒有任何CSS樣式的情況下,我們的網站看起來是這個樣子:


點選檢視線上demo

  功能可用,但看起來不好看,我們可以繼續在index.css加點CSS美化下排版:

/* BASIC TYPOGRAPHY                       */
/* from https://github.com/oxalorg/sakura */
html {
  font-size: 62.5%;
  font-family: serif;
}
body {
  font-size: 1.8rem;
  line-height: 1.618;
  max-width: 38em;
  margin: auto;
  color: #4a4a4a;
  background-color: #f9f9f9;
  padding: 13px;
}
@media (max-width: 684px) {
  body {
    font-size: 1.53rem;
  }
}
@media (max-width: 382px) {
  body {
    font-size: 1.35rem;
  }
}
h1, h2, h3, h4, h5, h6 {
  line-height: 1.1;
  font-family: Verdana, Geneva, sans-serif;
  font-weight: 700;
  overflow-wrap: break-word;
  word-wrap: break-word;
  -ms-word-break: break-all;
  word-break: break-word;
  -ms-hyphens: auto;
  -moz-hyphens: auto;
  -webkit-hyphens: auto;
  hyphens: auto;
}
h1 {
  font-size: 2.35em;
}
h2 {
  font-size: 2em;
}
h3 {
  font-size: 1.75em;
}
h4 {
  font-size: 1.5em;
}
h5 {
  font-size: 1.25em;
}
h6 {
  font-size: 1em;
}

  這地方大部分都是關於排版(字型、行高等)樣式的定義,也包含一些顏色和一個layout居中設定。為了讓每個屬性有個合理的值你需要學習點設計理論,但是這個地方我們用到的CSS本身並不複雜,你可以直接定義,結果如下所示:


Click here to see a live example

  有所變化了吧!正如CSS許諾的一樣——用一種簡單的方式給文件新增上樣式,不需要程式設計或者複雜的業務邏輯。不幸的是,實際情況會複雜的很多,我們不單單使用的是CSS的排版和顏色這種簡單的樣式定義。

 CSS的佈局使用

  在20世紀90年代,CSS還未廣泛普及之前,對於頁面的佈局沒有太多的選擇。HTML最初是被設計為建立純文字的一門語言,並不是包含側邊欄、列等佈局的動態頁面。早期的時候,頁面佈局通常使用的是HTML表格,在行和列中組織內容,這種方式雖然有效,但是把內容和表現雜糅在一塊了,如果你想改變網頁的佈局就得需要修改大量的HTML程式碼。

  CSS的出現推動了內容(寫在HTML中)和表現(寫在CSS中)的分離,人們開始把所有的佈局程式碼從HTML中移除放入到CSS中,需要注意的是,和HTML一樣CSS的設計也不是用來做網頁內容佈局的,所以早期的時候試圖解決這種分離設計是很困難的。

  我們來用個實際例子來看下如何實現佈局,在我們定義CSS佈局前先重置下padding和margin(會影響佈局的計算),不同的區域我們定義不同的顏色(不要太在意好看不好看只要不同區域間足夠醒目就可以)

/* RESET LAYOUT AND ADD COLORS */
body {
  margin: 0;
  padding: 0;
  max-width: inherit;
  background: #fff;
  color: #4a4a4a;
}
header, footer {
  font-size: large;
  text-align: center;
  padding: 0.3em 0;
  background-color: #4a4a4a;
  color: #f9f9f9;
}
nav {
  background: #eee;
}
main {
  background: #f9f9f9;
}
aside {
  background: #eee;
}

  現在頁面應該看起來如下:


Click here to see a live example

  接下來我們用CSS來佈局下頁面內容,我們將按照時間順序採用三種不同的方式,先從最經典的浮動佈局開始吧。

  基於浮動的佈局

  CSS浮動屬性最初是為了將圖片浮動在一列文字的左側或者右側(報紙上經常看到)。早在21世紀初,web開發者將這個屬性的優勢擴充套件到了任意的元素,這意味著你可以通過div的內容浮動建立出行和列的錯覺。同樣,浮動也不是基於這樣的目的設計的,所以相容性上會有很多問題。

  2006年,A List Apart上發表了一篇熱門文章In Search of the Holy Grail,文章概述了實現聖盃佈局的詳細方法——一個頭部、三列內容和一個底部,你一定覺得一個簡單的佈局被稱為聖盃佈局很瘋狂吧,但是在當時純CSS的時代這的確很難實現。

  下面是一個基於浮動佈局的例子,用到了我們文章中提到的一些技術點:

/* FLOAT-BASED LAYOUT */
body {
  padding-left: 200px;
  padding-right: 190px;
  min-width: 240px;
}
header, footer {
  margin-left: -200px;
  margin-right: -190px;   
}
main, nav, aside {
  position: relative;
  float: left;
}
main {
  padding: 0 20px;
  width: 100%;
}
nav {
  width: 180px;
  padding: 0 10px;
  right: 240px;
  margin-left: -100%;
}
aside {
  width: 130px;
  padding: 0 10px;
  margin-right: -100%;
}
footer {
  clear: both;
}
* html nav {
  left: 150px;
}

  仔細看下CSS程式碼,這裡面為了讓它工作包含一些必須的hack方式(負邊距、clear: both、硬編碼的寬度計算等),稍後我們會對這些細節做詳細的解釋。最終的結果如下:


Click here to see a live example

  看起來不錯了,但是通過三列的顏色可以看出來他們的高度不一樣,頁面的高度也沒有填充滿螢幕。這些問題是浮動佈局導致的,所有的浮動只是將內容放在某一區塊的左邊或者右邊,但是沒法知道其他區塊的高度。這個問題一直沒有個好的解決方案,直到Flexbox佈局的出現。

  基於Flexbox的佈局

  flexbox CSS屬性實在2009年第一次提出來的,但直到2015年才得到瀏覽器的廣泛支援。Flexbox被設計為定義一個空間在行或者列上如何分佈的,這讓它比浮動更適合用來做佈局,這意味在使用浮動佈局十多年後,web開發者終於不再使用帶有hack的浮動佈局方式了。

  下面是一個基於Flexbox佈局的例子。注意為了讓flexbox生效我們需要在三列的外面額外包裝一個div:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Modern CSS</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <header>This is the header.</header>
  <div class="container">
    <main>
      <h1>This is the main content.</h1>
      <p>...</p>
    </main>
    <nav>
      <h4>This is the navigation section.</h4>
      <p>...</p>
    </nav>
    <aside>
      <h4>This is an aside section.</h4>
      <p>...</p>
    </aside>
  </div>
  <footer>This is the footer.</footer>
</body>
</html>

  下面是flexbox佈局的CSS程式碼:

/* FLEXBOX-BASED LAYOUT */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.container {
  display: flex;
  flex: 1;
}
main {
  flex: 1;
  padding: 0 20px;
}
nav {
  flex: 0 0 180px;
  padding: 0 10px;
  order: -1;
}
aside {
  flex: 0 0 130px;
  padding: 0 10px;
}

  這種方式和浮動佈局相比更加緊湊了,雖然flexbox一些屬性和值初看起來有些困惑,但是好歹不需要像浮動佈局那樣負邊距的hack方案了,這是個巨大的進步。最終結果如下:


Click here for a live example

  效果好多了!所有的列高度都相同,並且佔據了整個頁面的高度。從某種意義上來說這似乎是完美的了,但是這個方式也有些小問題,其中一個就是瀏覽器的相容性——主流的現代瀏覽器都支援flexbox,但是一些舊的瀏覽器不相容。幸運的是瀏覽器廠商也正在盡最大努力終止對舊版本瀏覽器的支援,為web開發者提供更一致的開發體驗。另一個問題是我們需要<div class="container">包裹HTML內容標籤,如果能避免會更完美。理想狀態下,任何CSS佈局都不需要改變HTML標籤的。

  最大的缺點是CSS程式碼本身——flexbox雖然去掉了浮動的Hack,但是程式碼的可讀性上變得更差了。你很難去理解flexbox的CSS,並且不知道頁面上是如何去佈局所有元素的。在寫flexbox佈局程式碼的時,有很多時候靠的是大量的猜測和嘗試。

  特別需要注意的是,flexbox被設計用來在單行或者單列中分割元素的——它不是設計用來給整個頁面做佈局的!儘管它能很好的實現(相對於浮動佈局好很多)。另一種不同的規範是用來處理多行或者多列布局的,我們稱之為CSS 網格。

  基於Grid的佈局

  CSS網格最早在2011年提出的(比flexbox提案晚不了多久),但是花了好長時間才在瀏覽器上普及起來。截止2018年初,大多數現代瀏覽器都已經支援CSS grid(這比一兩年前有巨大的進步了)

  下面我們看一下基於網格佈局的例子,注意在這個例子中我們擺脫了flexbox佈局中必須使用<div class="container">的限制,我們可以簡單的使用原始的HTML,先看下CSS檔案:

/* GRID-BASED LAYOUT */
body {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: min-content 1fr min-content;
}
header {
  grid-row: 1;
  grid-column: 1 / 4;
}
nav {
  grid-row: 2;
  grid-column: 1 / 2;
  padding: 0 10px;
}
main {
  grid-row: 2;
  grid-column: 2 / 3;
  padding: 0 20px;
}
aside {
  grid-row: 2;
  grid-column: 3 / 4;
  padding: 0 10px;
}
footer {
  grid-row: 3;
  grid-column: 1 / 4;
}

  雖然結果看起來和基於flexbox的佈局一樣,但是CSS在很大程度上得到了改進,它清晰地表達出了期望的佈局方式。行和列的大小和形狀在body選擇器中定義,每一項item直接通過他們所在行和列的位置定義。

  grid-column 這個屬性你可能覺得不太好理解,它定義了列的起點和終點。這個地方讓你覺得困惑的可能是明明有3列,卻為什麼定義的範圍是1到4,通過下面的圖片你就能理解了:


Click here to see a live example

  第一列是從1到2,第二列是從2到3,第三列從3到4,所以頭部的grid-column是從1到4佔據整個頁面,導航的grid-column是從1到2佔據第一列等等

  一旦你習慣了grid語法,你會覺得它是一種非常理想的CSS佈局方式。唯一缺點就是瀏覽器支援,幸運的是過去一年中瀏覽器的支援又得到了進一步的提高。作為專為CSS設計的第一款真正的佈局工具很難描繪它的重要性,從某種意義上來說,由於現有的工具需要太多的hack和變通方式去實現,因此web設計者過去對於佈局的創意上一直很保守,CSS網格的出現有可能會激發出一批從未有過的創意佈局設計——想想還是挺激動人心的!

 使用CSS前處理器擴充套件CSS語法

  到目前為止,我們介紹了CSS的基本樣式和佈局,現在我們再來看下那些幫助CSS提升語言本身體驗的工具,先從CSS前處理器開始吧。

  CSS前處理器允許你使用不同的語言來定義樣式,最終會幫你轉換為瀏覽器可以解釋的CSS,這一點在當今瀏覽器對新特性支援緩慢的情況下很有價值。第一個主流的CSS前處理器是2006年釋出的Sass,它提供了一個新的更簡潔的語法(縮排代替大括號,沒有分號等等),同時增加了一些CSS缺失的高階特性,像變數、工具方法還有計算。下面我們使用Sass變數實現下前面例子中帶顏色的區域定義:

$dark-color: #4a4a4a
$light-color: #f9f9f9
$side-color: #eee
body
  color: $dark-color
  
header, footer
  background-color: $dark-color
  color: $light-color
  
main
  background: $light-color
nav, aside
  background: $side-color

  注意我們用$定義了可複用的變數,省略了大括號和分號,語法看起來更加清晰了。簡潔的語法讓Sass看起來很棒,但變數這樣的特性出現在當時來說意義更大,這為編寫整潔可維護的CSS程式碼開闢了新的可能性。

  使用Sass你需要安裝Ruby(Ruby),這門語言主要是讓Sass編譯成正常的CSS,同時你需要安裝Sass gem,之後你就可以通過命令列把你的.sass檔案轉成.css檔案了,我們先看一個使用命令列的例子:

sass --watch index.sass index.css

  這個命令定期把index.sass中的Sass程式碼轉為CSS寫入到index.css檔案中(--watch引數設定後會實時監聽.sass檔案改動並執行編譯,非常方便)

  這個過程被稱為構建步驟。這在2006年的時候是非常大的一個障礙,如果你對Ruby這樣的程式語言熟悉的話,這個過程非常簡單。但是當時很多前端開發者只用HTML和CSS,他們不需要類似這樣的工具。因此,為了使用CSS預編譯的功能而讓一個人學習整個生態系統是很大的一個要求了。

  2009年的時候,Less CSS預編譯器釋出。它也是Ruby寫的,並且提供了類似於Sass的功能,關鍵不同點是它的語法設計上更接近CSS。這意味著任何CSS程式碼都是合法的Less程式碼,同樣我們看一個用Less語法的例子:

@dark-color: #4a4a4a;
@light-color: #f9f9f9;
@side-color: #eee;
body {
  color: @dark-color;
}
  
header, footer {
  background-color: @dark-color;
  color: @light-color;
}
  
main {
  background: @light-color;
}
nav, aside {
  background: @side-color;
}

  語法上幾乎是相同的(變數的定義使用@替代了$),但是Less和CSS一樣帶有大括號和分號,沒有Sass例子的程式碼看起來漂亮。然而,和CSS相近的特性反而讓開發者更容易接受它,在2012年,Less使用了JavaScript(Node.js)重寫了替換了Ruby,效能上比Ruby編譯更快了,並且很多在工作中使用了Node.js的人更容易上手了。

  把這段程式碼轉化為標準的CSS,你需要安裝Node.jsLess,執行的命令列如下:

lessc index.less index.css

  這個命令把index.less檔案中的Lessz程式碼轉化為標準的CSS程式碼寫入到index.css檔案中,注意lessc命令不能監聽檔案的變化(和sass不一樣),這意味著你需要安裝其他自動監聽和編譯的元件來實現該功能,增加了流程的複雜性。同樣,對於程式設計師來說使用命令列的方式並不難,但是對於其他只想使用CSS預編譯器的人來說還是個非常大的障礙。

  汲取了Less的經驗,Sass開發者在2010年釋出了一個新的語法叫SCSS(與Less類似的一個CSS超集),同時釋出了LibSass,一個基於C++擴充套件的Ruby引擎,讓編譯更快並且適配於多種語言。

  另外一個CSS前處理器是2010年釋出的Stylus,使用Node.js編寫,和Sass或者Less相比更注重於清晰的語法。通常主流的CSS預編譯器就這三種(Sass,Less,Stylus),他們在功能方面非常相似,所以你不必擔心選擇哪一個會是錯誤的。

  然而,有些人認為使用CSS前處理器開始變得越來越沒必要,因為瀏覽器最終會慢慢實現這些功能(像變數和計算)。此外,還有一種稱為CSS後處理器的方法,有可能會讓CSS前處理器過時(顯然這存在些爭議),我們在後面會詳細介紹下。

 使用CSS後處理器的轉換功能

  CSS後處理器使用JavaScript分析並轉換你的CSS為合法CSS,從這方面來看和CSS前處理器很相似,你可以認為是解決同一個問題的不同方式。關鍵的不同點是CSS前處理器使用特殊的語法來標記需要轉換的地方,而CSS後處理器可以解析轉換標準的CSS,並不需要任何特殊的語法。舉一個例子來說明下,我們用最初定義的header標籤樣式來看一下吧:

h1, h2, h3, h4, h5, h6 {
  **-ms-hyphens: auto;
  -moz-hyphens: auto;
  -webkit-hyphens: auto;**
  hyphens: auto;
}

  粗體部分的屬性成為廠商字首,廠商字首是瀏覽器廠商對CSS新功能的實驗和測試使用的,在正式實現前提供給開發者使用CSS新屬性的一種方式。-ms代表IE瀏覽器,-moz是火狐瀏覽器,-webkit是基於webkit核心的瀏覽器。

  定義這些不同瀏覽器廠商的字首屬性是非常煩人的,儘量使用生成工具自動新增廠商字首。我們可以使用CSS前處理器來完成這個功能,例如,我們可以用SCSS來實現:

@mixin hyphens($value) {
  -ms-hyphens: $value;
  -moz-hyphens: $value;
  -webkit-hyphens: $value;
  hyphens: $value;
}
h1, h2, h3, h4, h5, h6 {
  @include hyphens(auto);
}

  這個地方使用了Sass的 mixin 功能,你可以定義一個CSS程式碼塊然後在其他任何地方重用,當這個檔案被編譯成標準的CSS的時候,所有的@include語句都被替換成與之匹配的@mixin中的CSS。總體來說,這個解決方案也不差,但是你仍然要為每個需要廠商字首的的CSS屬性定義一個mixin,這些mixin的定義將需要不斷的維護,比如當瀏覽器支援了某個CSS屬性後你就要在你的定義中移除掉該屬性。

  比起寫mixin的方式,直接正常寫CSS然後由工具自動識別新增需要廠商字首的屬性的方式顯然更優雅些。CSS後處理器就恰好能完成這樣的功能。比如,如果你使用 PostCSSautoprefixer 外掛,你就可以直接寫正常的CSS並不需要指定瀏覽器廠商字首,剩下的工作全交給後置處理器去處理:

h1, h2, h3, h4, h5, h6 {
  hyphens: auto;
}

  當你使用CSS後處理器執行這段程式碼的時候hyphens: auto; 將被替換成包含所有瀏覽器廠商字首的屬性,這意味著你可以正常寫CSS不用擔心各種瀏覽器相容性問題,豈不是很棒!

  除了PostCSS的autoprefixer外掛還有很多有意思的外掛,cssnext 外掛可以讓你體驗下一些實驗性質的CSS新功能,CSS modules 可以自動改變class的名字避免名稱衝突,stylelint 能檢查出你CSS程式碼中一些定義錯誤和不符合規範的寫法。這些工具在過去一兩年裡開始流行起來,給開發者提供了從未有過的工程化流程。

  然而,程式的發展總是有代價的,安裝和使用CSS後處理比CSS前處理器更復雜。你不僅要安裝、執行命令列,還需要安裝配置各個外掛並且定義好各種複雜的規則(比如你的目標瀏覽器等)。很多開發者不再直接使用命令列執行PostCSS了,而是通過配置一些構建系統,像GruntGulpwebpack,他們可以幫助你管理前端開發工作中需要的各種構建工具。

  值得注意的是對於CSS後處理器存在些爭議,有人認為這個術語有些讓人迷惑(一種說法是建議都應該叫CSS前處理器,還有一種說法是應該都簡稱CSS處理器,等等),有人認為有了CSS後處理器完全可以不需要CSS前處理器,有人則主張兩者一起使用。不管怎麼說,去了解下CSS後處理器的使用還是非常值得的。

 使用CSS設計模式

  CSS前處理器和CSS後處理器讓CSS開發體驗有了巨大的提升,但是單靠這些工具還不足以解決維護大型專案CSS程式碼的問題。為了解決這個問題,人們編寫了一些關於如何寫CSS的指導方針,通常被稱為CSS規範。

  在我們深入分析CSS規範前,首先要搞清楚是什麼讓CSS隨著時間推移變得更加難維護,關鍵點是CSS是全域性性的——你定義的每個樣式都會全域性應用到頁面的每個部分,用一個命名約定來保證class名稱的唯一性或者有特殊的規則來決定指定樣式應用到指定元素。CSS規範提供了一個有組織性的方式來避免大量程式碼時出現的這些問題,讓我們按照時間順序來看看主流的一些規範吧

  OOCSS

  OOCSS(物件導向的CSS)是在2009年首次提出的,它是圍繞兩個原則建立的規範。第一個原則是結構和樣式分離,這意味著定義結構(佈局)的CSS不應該和定義樣式(顏色、字型等)的CSS混雜在一起,這樣我們就可以很簡單的為一個應用定義新的皮膚了;第二個原則是容器和內容分離,把元素看成是一個可重用的物件,關鍵核心點是一個物件不管用在頁面的任何位置都應該看起來是相同的。

  OOCSS提供了成熟的指導規範,但是對於具體的執行規範並沒有明確指出。後來出現的SMACSS採用了它的核心概念,並且新增了更多的細節,使用起來更簡單了。

  SMACSS

  SMACSS(可擴充套件模組化架構的CSS)是在2011年出現的一種設計模式,它將CSS分為5個不同的類別——基本規範、佈局規範、模組、狀態規範和樣式規範。SMACSS也有一些推薦的命名規則,對於佈局規範使用l- 或者layout- 作為字首;對於狀態規範,使用is-hidden 或者is-collapsed 作為字首。

  相比OOCSS,SMACSS有了更多細節上的規範,但是CSS規則該劃分為哪一類別的規範中,這是個需要仔細考慮的問題。後來出現的BEM對這一方面進行了改進,讓它更易使用了。

  BEM

  BEM (塊, 元素, 修飾符)是在2010年出現的規範,它的思想主要是圍繞把使用者介面切分成獨立的塊。塊是一個可重用的元件(舉個例子像表單搜尋,可以這樣定義<form class="search-form"></form>),元素是塊的一部分不能單獨重用(比如表單搜尋中的button,<button class="search-form__button">Search</button>),修飾符是定義了塊或者元素外觀、狀態或者行為的實體(比如禁用搜尋按鈕,定義為<button class="search-form__button search-form__button--disabled">Search</button>)。

  BEM的規範很容易理解,對於新手來說命名規則上也很友好,缺點就是可能會導致class名字非常長,並且沒有遵循傳統的命名規範。後來出現的Atomic CSS又把這個非傳統方式帶到了一個新的高度。

  Atomic CSS

  Atomic CSS (也稱為 功能性CSS)是2014年出現的一個規範,它的思想是基於視覺化的方法建立小而功能單一化的class。這種規範與OOCSS、SMACSS和BEM完全相反——它並不是把頁面上的元素看做是可重用的物件,Atomic CSS忽略掉了這些物件,每一個元素使用了可重用的單一功能的class樣式集合。因此像<button class="search-form__button">Search</button> 就被替換成這樣的寫法了<button class="f6 br3 ph3 pv2 white bg-purple hover-bg-light-purple">Search</button>

  如果你看到這個例子第一反應是被嚇的退縮了,沒關係你並不是唯一有這想法的人——很多人認為這種方式完全違背了CSS的最佳實踐,但是,關於這個有爭議的規範在不同場景下的應用也產出了一系列精彩的討論。這篇文章很清晰的分析了傳統的分離思想是CSS依賴於HTML建立(即使使用像BEM這類的規範),而Atomic的方式是HTML依賴於CSS建立,兩者都沒錯,但是仔細想想你會發現CSS和HTML徹底分離的想法是實現不了的。

  其他的CSS設計模式,像CSS in JS其實也包含了CSS和HTML相互依賴的思想,這也成為了一個飽受爭議的設計規範之一。

  CSS in JS

  CSS in JS 是2014年推出的一種設計模式,它的核心思想是把CSS直接寫到各自元件中,而不是單獨的樣式檔案裡。這種方式在React框架中引入的,最早是使用內聯樣式,後來又進化成了使用JavaScript生成CSS然後插入到頁面的style標籤中的方式。

  CSS in JS再一次違背了CSS中關於分離的最佳實踐,主要原因是web隨著時間推移發生了很大的變化。最初web大部分都是靜態網站——這種情況下HTML內容和CSS表現分離是很有意義的,但現在大部分應用都是動態web構建——這種情況下可重用的元件更加有意義了。

  CSS in JS設計的目標是定義邊界清晰包含自己HTML/CSS/JS的獨立元件,並且不受其他元件的影響。React是最早採用這種思想的框架,後續也影響到了其他框架像Angular、Ember和Vue.js。需要注意的是CSS in JS的模式相對來說比較新的,開發人員正在不斷的嘗試開發web應用元件時的一些CSS最佳實踐。

  五花八門的設計模式很容易讓你不知所措,最重要的記住一點——沒有銀彈。

 結論

  簡而言之這就是現代CSS。我們介紹了CSS基本排版樣式,浮動佈局、flexbox和grid佈局,瞭解了CSS前處理器為CSS提供的新語法,比如變數和mixins,還了解了CSS後處理器的轉換功能,像給CSS新增廠商字首,並且使用CSS的一些設計模式克服了全域性CSS的一些問題。在這裡我們沒有時間去挖掘更多CSS其他功能了,CSS覆蓋面太廣了——任何一個說它簡單的人可能只是對它一知半解吧!

  現代CSS的多變和快速發展多少讓人感到有些沮喪,但是重要的是要記住web隨著時間推移進化的歷史背景,並且有一群聰明的人願意為CSS向更好的方向的進化去建立一些工具和指導規範。作為一名開發者是一件幸運的事情,我希望這篇文章提供的資訊能作為一個路線圖幫助你更好的暢行在CSS路程中!

英文原文:https://medium.com/actualize-network/modern-css-explained-for-dinosaurs-5226febe3525

相關文章