1.5 萬字 CSS 基礎拾遺(核心知識、常見需求)

本篇文章圍繞了 CSS 的核心知識點和項目中常見的需求來展開。雖然行文偏長,但較基礎,適合初級中級前端閱讀,閱讀的時候請適當跳過已經掌握的部分。css

這篇文章斷斷續續寫了比較久,也參考了許多優秀的文章,但或許文章裏仍是存在很差或不對的地方,請多多指教,能夠評論裏直接提出來哈。html

小tip:後續內容更精彩哦。前端

核心概念和知識點

語法

CSS 的核心功能是將 CSS 屬性設定爲特定的值。一個屬性與值的鍵值對被稱爲聲明(declaration)。git

color: red;
複製代碼

而若是將一個或者多個聲明用 {} 包裹起來後,那就組成了一個聲明塊(declaration block)。github

{
    color: red;
    text-align: center;
}
複製代碼

聲明塊若是須要做用到對應的 HTML 元素,那還須要加上選擇器。選擇器和聲明塊組成了CSS 規則集(CSS ruleset),常簡稱爲 CSS 規則。web

span {
    color: red;
    text-align: center;
}
複製代碼

規則集中最後一條聲明能夠省略分號,可是並不建議這麼作,由於容易出錯。算法

CSS 中的註釋canvas

/* 單行註釋 */

/* 多行 註釋 */
複製代碼

在 CSS 文件中,除了註釋、CSS 規則集以及 @規則 外,定義的一些別的東西都將被瀏覽器忽略。segmentfault

@規則

CSS 規則是樣式表的主體,一般樣式表會包括大量的規則列表。但有時候也須要在樣式表中包括其餘的一些信息,好比字符集,導入其它的外部樣式表,字體等,這些須要專門的語句表示。瀏覽器

而 @規則 就是這樣的語句。CSS 裏包含了如下 @規則:

  • @namespace 告訴 CSS 引擎必須考慮XML命名空間。
  • @media, 若是知足媒體查詢的條件則條件規則組裏的規則生效。
  • @page, 描述打印文檔時佈局的變化.
  • @font-face, 描述將下載的外部的字體。
  • @keyframes, 描述 CSS 動畫的關鍵幀。
  • @document, 若是文檔樣式表知足給定條件則條件規則組裏的規則生效。 (推延至 CSS Level 4 規範)

除了以上這幾個以外,下面還將對幾個比較生澀的 @規則 進行介紹。

@charset

@charset 用於定義樣式表使用的字符集。它必須是樣式表中的第一個元素。若是有多個 @charset 被聲明,只有第一個會被使用,並且不能在HTML元素或HTML頁面的 <style> 元素內使用。

注意:值必須是雙引號包裹,且和

@charset "UTF-8";
複製代碼

平時寫樣式文件都沒寫 @charset 規則,那這個 CSS 文件究竟是用的什麼字符編碼的呢?

某個樣式表文件到底用的是什麼字符編碼,瀏覽器有一套識別順序(優先級由高到低):

  • 文件開頭的 Byte order mark 字符值,不過通常編輯器並不能看到文件頭裏的 BOM 值;

  • HTTP 響應頭裏的 content-type 字段包含的 charset 所指定的值,好比:

    Content-Type: text/css; charset=utf-8
    複製代碼
  • CSS 文件頭裏定義的 @charset 規則裏指定的字符編碼;

  • <link> 標籤裏的 charset 屬性,該條已在 HTML5 中廢除;

  • 默認是 UTF-8

@import

@import 用於告訴 CSS 引擎引入一個外部樣式表。

link 和 @import 都能導入一個樣式文件,它們有什麼區別嘛?

  • link 是 HTML 標籤,除了能導入 CSS 外,還能導入別的資源,好比圖片、腳本和字體等;而 @import 是 CSS 的語法,只能用來導入 CSS;
  • link 導入的樣式會在頁面加載時同時加載,@import 導入的樣式需等頁面加載完成後再加載;
  • link 沒有兼容性問題,@import 不兼容 ie5 如下;
  • link 能夠經過 JS 操做 DOM 動態引入樣式表改變樣式,而@import不能夠。

@supports

@supports 用於查詢特定的 CSS 是否生效,能夠結合 not、and 和 or 操做符進行後續的操做。

/* 若是支持自定義屬性,則把 body 顏色設置爲變量 varName 指定的顏色 */
@supports (--foo: green) {
    body {
        color: var(--varName);
    }
}
複製代碼

層疊性

層疊樣式表,這裏的層疊怎麼理解呢?其實它是 CSS 中的核心特性之一,用於合併來自多個源的屬性值的算法。好比說針對某個 HTML 標籤,有許多的 CSS 聲明都能做用到的時候,那最後誰應該起做用呢?層疊性說的大概就是這個。

針對不一樣源的樣式,將按照以下的順序進行層疊,越往下優先級越高:

  • 用戶代理樣式表中的聲明(例如,瀏覽器的默認樣式,在沒有設置其餘樣式時使用)。
  • 用戶樣式表中的常規聲明(由用戶設置的自定義樣式。因爲 Chrome 在很早的時候就放棄了用戶樣式表的功能,因此這裏將再也不考慮它的排序。)
  • 做者樣式表中的常規聲明(這些是咱們 Web 開發人員設置的樣式)。
  • 做者樣式表中的 !important 聲明。
  • 用戶樣式表中的 !important 聲明S

理解層疊性的時候須要結合 CSS 選擇器的優先級以及繼承性來理解。好比針對同一個選擇器,定義在後面的聲明會覆蓋前面的;做者定義的樣式會比默認繼承的樣式優先級更高。

選擇器

CSS 選擇器無疑是其核心之一,對於基礎選擇器以及一些經常使用僞類必須掌握。下面列出了經常使用的選擇器。 想要獲取更多選擇器的用法能夠看 MDN CSS Selectors

基礎選擇器

  • 標籤選擇器:h1
  • 類選擇器:.checked
  • ID 選擇器:#picker
  • 通配選擇器:*

屬性選擇器

  • [attr]:指定屬性的元素;
  • [attr=val]:屬性等於指定值的元素;
  • [attr*=val]:屬性包含指定值的元素;
  • [attr^=val] :屬性以指定值開頭的元素;
  • [attr$=val]:屬性以指定值結尾的元素;
  • [attr~=val]:屬性包含指定值(完整單詞)的元素(不推薦使用);
  • [attr|=val]:屬性以指定值(完整單詞)開頭的元素(不推薦使用);

