現代 CSS 進化史

v2-3622f785117e21116dc9837d6e3ac641_r.jpg

簡評:CSS 是一門入門比較簡單,但真正使用起來又很困難的語言(有些人認爲它不該該稱爲一門語言)。CSS 看起來凌亂複雜,其實攻克也不難,瞭解了 CSS 的發展背景你就會有對它有了系統性的認知。經過這一篇文章,你基本就會對 CSS 有了一個熟識的瞭解。

v2-85d897b7e26a4f6d60131029e7248543_hd.jpg

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

爲了解決 CSS 錯綜複雜的繼承問題,開發者創建了各類不一樣的最佳實踐,問題是哪個最佳實踐是最好的目前尚無定論,並且有些實踐相互之間是徹底矛盾的。若是你第一次嘗試學習 CSS ,這對於你來講是至關迷惑的。html

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

CSS 基本樣式使用node

咱們從一個最簡單的網頁 index.html 開始,這個文件中包含一個獨立的樣式文件 index.css :webpack

<!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 樣式的狀況下,咱們的網站看起來是這個樣子:git

v2-3bff7b89379dfb250fbedd11abc62b9b_hd.jpg
點擊查看在線demo程序員

功能可用,但看起來很差看,咱們能夠繼續在 index.css 加點 CSS 美化下排版:github

/* 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 自己並不複雜,你能夠直接定義,結果以下所示:web

v2-ccfd2a62ec97bffec184f5c855a6bd21_hd.jpg

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;
}

如今頁面應該看起來以下:

v2-8fba410c70130bb8836dd64aa7b3ad3f_hd.jpg

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、硬編碼的寬度計算等),稍後咱們會對這些細節作詳細的解釋。最終的結果以下:

v2-6be1970ed53f49366f0a2965df927a0c_hd.jpg

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 方案了,這是個巨大的進步。最終結果以下:

v2-3acd79844888f966161d58be2f3153ca_hd.jpg

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,經過下面的圖片你就能理解了:

v2-5118403ab2f924c2b60d0b2e1b84dec3_hd.jpg

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 網格的出現有可能會激發出一批從未有過的創意佈局設計——想一想仍是挺激動人心的!

v2-1377282492cfb42352a695e899daac0a_hd.jpg

使用 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 後處理器的使用仍是很是值得的。

v2-4dc8bd85499a0923324a40448235082d_hd.jpg

使用 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 路程中!

v2-e58f96cd00fcac59ceb3ceb6ec925f2d_hd.jpg

英文: Modern CSS Explained For Dinosaurs
相關文章
相關標籤/搜索