組合選擇器

  • 相鄰兄弟選擇器:A + B
  • 普通兄弟選擇器:A ~ B
  • 子選擇器:A > B
  • 後代選擇器:A B

僞類

條件僞類

  • :lang():基於元素語言來匹配頁面元素;
  • :dir():匹配特定文字書寫方向的元素;
  • :has():匹配包含指定元素的元素;
  • :is():匹配指定選擇器列表裏的元素;
  • :not():用來匹配不符合一組選擇器的元素;

行爲僞類

  • :active:鼠標激活的元素;
  • :hover: 鼠標懸浮的元素;
  • ::selection:鼠標選中的元素;

狀態僞類

  • :target:當前錨點的元素;
  • :link:未訪問的連接元素;
  • :visited:已訪問的連接元素;
  • :focus:輸入聚焦的表單元素;
  • :required:輸入必填的表單元素;
  • :valid:輸入合法的表單元素;
  • :invalid:輸入非法的表單元素;
  • :in-range:輸入範圍之內的表單元素;
  • :out-of-range:輸入範圍之外的表單元素;
  • :checked:選項選中的表單元素;
  • :optional:選項可選的表單元素;
  • :enabled:事件啓用的表單元素;
  • :disabled:事件禁用的表單元素;
  • :read-only:只讀的表單元素;
  • :read-write:可讀可寫的表單元素;
  • :blank:輸入爲空的表單元素;
  • :current():瀏覽中的元素;
  • :past():已瀏覽的元素;
  • :future():未瀏覽的元素;

結構僞類

  • :root:文檔的根元素;
  • :empty:無子元素的元素;
  • :first-letter:元素的首字母;
  • :first-line:元素的首行;
  • :nth-child(n):元素中指定順序索引的元素;
  • :nth-last-child(n):元素中指定逆序索引的元素;;
  • :first-child :元素中爲首的元素;
  • :last-child :元素中爲尾的元素;
  • :only-child:父元素僅有該元素的元素;
  • :nth-of-type(n) :標籤中指定順序索引的標籤;
  • :nth-last-of-type(n):標籤中指定逆序索引的標籤;
  • :first-of-type :標籤中爲首的標籤;
  • :last-of-type:標籤中爲尾標籤;
  • :only-of-type:父元素僅有該標籤的標籤;

僞元素

  • ::before:在元素前插入內容;
  • ::after:在元素後插入內容;

優先級

優先級就是分配給指定的 CSS 聲明的一個權重,它由匹配的選擇器中的每一種選擇器類型的數值決定。爲了記憶,能夠把權重分紅以下幾個等級,數值越大的權重越高:

  • 10000:!important;
  • 01000:內聯樣式;
  • 00100:ID 選擇器;
  • 00010:類選擇器、僞類選擇器、屬性選擇器;
  • 00001:元素選擇器、僞元素選擇器;
  • 00000:通配選擇器、後代選擇器、兄弟選擇器;

能夠看到內聯樣式(經過元素中 style 屬性定義的樣式)的優先級大於任何選擇器;而給屬性值加上 !important 又能夠把優先級提至最高,就是由於它的優先級最高,因此須要謹慎使用它,如下有些使用注意事項:

  • 必定要優先考慮使用樣式規則的優先級來解決問題而不是 !important;
  • 只有在須要覆蓋全站或外部 CSS 的特定頁面中使用 !important;
  • 永遠不要在你的插件中使用 !important;
  • 永遠不要在全站範圍的 CSS 代碼中使用 !important;

繼承性

在 CSS 中有一個很重要的特性就是子元素會繼承父元素對應屬性計算後的值。好比頁面根元素 html 的文本顏色默認是黑色的,頁面中的全部其餘元素都將繼承這個顏色,當申明瞭以下樣式後,H1 文本將變成橙色。

body {
    color: orange;
}
h1 {
    color: inherit;
}
複製代碼

設想一下,若是 CSS 中不存在繼承性,那麼咱們就須要爲不一樣文本的標籤都設置一下 color,這樣一來的後果就是 CSS 的文件大小就會無限增大。

CSS 屬性不少,但並非全部的屬性默認都是能繼承父元素對應屬性的,那哪些屬性存在默認繼承的行爲呢?必定是那些不會影響到頁面佈局的屬性,能夠分爲以下幾類:

  • 字體相關:font-familyfont-stylefont-sizefont-weight 等;
  • 文本相關:text-aligntext-indenttext-decorationtext-shadowletter-spacingword-spacingwhite-spaceline-heightcolor 等;
  • 列表相關:list-stylelist-style-imagelist-style-typelist-style-position 等;
  • 其餘屬性:visibilitycursor 等;

對於其餘默認不繼承的屬性也能夠經過如下幾個屬性值來控制繼承行爲:

  • inherit:繼承父元素對應屬性的計算值;
  • initial:應用該屬性的默認值,好比 color 的默認值是 #000
  • unset:若是屬性是默承認以繼承的,則取 inherit 的效果,不然同 initial
  • revert:效果等同於 unset,兼容性差。

文檔流

在 CSS 的世界中,會把內容按照從左到右、從上到下的順序進行排列顯示。正常狀況下會把頁面分割成一行一行的顯示,而每行又可能由多列組成,因此從視覺上看起來就是從上到下從左到右,而這就是 CSS 中的流式佈局,又叫文檔流。文檔流就像水同樣,可以自適應所在的容器,通常它有以下幾個特性:

  • 塊級元素默認會佔滿整行,因此多個塊級盒子之間是從上到下排列的;
  • 內聯元素默認會在一行裏一列一列的排布,當一行放不下的時候,會自動切換到下一行繼續按照列排布;

如何脫離文檔流呢?

脫流文檔流指節點脫流正常文檔流後,在正常文檔流中的其餘節點將忽略該節點並填補其原先空間。文檔一旦脫流,計算其父節點高度時不會將其高度歸入,脫流節點不佔據空間。有兩種方式可讓元素脫離文檔流:浮動和定位。

  • 使用浮動(float)會將元素脫離文檔流,移動到容器左/右側邊界或者是另外一個浮動元素旁邊,該浮動元素以前佔用的空間將被別的元素填補,另外浮動以後所佔用的區域不會和別的元素之間發生重疊;
  • 使用絕對定位(position: absolute;)或者固定定位(position: fixed;)也會使得元素脫離文檔流,且空出來的位置將自動被後續節點填補。

盒模型

在 CSS 中任何元素均可以當作是一個盒子,而一個盒子是由 4 部分組成的:內容(content)、內邊距(padding)、邊框(border)和外邊距(margin)。

盒模型有 2 種:標準盒模型和 IE 盒模型,本別是由 W3C 和 IExplore 制定的標準。

若是給某個元素設置以下樣式:

.box {
    width: 200px;
    height: 200px;
    padding: 10px;
    border: 1px solid #eee;
    margin: 10px;
}
複製代碼

標準盒模型認爲:盒子的實際尺寸 = 內容(設置的寬/高) + 內邊距 + 邊框

因此 .box 元素內容的寬度就爲 200px,而實際的寬度則是 width + padding-left + padding-right + border-left-width + border-right-width = 200 + 10 + 10 + 1 + 1 = 222。

IE 盒模型認爲:盒子的實際尺寸 = 設置的寬/高 = 內容 + 內邊距 + 邊框

.box 元素所佔用的實際寬度爲 200px,而內容的真實寬度則是 width - padding-left - padding-right - border-left-width - border-right-width = 200 - 10 - 10 - 1 - 1 = 178。

如今高版本的瀏覽器基本上默認都是使用標準盒模型,而像 IE6 這種老古董纔是默認使用 IE 盒模型的。

在 CSS3 中新增了一個屬性 box-sizing,容許開發者來指定盒子使用什麼標準,它有 2 個值:

  • content-box:標準盒模型;
  • border-box:IE 盒模型;

視覺格式化模型

視覺格式化模型(Visual formatting model)是用來處理和在視覺媒體上顯示文檔時使用的計算規則。CSS 中一切皆盒子,而視覺格式化模型簡單來理解就是規定這些盒子應該怎麼樣放置到頁面中去,這個模型在計算的時候會依賴到不少的因素,好比:盒子尺寸、盒子類型、定位方案(是浮動仍是定位)、兄弟元素或者子元素以及一些別的因素。

Visual formatting model

從上圖中能夠看到視覺格式化模型涉及到的內容不少,有興趣深刻研究的能夠結合上圖看這個 W3C 的文檔 Visual formatting model。因此這裏就簡單介紹下盒子類型。

盒子類型由 display 決定,同時給一個元素設置 display 後,將會決定這個盒子的 2 個顯示類型(display type):

  • outer display type(對外顯示):決定了該元素自己是如何佈局的,即參與何種格式化上下文;
  • inner display type(對內顯示):其實就至關於把該元素當成了容器,規定了其內部子元素是如何佈局的,參與何種格式化上下文;

outer display type

對外顯示方面,盒子類型能夠分紅 2 類:block-level box(塊級盒子) 和 inline-level box(行內級盒子)。

依據上圖能夠列出都有哪些塊級和行內級盒子:

  • 塊級盒子:display 爲 block、list-item、table、flex、grid、flow-root 等;
  • 行內級盒子:display 爲 inline、inline-block、inline-table 等;

全部塊級盒子都會參與 BFC,呈現垂直排列;而全部行內級盒子都參會 IFC,呈現水平排列。

除此以外,block、inline 和 inline-block 還有什麼更具體的區別呢?

block

  • 佔滿一行,默認繼承父元素的寬度;多個塊元素將從上到下進行排列;
  • 設置 width/height 將會生效;
  • 設置 padding 和 margin 將會生效;

inline

  • 不會佔滿一行,寬度隨着內容而變化;多個 inline 元素將按照從左到右的順序在一行裏排列顯示,若是一行顯示不下,則自動換行;
  • 設置 width/height 將不會生效;
  • 設置豎直方向上的 padding 和 margin 將不會生效;

inline-block

  • 是行內塊元素,不單獨佔滿一行,能夠當作是可以在一行裏進行左右排列的塊元素;
  • 設置 width/height 將會生效;
  • 設置 padding 和 margin 將會生效;

inner display type

對內方面,其實就是把元素當成了容器,裏面包裹着文本或者其餘子元素。container box 的類型依據 display 的值不一樣,分爲 4 種:

  • block container:創建 BFC 或者 IFC;
  • flex container:創建 FFC;
  • grid container:創建 GFC;
  • ruby container:接觸很少,不作介紹。

值得一提的是若是把 img 這種替換元素(replaced element)申明爲 block 是不會產生 container box 的,由於替換元素好比 img 設計的初衷就僅僅是經過 src 把內容替換成圖片,徹底沒考慮過會把它當成容器。

參考:

格式化上下文

格式化上下文(Formatting Context)是 CSS2.1 規範中的一個概念,大概說的是頁面中的一塊渲染區域,規定了渲染區域內部的子元素是如何排版以及相互做用的。

不一樣類型的盒子有不一樣格式化上下文,大概有這 4 類:

  • BFC (Block Formatting Context) 塊級格式化上下文;
  • IFC (Inline Formatting Context) 行內格式化上下文;
  • FFC (Flex Formatting Context) 彈性格式化上下文;
  • GFC (Grid Formatting Context) 格柵格式化上下文;

其中 BFC 和 IFC 在 CSS 中扮演着很是重要的角色,由於它們直接影響了網頁佈局,因此須要深刻理解其原理。

BFC

塊格式化上下文,它是一個獨立的渲染區域,只有塊級盒子參與,它規定了內部的塊級盒子如何佈局,而且與這個區域外部絕不相干。

圖來源於 yachen168

BFC 渲染規則

  • 內部的盒子會在垂直方向,一個接一個地放置;
  • 盒子垂直方向的距離由 margin 決定,屬於同一個 BFC 的兩個相鄰盒子的 margin 會發生重疊;
  • 每一個元素的 margin 的左邊,與包含塊 border 的左邊相接觸(對於從左往右的格式化,不然相反),即便存在浮動也是如此;
  • BFC 的區域不會與 float 盒子重疊;
  • BFC 就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
  • 計算 BFC 的高度時,浮動元素也參與計算。

如何建立 BFC?

  • 根元素:html
  • 非溢出的可見元素:overflow 不爲 visible
  • 設置浮動:float 屬性不爲 none
  • 設置定位:position 爲 absolute 或 fixed
  • 定義成塊級的非塊級元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid

BFC 應用場景

一、 自適應兩欄佈局

應用原理:BFC 的區域不會和浮動區域重疊,因此就能夠把側邊欄固定寬度且左浮動,而對右側內容觸發 BFC,使得它的寬度自適應該行剩餘寬度。

<div class="layout">
    <div class="aside">aside</div>
    <div class="main">main</div>
</div>
複製代碼
.aside {
    float: left;
    width: 100px;
}
.main {
    <!-- 觸發 BFC -->
    overflow: auto;
}
複製代碼

二、清除內部浮動

浮動形成的問題就是父元素高度坍塌,因此清除浮動須要解決的問題就是讓父元素的高度恢復正常。而用 BFC 清除浮動的原理就是:計算 BFC 的高度時,浮動元素也參與計算。只要觸發父元素的 BFC 便可。

.parent {
    overflow: hidden;
}
複製代碼

三、 防止垂直 margin 合併

BFC 渲染原理之一:同一個 BFC 下的垂直 margin 會發生合併。因此若是讓 2 個元素不在同一個 BFC 中便可阻止垂直 margin 合併。那如何讓 2 個相鄰的兄弟元素不在同一個 BFC 中呢?能夠給其中一個元素外面包裹一層,而後觸發其包裹層的 BFC,這樣一來 2 個元素就不會在同一個 BFC 中了。

<div class="layout">
    <div class="a">a</div>
    <div class="contain-b">
        <div class="b">b</div>
    </div>
</div>
複製代碼
.demo3 .a,
.demo3 .b {
    border: 1px solid #999;
    margin: 10px;
}
.contain-b {
    overflow: hidden;
}
複製代碼

針對以上 3 個 示例 ,能夠結合這個 BFC 應用示例 配合觀看更佳。

參考:CSS 原理 - Formatting Context

IFC

IFC 的造成條件很是簡單,塊級元素中僅包含內聯級別元素,須要注意的是當IFC中有塊級元素插入時,會產生兩個匿名塊將父元素分割開來,產生兩個 IFC。

IFC 渲染規則

  • 子元素在水平方向上一個接一個排列,在垂直方向上將以容器頂部開始向下排列;
  • 節點沒法聲明寬高,其中 margin 和 padding 在水平方向有效在垂直方向無效;
  • 節點在垂直方向上以不一樣形式對齊;
  • 能把在一行上的框都徹底包含進去的一個矩形區域,被稱爲該行的線盒(line box)。線盒的寬度是由包含塊(containing box)和與其中的浮動來決定;
  • IFC 中的 line box 通常左右邊貼緊其包含塊,但 float 元素會優先排列。
  • IFC 中的 line box 高度由 line-height 計算規則來肯定,同個 IFC 下的多個 line box 高度可能會不一樣;
  • 當內聯級盒子的總寬度少於包含它們的 line box 時,其水平渲染規則由 text-align 屬性值來決定;
  • 當一個內聯盒子超過父元素的寬度時,它會被分割成多盒子,這些盒子分佈在多個 line box 中。若是子元素未設置強制換行的狀況下,inline box 將不可被分割,將會溢出父元素。

針對如上的 IFC 渲染規則,你是否是能夠分析下下面這段代碼的 IFC 環境是怎麼樣的呢?

<p>It can get <strong>very complicated</storng> once you start looking into it.</p>
複製代碼

對應上面這樣一串 HTML 分析以下:

  • p 標籤是一個 block container,對內將產生一個 IFC;
  • 因爲一行沒辦法顯示徹底,因此產生了 2 個線盒(line box);線盒的寬度就繼承了 p 的寬度;高度是由裏面的內聯盒子的 line-height 決定;
  • It can get:匿名的內聯盒子;
  • very complicated:strong 標籤產生的內聯盒子;
  • once you start:匿名的內聯盒子;
  • looking into it.:匿名的內聯盒子。

參考:Inline formatting contexts

IFC 應用場景

  • 水平居中:當一個塊要在環境中水平居中時,設置其爲 inline-block 則會在外層產生 IFC,經過 text-align 則可使其水平居中。
  • 垂直居中:建立一個 IFC,用其中一個元素撐開父元素的高度,而後設置其 vertical-align: middle,其餘行內元素則能夠在此父元素下垂直居中。

偷個懶,demo 和圖我就不作了。

層疊上下文

在電腦顯示屏幕上的顯示的頁面實際上是一個三維的空間,水平方向是 X 軸,豎直方向是 Y 軸,而屏幕到眼睛的方向能夠當作是 Z 軸。衆 HTML 元素依據本身定義的屬性的優先級在 Z 軸上按照必定的順序排開,而這其實就是層疊上下文所要描述的東西。

-w566

咱們對層疊上下文的第一印象可能要來源於 z-index,認爲它的值越大,距離屏幕觀察者就越近,那麼層疊等級就越高,事實確實是這樣的,但層疊上下文的內容遠非僅僅如此:

  • z-index 可以在層疊上下文中對元素的堆疊順序其做用是必須配合定位才能夠;
  • 除了 z-index 以外,一個元素在 Z 軸上的顯示順序還受層疊等級和層疊順序影響;

在看層疊等級和層疊順序以前,咱們先來看下如何產生一個層疊上下文,特定的 HTML 元素或者 CSS 屬性產生層疊上下文,MDN 中給出了這麼一個列表,符合如下任一條件的元素都會產生層疊上下文:

  • html 文檔根元素
  • 聲明 position: absolute/relative 且 z-index 值不爲 auto 的元素;
  • 聲明 position: fixed/sticky 的元素;
  • flex 容器的子元素,且 z-index 值不爲 auto;
  • grid 容器的子元素,且 z-index 值不爲 auto;
  • opacity 屬性值小於 1 的元素;
  • mix-blend-mode 屬性值不爲 normal 的元素;
  • 如下任意屬性值不爲 none 的元素:
    • transform
    • filter
    • perspective
    • clip-path
    • mask / mask-image / mask-border
  • isolation 屬性值爲 isolate 的元素;
  • -webkit-overflow-scrolling 屬性值爲 touch 的元素;
  • will-change 值設定了任一屬性而該屬性在 non-initial 值時會建立層疊上下文的元素;
  • contain 屬性值爲 layout、paint 或包含它們其中之一的合成值(好比 contain: strict、contain: content)的元素。

層疊等級

層疊等級指節點在三維空間 Z 軸上的上下順序。它分兩種狀況:

  • 在同一個層疊上下文中,它描述定義的是該層疊上下文中的層疊上下文元素在 Z 軸上的上下順序;
  • 在其餘普通元素中,它描述定義的是這些普通元素在 Z 軸上的上下順序;

普通節點的層疊等級優先由其所在的層疊上下文決定,層疊等級的比較只有在當前層疊上下文中才有意義,脫離當前層疊上下文的比較就變得無心義了。

層疊順序

在同一個層疊上下文中若是有多個元素,那麼他們之間的層疊順序是怎麼樣的呢?

如下這個列表越往下層疊優先級越高,視覺上的效果就是越容易被用戶看到(不會被其餘元素覆蓋):

  • 層疊上下文的 border 和 background
  • z-index < 0 的子節點
  • 標準流內塊級非定位的子節點
  • 浮動非定位的子節點
  • 標準流內行內非定位的子節點
  • z-index: auto/0 的子節點
  • z-index > 0的子節點

如何比較兩個元素的層疊等級?

  • 在同一個層疊上下文中,比較兩個元素就是按照上圖的介紹的層疊順序進行比較。
  • 若是不在同一個層疊上下文中的時候,那就須要比較兩個元素分別所處的層疊上下文的等級。
  • 若是兩個元素都在同一個層疊上下文,且層疊順序相同,則在 HTML 中定義越後面的層疊等級越高。

參考:完全搞懂CSS層疊上下文、層疊等級、層疊順序、z-index

值和單位

CSS 的聲明是由屬性和值組成的,而值的類型有許多種:

  • 數值:長度值 ,用於指定例如元素 width、border-width、font-size 等屬性的值;
  • 百分比:能夠用於指定尺寸或長度,例如取決於父容器的 width、height 或默認的 font-size;
  • 顏色:用於指定 background-color、color 等;
  • 座標位置:以屏幕的左上角爲座標原點定位元素的位置,好比常見的 background-position、top、right、bottom 和 left 等屬性;
  • 函數:用於指定資源路徑或背景圖片的漸變,好比 url()、linear-gradient() 等;

而還有些值是須要帶單位的,好比 width: 100px,這裏的 px 就是表示長度的單位,長度單位除了 px 外,比較經常使用的還有 em、rem、vw/vh 等。那他們有什麼區別呢?又應該在何時使用它們呢?

px

屏幕分辨率是指在屏幕的橫縱方向上的像素點數量,好比分辨率 1920×1080 意味着水平方向含有 1920 個像素數,垂直方向含有 1080 個像素數。

而 px 表示的是 CSS 中的像素,在 CSS 中它是絕對的長度單位,也是最基礎的單位,其餘長度單位會自動被瀏覽器換算成 px。可是對於設備而言,它其實又是相對的長度單位,好比寬高都爲 2px,在正常的屏幕下,其實就是 4 個像素點,而在設備像素比(devicePixelRatio) 爲 2 的 Retina 屏幕下,它就有 16 個像素點。因此屏幕尺寸一致的狀況下,屏幕分辨率越高,顯示效果就越細膩。

講到這裏,還有一些相關的概念須要理清下:

設備像素(Device pixels)

設備屏幕的物理像素,表示的是屏幕的橫縱有多少像素點;和屏幕分辨率是差很少的意思。

設備像素比(DPR)

設備像素比表示 1 個 CSS 像素等於幾個物理像素。

計算公式:DPR = 物理像素數 / 邏輯像素數;

在瀏覽器中能夠經過 window.devicePixelRatio 來獲取當前屏幕的 DPR。

像素密度(DPI/PPI)

像素密度也叫顯示密度或者屏幕密度,縮寫爲 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。從技術角度說,PPI 只存在於計算機顯示領域,而 DPI 只出現於打印或印刷領域。

計算公式:像素密度 = 屏幕對角線的像素尺寸 / 物理尺寸

好比,對於分辨率爲 750 * 1334 的 iPhone 6 來講,它的像素密度爲:

Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi
複製代碼

設備獨立像素(DIP)

DIP 是特別針對 Android設備而衍生出來的,緣由是安卓屏幕的尺寸繁多,所以爲了顯示能儘可能和設備無關,而提出的這個概念。它是基於屏幕密度而計算的,認爲當屏幕密度是 160 的時候,px = DIP。

計算公式:dip = px * 160 / dpi

em

em 是 CSS 中的相對長度單位中的一個。竟然是相對的,那它究竟是相對的誰呢?它有 2 層意思:

  • 在 font-size 中使用是相對於父元素的 font-size 大小,好比父元素 font-size: 16px,當給子元素指定 font-size: 2em 的時候,通過計算後它的字體大小會是 32px;
  • 在其餘屬性中使用是相對於自身的字體大小,如 width/height/padding/margin 等;

咱們都知道每一個瀏覽器都會給 HTML 根元素 html 設置一個默認的 font-size,而這個值一般是 16px。這也就是爲何 1em = 16px 的緣由所在了。

em 在計算的時候是會層層計算的,好比:

<div>
    <p></p>
</div>
複製代碼
div { font-size: 2em; }
p { font-size: 2em; }
複製代碼

對於如上一個結構的 HTML,因爲根元素 html 的字體大小是 16px,因此 p 標籤最終計算出來後的字體大小會是 16 * 2 * 2 = 64px

rem

rem(root em) 和 em 同樣,也是一個相對長度單位,不過 rem 相對的是 HTML 的根元素 html。

rem 因爲是基於 html 的 font-size 來計算,因此一般用於自適應網站或者 H5 中。

好比在作 H5 的時候,前端一般會讓 UI 給 750px 寬的設計圖,而在開發的時候能夠基於 iPhone X 的尺寸 375px * 812px 來寫頁面,這樣一來的話,就能夠用下面的 JS 依據當前頁面的視口寬度自動計算出根元素 html 的基準 font-size 是多少。

(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        psdWidth = 750,  // 設計圖寬度
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if ( !clientWidth ) return;
            if ( clientWidth >= 640 ) {
                docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px';
            } else {
                docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px';
            }
        };

    if ( !doc.addEventListener ) return;
    // 綁定事件的時候最好配合防抖函數
    win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
    doc.addEventListener( 'DOMContentLoaded', recalc, false );
    
    function debounce(func, wait) {
        var timeout;
        return function () {
            var context = this;
            var args = arguments;
            clearTimeout(timeout)
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
})(document, window);
複製代碼

好比當視口是 375px 的時候,通過計算 html 的 font-size 會是 100px,這樣有什麼好處呢?好處就是方便寫樣式,好比從設計圖量出來的 header 高度是 50px 的,那咱們寫樣式的時候就能夠直接寫:

header {
    height: 0.5rem;
}
複製代碼

每一個從設計圖量出來的尺寸只要除於 100 便可獲得當前元素的 rem 值,都不用通過計算,很是方便。偷偷告訴你,若是你把上面那串計算 html 標籤 font-size 的 JS 代碼中的 200 替換成 2,那在計算 rem 的時候就不須要除於 100 了,從設計圖量出多大 px,就直接寫多少個 rem。

vw/vh

vw 和 vh 分別是相對於屏幕視口寬度和高度而言的長度單位:

  • 1vw = 視口寬度均分紅 100 份中 1 份的長度;
  • 1vh = 視口高度均分紅 100 份中 1 份的長度;

在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。

vw/vh 的出現使得多了一種寫自適應佈局的方案,開發者再也不侷限於 rem 了。

相對視口的單位,除了 vw/vh 外,還有 vmin 和 vmax:

  • vmin:取 vw 和 vh 中值較小的;
  • vmax:取 vw 和 vh 中值較大的;

顏色體系

CSS 中用於表示顏色的值種類繁多,足夠構成一個體系,因此這裏就專門拿出一個小節來說解它。

根據 CSS 顏色草案 中提到的顏色值類型,大概能夠把它們分爲這幾類:

  • 顏色關鍵字
  • transparent 關鍵字
  • currentColor 關鍵字
  • RGB 顏色
  • HSL 顏色

顏色關鍵字

顏色關鍵字(color keywords)是不區分大小寫的標識符,它表示一個具體的顏色,好比 white(白),黑(black)等;

可接受的關鍵字列表在CSS的演變過程當中發生了改變:

  • CSS 標準 1 只接受 16 個基本顏色,稱爲 VGA 顏色,由於它們來源於 VGA 顯卡所顯示的顏色集合而被稱爲 VGA colors (視頻圖形陣列色彩)。
  • CSS 標準 2 增長了 orange 關鍵字。
  • 從一開始,瀏覽器接受其它的顏色,因爲一些早期瀏覽器是 X11 應用程序,這些顏色大多數是 X11 命名的顏色列表,雖然有一點不一樣。SVG 1.0 是首個正式定義這些關鍵字的標準;CSS 色彩標準 3 也正式定義了這些關鍵字。它們常常被稱做擴展的顏色關鍵字, X11 顏色或 SVG 顏色 。
  • CSS 顏色標準 4 添加可 rebeccapurple 關鍵字來記念 web 先鋒 Eric Meyer。

以下這張圖是 16 個基礎色,又叫 VGA 顏色。截止到目前爲止 CSS 顏色關鍵字總共有 146 個,這裏能夠查看 完整的色彩關鍵字列表

VGA 顏色

須要注意的是若是聲明的時候的顏色關鍵字是錯誤的,瀏覽器會忽略它。

transparent 關鍵字

transparent 關鍵字表示一個徹底透明的顏色,即該顏色看上去將是背景色。從技術上說,它是帶有 alpha 通道爲最小值的黑色,是 rgba(0,0,0,0) 的簡寫。

透明關鍵字有什麼應用場景呢?

實現三角形

下面這個圖是用 4 條邊框填充的正方形,看懂了它你大概就知道該如何用 CSS 寫三角形了。

div {
    border-top-color: #ffc107;
    border-right-color: #00bcd4;
    border-bottom-color: #e26b6b;
    border-left-color: #cc7cda;
    border-width: 50px;
    border-style: solid;
}
複製代碼

用 transparent 實現三角形的原理:

  • 首先寬高必須是 0px,經過邊框的粗細來填充內容;
  • 那條邊須要就要加上顏色,而不須要的邊則用 transparent;
  • 想要什麼樣姿式的三角形,徹底由上下左右 4 條邊的中有顏色的邊和透明的邊的位置決定;
  • 等腰三角形:設置一條邊有顏色,而後緊挨着的 2 邊是透明,且寬度是有顏色邊的一半;直角三角形:設置一條邊有顏色,而後緊挨着的任何一邊透明便可。

看下示例:

增大點擊區域

經常在移動端的時候點擊的按鈕的區域特別小,可是因爲現實效果又不太好把它作大,因此經常使用的一個手段就是經過透明的邊框來增大按鈕的點擊區域:

.btn {
    border: 5px solid transparent;
}
複製代碼

currentColor 關鍵字

currentColor 會取當前元素繼承父級元素的文本顏色值或聲明的文本顏色值,即 computed 後的 color 值。

好比,對於以下 CSS,該元素的邊框顏色會是 red:

.btn {
    color: red;
    border: 1px solid currentColor;
}
複製代碼

RGB[A] 顏色

RGB[A] 顏色是由 R(red)-G(green)-B(blue)-A(alpha) 組成的色彩空間。

在 CSS 中,它有兩種表示形式:

  • 十六進制符號;
  • 函數符;

十六進制符號

RGB 中的每種顏色的值範圍是 00~ff,值越大表示顏色越深。因此一個顏色正常是 6 個十六進制字符加上 # 組成,好比紅色就是 #ff0000。

若是 RGB 顏色須要加上不透明度,那就須要加上 alpha 通道的值,它的範圍也是 00~ff,好比一個帶不透明度爲 67% 的紅色能夠這樣寫 #ff0000aa。

使用十六進制符號表示顏色的時候,都是用 2 個十六進制表示一個顏色,若是這 2 個字符相同,還能夠縮減成只寫 1 個,好比,紅色 #f00;帶 67% 不透明度的紅色 #f00a。

函數符

當 RGB 用函數表示的時候,每一個值的範圍是 0~255 或者 0%~100%,因此紅色是 rgb(255, 0, 0), 或者 rgb(100%, 0, 0)。

若是須要使用函數來表示帶不透明度的顏色值,值的範圍是 0~1 及其之間的小數或者 0%~100%,好比帶 67% 不透明度的紅色是 rgba(255, 0, 0, 0.67) 或者 rgba(100%, 0%, 0%, 67%)

須要注意的是 RGB 這 3 個顏色值須要保持一致的寫法,要嘛用數字要嘛用百分比,而不透明度的值的能夠不用和 RGB 保持一致寫法。好比 rgb(100%, 0, 0) 這個寫法是無效的;而 rgb(100%, 0%, 0%, 0.67) 是有效的。

在第 4 代 CSS 顏色標準中,新增了一種新的函數寫法,便可以把 RGB 中值的分隔逗號改爲空格,而把 RGB 和 alpha 中的逗號改爲 /,好比帶 67% 不透明度的紅色能夠這樣寫 rgba(255 0 0 / 0.67)。另外還把 rgba 的寫法合併到 rgb 函數中了,即 rgb 能夠直接寫帶不透明度的顏色。

HSL[A] 顏色

HSL[A] 顏色是由色相(hue)-飽和度(saturation)-亮度(lightness)-不透明度組成的顏色體系。

  • 色相(H)是色彩的基本屬性,值範圍是 0360 或者 0deg360deg, 0 (或 360) 爲紅色, 120 爲綠色, 240 爲藍色;
  • 飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取 0~100% 的數值;0% 爲灰色, 100% 全色;
  • 亮度(L),取 0~100%,0% 爲暗,100% 爲白;
  • 不透明度(A),取 0100%,或者01及之間的小數;

寫法上能夠參考 RGB 的寫法,只是參數的值不同。

給一個按鈕設置不透明度爲 67% 的紅色的 color 的寫法,如下所有寫法效果一致:

button {
    color: #ff0000aa;
    color: #f00a;
    color: rgba(255, 0, 0, 0.67);
    color: rgb(100% 0% 0% / 67%);
    color: hsla(0, 100%, 50%, 67%);
    color: hsl(0deg 100% 50% / 67%);
}
複製代碼

小提示:在 Chrome DevTools 中能夠按住 shift + 鼠標左鍵能夠切換顏色的表示方式。

媒體查詢

媒體查詢是指針對不一樣的設備、特定的設備特徵或者參數進行定製化的修改網站的樣式。

你能夠經過給 <link> 加上 media 屬性來指定該樣式文件只能對什麼設備生效,不指定的話默認是 all,即對全部設備都生效:

<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
複製代碼

都支持哪些設備類型?

  • all:適用於全部設備;
  • print:適用於在打印預覽模式下在屏幕上查看的分頁材料和文檔;
  • screen:主要用於屏幕;
  • speech:主要用於語音合成器。

須要注意的是:經過 media 指定的 資源儘管不匹配它的設備類型,可是瀏覽器依然會加載它。

除了經過 <link> 讓指定設備生效外,還能夠經過 @media 讓 CSS 規則在特定的條件下才能生效。響應式頁面就是使用了 @media 才讓一個頁面可以同時適配 PC、Pad 和手機端。

@media (min-width: 1000px) {}
複製代碼

媒體查詢支持邏輯操做符:

  • and:查詢條件都知足的時候才生效;
  • not:查詢條件取反;
  • only:整個查詢匹配的時候才生效,經常使用語兼容舊瀏覽器,使用時候必須指定媒體類型;
  • 逗號或者 or:查詢條件知足一項便可匹配;

媒體查詢還支持衆多的媒體特性,使得它能夠寫出很複雜的查詢條件:

/* 用戶設備的最小高度爲680px或爲縱向模式的屏幕設備 */
@media (min-height: 680px), screen and (orientation: portrait) {}
複製代碼

常見需求

自定義屬性

以前咱們一般是在預處理器裏纔可使用變量,而如今 CSS 裏也支持了變量的用法。經過自定義屬性就能夠在想要使用的地方引用它。

自定義屬性也和普通屬性同樣具備級聯性,申明在 :root 下的時候,在全文檔範圍內可用,而若是是在某個元素下申明自定義屬性,則只能在它及它的子元素下才可使用。

自定義屬性必須經過 --x 的格式申明,好比:--theme-color: red; 使用自定義屬性的時候,須要用 var 函數。好比:

<!-- 定義自定義屬性 -->
:root {
    --theme-color: red;
}

<!-- 使用變量 -->
h1 {
    color: var(--theme-color);
}
複製代碼

上圖這個是使用 CSS 自定義屬性配合 JS 實現的動態調整元素的 box-shadow,具體能夠看這個 codepen demo

1px 邊框解決方案

Retina 顯示屏比普通的屏幕有着更高的分辨率,因此在移動端的 1px 邊框就會看起來比較粗,爲了美觀一般須要把這個線條細化處理。這裏有篇文章列舉了 7 中方案能夠參考一下:7種方法解決移動端Retina屏幕1px邊框問題

而這裏附上最後一種經過僞類和 transform 實現的相對完美的解決方案:

只設置單條底部邊框:

.scale-1px-bottom {
    position: relative;
    border:none;
}
.scale-1px-bottom::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    background: #000;
    width: 100%;
    height: 1px;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}
複製代碼

同時設置 4 條邊框:

.scale-1px {
    position: relative;
    margin-bottom: 20px;
    border:none;
}
.scale-1px::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #000;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
}
複製代碼

清除浮動

什麼是浮動:浮動元素會脫離文檔流並向左/向右浮動,直到碰到父元素或者另外一個浮動元素。

爲何要清楚浮動,它形成了什麼問題?

由於浮動元素會脫離正常的文檔流,並不會佔據文檔流的位置,因此若是一個父元素下面都是浮動元素,那麼這個父元素就沒法被浮動元素所撐開,這樣一來父元素就丟失了高度,這就是所謂的浮動形成的父元素高度坍塌問題。

父元素高度一旦坍塌將對後面的元素佈局形成影響,爲了解決這個問題,因此須要清除浮動,讓父元素恢復高度,那該如何作呢?

這裏介紹兩種方法:經過 BFC 來清除、經過 clear 來清除。

BFC 清除浮動

前面介紹 BFC 的時候提到過,計算 BFC 高度的時候浮動子元素的高度也將計算在內,利用這條規則就能夠清楚浮動。

假設一個父元素 parent 內部只有 2 個子元素 child,且它們都是左浮動的,這個時候 parent 若是沒有設置高度的話,由於浮動形成了高度坍塌,因此 parent 的高度會是 0,此時只要給 parent 創造一個 BFC,那它的高度就能恢復了。

而產生 BFC 的方式不少,咱們能夠給父元素設置overflow: auto 來簡單的實現 BFC 清除浮動,可是爲了兼容 IE 最好用 overflow: hidden。

.parent {
    overflow: hidden;
}
複製代碼

經過 overflow: hidden 來清除浮動並不完美,當元素有陰影或存在下拉菜單的時候會被截斷,因此該方法使用比較侷限。

經過 clear 清除浮動

我先把結論貼出來:

.clearfix {
    zoom: 1;
}
.clearfix::after {
    content: "";
    display: block;
    clear: both;
}
複製代碼

這種寫法的核心原理就是經過 ::after 僞元素爲在父元素的最後一個子元素後面生成一個內容爲空的塊級元素,而後經過 clear 將這個僞元素移動到全部它以前的浮動元素的後面,畫個圖來理解一下。

能夠結合這個 codepen demo 一塊兒理解上圖的 clear 清楚浮動原理。

上面這個 demo 或者圖裏爲了展現須要因此給僞元素的內容設置爲了 ::after,實際使用的時候須要設置爲空字符串,讓它的高度爲 0,從而父元素的高度都是由實際的子元素撐開。

該方式基本上是如今人人都在用的清除浮動的方案,很是通用。

參考:CSS中的浮動和清除浮動,梳理一下

消除瀏覽器默認樣式

針對同一個類型的 HTML 標籤,不一樣的瀏覽器每每有不一樣的表現,因此在網站製做的時候,開發者一般都是須要將這些瀏覽器的默認樣式清除,讓網頁在不一樣的瀏覽器上可以保持一致。

針對清除瀏覽器默認樣式這件事,在很早以前 CSS 大師 Eric A. Meyer 就幹過。它就是寫一堆通用的樣式用來重置瀏覽器默認樣式,這些樣式一般會放到一個命名爲 reset.css 文件中。好比大師的 reset.css 是這麼寫的:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
複製代碼

他的這份 reset.css 聽說是被使用最普遍的重設樣式的方案了。

除了 reset.css 外,後來又出現了 Normalize.css 。關於 Normalize.css, 其做者 necolas 專門寫了一篇文章介紹了它,並談到了它和 reset.css 的區別。這個是他寫那篇文章的翻譯版:讓咱們談一談 Normalize.css

文章介紹到:Normalize.css 只是一個很小的CSS文件,但它在默認的 HTML 元素樣式上提供了跨瀏覽器的高度一致性。相比於傳統的 CSS reset,Normalize.css 是一種現代的、爲 HTML5 準備的優質替代方案,如今已經有不少知名的框架和網站在使用它了。

Normalize.css 的具體樣式能夠看這裏 Normalize.css

區別於 reset.css,Normalize.css 有以下特色:

  • reset.css 幾乎爲全部標籤都設置了默認樣式,而 Normalize.css 則是有選擇性的保護了部分有價值的默認值;
  • 修復了不少瀏覽器的 bug,而這是 reset.css 沒作到的;
  • 不會讓你的調試工具變的雜亂,相反 reset.css 因爲設置了不少默認值,因此在瀏覽器調試工具中每每會看到一大堆的繼承樣式,顯得很雜亂;
  • Normalize.css 是模塊化的,因此能夠選擇性的去掉永遠不會用到的部分,好比表單的通常化;
  • Normalize.css 有詳細的說明文檔;

長文本處理

默認:字符太長溢出了容器

字符超出部分換行

字符超出位置使用連字符

單行文本超出省略

多行文本超出省略

查看以上這些方案的示例: codepen demo

有意思的是恰好前兩天看到 chokcoco 針對文本溢出也寫了一篇文章,主要突出的是對整塊的文本溢出處理。啥叫整塊文本?好比,下面這種技術標籤就是屬於整塊文本:

另外他還對 iOS/Safari 作了兼容處理,感興趣的能夠去閱讀下:CSS 整塊文本溢出省略特性探究

水平垂直居中

讓元素在父元素中呈現出水平垂直居中的形態,無非就 2 種狀況:

  • 單行的文本、inline 或者 inline-block 元素;
  • 固定寬高的塊級盒子;
  • 不固定寬高的塊級盒子;

如下列到的全部水平垂直居中方案這裏寫了個 codepen demo,配合示例閱讀效果更佳。

單行的文本、inline 或 inline-block 元素

水平居中

此類元素須要水平居中,則父級元素必須是塊級元素(block level),且父級元素上須要這樣設置樣式:

.parent {
    text-align: center;
}
複製代碼

垂直居中

方法一:經過設置上下內間距一致達到垂直居中的效果:

.single-line {
    padding-top: 10px;
    padding-bottom: 10px;
}
複製代碼

方法二:經過設置 heightline-height 一致達到垂直居中:

.single-line {
    height: 100px;
    line-height: 100px;
}
複製代碼

固定寬高的塊級盒子

方法一:absolute + 負 margin

方法二:absolute + margin auto

方法三:absolute + calc

不固定寬高的塊級盒子

這裏列了 6 種方法,參考了顏海鏡 寫的文章 ,其中的兩種 line-height 和 writing-mode 方案看後讓我驚呼:還有這種操做?學到了學到了。

方法一:absolute + transform

方法二:line-height + vertical-align

方法三:writing-mode

方法四:table-cell

方法五:flex

方法六:grid

經常使用佈局

兩欄佈局(邊欄定寬主欄自適應)

針對如下這些方案寫了幾個示例: codepen demo

方法一:float + overflow(BFC 原理)

方法二:float + margin

方法三:flex

方法四:grid

三欄佈局(兩側欄定寬主欄自適應)

針對如下這些方案寫了幾個示例: codepen demo

方法一:聖盃佈局

方法二:雙飛翼佈局

方法三:float + overflow(BFC 原理)

方法四:flex

方法五:grid

多列等高佈局

結合示例閱讀更佳:codepen demo

方法一:padding + 負margin

方法二:設置父級背景圖片

三行佈局(頭尾定高主欄自適應)

列了 4 種方法,都是基於以下的 HTML 和 CSS 的,結合示例閱讀效果更佳:codepen demo

<div class="layout">
    <header></header>
    <main>
        <div class="inner"></div>
    </main>
    <footer></footer>
</div>
複製代碼
html,
body,
.layout {
    height: 100%;
}
body {
    margin: 0;
}
header, 
footer {
    height: 50px;
}
main {
    overflow-y: auto;
}
複製代碼

方法一:calc

方法二:absolute

方法三:flex

方法四:grid

結了個尾

這是我斷斷續續寫了 2 周完成的文章,算是本身對 CSS 的一個總結,雖然寫得很長,但不足以覆蓋全部 CSS 的知識,好比動畫和一些 CSS3 的新特性就徹底沒涉及,由於這要寫下來估計得有大幾萬字(其實就是懶 😝 )。

碼字做圖不易,若是喜歡或者對你有絲毫幫助的話,幫忙點個👍 哈,點贊就是個人動力。同時也但願本身能堅持認真的寫下去,由於在總結提高本身的同時若是也能幫助更多的前端er,那將會讓我感受很開心。

相關文章
相關標籤/搜索