本篇文章圍繞了 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 裏包含了如下 @規則:
除了以上這幾個以外,下面還將對幾個比較生澀的 @規則 進行介紹。
@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 用於告訴 CSS 引擎引入一個外部樣式表。
link 和 @import 都能導入一個樣式文件,它們有什麼區別嘛?
@supports 用於查詢特定的 CSS 是否生效,能夠結合 not、and 和 or 操做符進行後續的操做。
/* 若是支持自定義屬性,則把 body 顏色設置爲變量 varName 指定的顏色 */
@supports (--foo: green) {
body {
color: var(--varName);
}
}
複製代碼
層疊樣式表,這裏的層疊怎麼理解呢?其實它是 CSS 中的核心特性之一,用於合併來自多個源的屬性值的算法。好比說針對某個 HTML 標籤,有許多的 CSS 聲明都能做用到的時候,那最後誰應該起做用呢?層疊性說的大概就是這個。
針對不一樣源的樣式,將按照以下的順序進行層疊,越往下優先級越高:
理解層疊性的時候須要結合 CSS 選擇器的優先級以及繼承性來理解。好比針對同一個選擇器,定義在後面的聲明會覆蓋前面的;做者定義的樣式會比默認繼承的樣式優先級更高。
CSS 選擇器無疑是其核心之一,對於基礎選擇器以及一些經常使用僞類必須掌握。下面列出了經常使用的選擇器。 想要獲取更多選擇器的用法能夠看 MDN CSS Selectors。
h1
.checked
#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 聲明的一個權重,它由匹配的選擇器中的每一種選擇器類型的數值決定。爲了記憶,能夠把權重分紅以下幾個等級,數值越大的權重越高:
能夠看到內聯樣式(經過元素中 style 屬性定義的樣式)的優先級大於任何選擇器;而給屬性值加上 !important
又能夠把優先級提至最高,就是由於它的優先級最高,因此須要謹慎使用它,如下有些使用注意事項:
在 CSS 中有一個很重要的特性就是子元素會繼承父元素對應屬性計算後的值。好比頁面根元素 html 的文本顏色默認是黑色的,頁面中的全部其餘元素都將繼承這個顏色,當申明瞭以下樣式後,H1 文本將變成橙色。
body {
color: orange;
}
h1 {
color: inherit;
}
複製代碼
設想一下,若是 CSS 中不存在繼承性,那麼咱們就須要爲不一樣文本的標籤都設置一下 color,這樣一來的後果就是 CSS 的文件大小就會無限增大。
CSS 屬性不少,但並非全部的屬性默認都是能繼承父元素對應屬性的,那哪些屬性存在默認繼承的行爲呢?必定是那些不會影響到頁面佈局的屬性,能夠分爲以下幾類:
font-family
、font-style
、font-size
、font-weight
等;text-align
、text-indent
、text-decoration
、text-shadow
、letter-spacing
、word-spacing
、white-space
、line-height
、color
等;list-style
、list-style-image
、list-style-type
、list-style-position
等;visibility
、cursor
等;對於其餘默認不繼承的屬性也能夠經過如下幾個屬性值來控制繼承行爲:
inherit
:繼承父元素對應屬性的計算值;initial
:應用該屬性的默認值,好比 color 的默認值是 #000
;unset
:若是屬性是默承認以繼承的,則取 inherit
的效果,不然同 initial
;revert
:效果等同於 unset
,兼容性差。在 CSS 的世界中,會把內容按照從左到右、從上到下的順序進行排列顯示。正常狀況下會把頁面分割成一行一行的顯示,而每行又可能由多列組成,因此從視覺上看起來就是從上到下從左到右,而這就是 CSS 中的流式佈局,又叫文檔流。文檔流就像水同樣,可以自適應所在的容器,通常它有以下幾個特性:
如何脫離文檔流呢?
脫流文檔流指節點脫流正常文檔流後,在正常文檔流中的其餘節點將忽略該節點並填補其原先空間。文檔一旦脫流,計算其父節點高度時不會將其高度歸入,脫流節點不佔據空間。有兩種方式可讓元素脫離文檔流:浮動和定位。
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 中一切皆盒子,而視覺格式化模型簡單來理解就是規定這些盒子應該怎麼樣放置到頁面中去,這個模型在計算的時候會依賴到不少的因素,好比:盒子尺寸、盒子類型、定位方案(是浮動仍是定位)、兄弟元素或者子元素以及一些別的因素。
從上圖中能夠看到視覺格式化模型涉及到的內容不少,有興趣深刻研究的能夠結合上圖看這個 W3C 的文檔 Visual formatting model。因此這裏就簡單介紹下盒子類型。
盒子類型由 display 決定,同時給一個元素設置 display 後,將會決定這個盒子的 2 個顯示類型(display type):
對外顯示方面,盒子類型能夠分紅 2 類:block-level box(塊級盒子) 和 inline-level box(行內級盒子)。
依據上圖能夠列出都有哪些塊級和行內級盒子:
全部塊級盒子都會參與 BFC,呈現垂直排列;而全部行內級盒子都參會 IFC,呈現水平排列。
除此以外,block、inline 和 inline-block 還有什麼更具體的區別呢?
block
inline
inline-block
對內方面,其實就是把元素當成了容器,裏面包裹着文本或者其餘子元素。container box 的類型依據 display 的值不一樣,分爲 4 種:
值得一提的是若是把 img 這種替換元素(replaced element)申明爲 block 是不會產生 container box 的,由於替換元素好比 img 設計的初衷就僅僅是經過 src 把內容替換成圖片,徹底沒考慮過會把它當成容器。
參考:
格式化上下文(Formatting Context)是 CSS2.1 規範中的一個概念,大概說的是頁面中的一塊渲染區域,規定了渲染區域內部的子元素是如何排版以及相互做用的。
不一樣類型的盒子有不一樣格式化上下文,大概有這 4 類:
其中 BFC 和 IFC 在 CSS 中扮演着很是重要的角色,由於它們直接影響了網頁佈局,因此須要深刻理解其原理。
塊格式化上下文,它是一個獨立的渲染區域,只有塊級盒子參與,它規定了內部的塊級盒子如何佈局,而且與這個區域外部絕不相干。
BFC 渲染規則
如何建立 BFC?
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 渲染規則,你是否是能夠分析下下面這段代碼的 IFC 環境是怎麼樣的呢?
<p>It can get <strong>very complicated</storng> once you start looking into it.</p>
複製代碼
對應上面這樣一串 HTML 分析以下:
IFC 應用場景
偷個懶,demo 和圖我就不作了。
在電腦顯示屏幕上的顯示的頁面實際上是一個三維的空間,水平方向是 X 軸,豎直方向是 Y 軸,而屏幕到眼睛的方向能夠當作是 Z 軸。衆 HTML 元素依據本身定義的屬性的優先級在 Z 軸上按照必定的順序排開,而這其實就是層疊上下文所要描述的東西。
咱們對層疊上下文的第一印象可能要來源於 z-index,認爲它的值越大,距離屏幕觀察者就越近,那麼層疊等級就越高,事實確實是這樣的,但層疊上下文的內容遠非僅僅如此:
在看層疊等級和層疊順序以前,咱們先來看下如何產生一個層疊上下文,特定的 HTML 元素或者 CSS 屬性產生層疊上下文,MDN 中給出了這麼一個列表,符合如下任一條件的元素都會產生層疊上下文:
層疊等級
層疊等級指節點在三維空間 Z 軸上的上下順序。它分兩種狀況:
普通節點的層疊等級優先由其所在的層疊上下文決定,層疊等級的比較只有在當前層疊上下文中才有意義,脫離當前層疊上下文的比較就變得無心義了。
層疊順序
在同一個層疊上下文中若是有多個元素,那麼他們之間的層疊順序是怎麼樣的呢?
如下這個列表越往下層疊優先級越高,視覺上的效果就是越容易被用戶看到(不會被其餘元素覆蓋):
如何比較兩個元素的層疊等級?
參考:完全搞懂CSS層疊上下文、層疊等級、層疊順序、z-index
CSS 的聲明是由屬性和值組成的,而值的類型有許多種:
而還有些值是須要帶單位的,好比 width: 100px,這裏的 px 就是表示長度的單位,長度單位除了 px 外,比較經常使用的還有 em、rem、vw/vh 等。那他們有什麼區別呢?又應該在何時使用它們呢?
屏幕分辨率是指在屏幕的橫縱方向上的像素點數量,好比分辨率 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 是 CSS 中的相對長度單位中的一個。竟然是相對的,那它究竟是相對的誰呢?它有 2 層意思:
咱們都知道每一個瀏覽器都會給 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(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 分別是相對於屏幕視口寬度和高度而言的長度單位:
在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。
vw/vh 的出現使得多了一種寫自適應佈局的方案,開發者再也不侷限於 rem 了。
相對視口的單位,除了 vw/vh 外,還有 vmin 和 vmax:
CSS 中用於表示顏色的值種類繁多,足夠構成一個體系,因此這裏就專門拿出一個小節來說解它。
根據 CSS 顏色草案 中提到的顏色值類型,大概能夠把它們分爲這幾類:
顏色關鍵字(color keywords)是不區分大小寫的標識符,它表示一個具體的顏色,好比 white(白),黑(black)等;
可接受的關鍵字列表在CSS的演變過程當中發生了改變:
以下這張圖是 16 個基礎色,又叫 VGA 顏色。截止到目前爲止 CSS 顏色關鍵字總共有 146 個,這裏能夠查看 完整的色彩關鍵字列表。
須要注意的是若是聲明的時候的顏色關鍵字是錯誤的,瀏覽器會忽略它。
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 實現三角形的原理:
看下示例:
增大點擊區域
經常在移動端的時候點擊的按鈕的區域特別小,可是因爲現實效果又不太好把它作大,因此經常使用的一個手段就是經過透明的邊框來增大按鈕的點擊區域:
.btn {
border: 5px solid transparent;
}
複製代碼
currentColor 會取當前元素繼承父級元素的文本顏色值或聲明的文本顏色值,即 computed 後的 color 值。
好比,對於以下 CSS,該元素的邊框顏色會是 red:
.btn {
color: red;
border: 1px solid currentColor;
}
複製代碼
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] 顏色是由色相(hue)-飽和度(saturation)-亮度(lightness)-不透明度組成的顏色體系。
寫法上能夠參考 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" />
複製代碼
都支持哪些設備類型?
須要注意的是:經過 media 指定的 資源儘管不匹配它的設備類型,可是瀏覽器依然會加載它。
除了經過 <link>
讓指定設備生效外,還能夠經過 @media
讓 CSS 規則在特定的條件下才能生效。響應式頁面就是使用了 @media 才讓一個頁面可以同時適配 PC、Pad 和手機端。
@media (min-width: 1000px) {}
複製代碼
媒體查詢支持邏輯操做符:
媒體查詢還支持衆多的媒體特性,使得它能夠寫出很複雜的查詢條件:
/* 用戶設備的最小高度爲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。
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 高度的時候浮動子元素的高度也將計算在內,利用這條規則就能夠清楚浮動。
假設一個父元素 parent 內部只有 2 個子元素 child,且它們都是左浮動的,這個時候 parent 若是沒有設置高度的話,由於浮動形成了高度坍塌,因此 parent 的高度會是 0,此時只要給 parent 創造一個 BFC,那它的高度就能恢復了。
而產生 BFC 的方式不少,咱們能夠給父元素設置overflow: auto 來簡單的實現 BFC 清除浮動,可是爲了兼容 IE 最好用 overflow: hidden。
.parent {
overflow: hidden;
}
複製代碼
經過 overflow: hidden 來清除浮動並不完美,當元素有陰影或存在下拉菜單的時候會被截斷,因此該方法使用比較侷限。
我先把結論貼出來:
.clearfix {
zoom: 1;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
複製代碼
這種寫法的核心原理就是經過 ::after 僞元素爲在父元素的最後一個子元素後面生成一個內容爲空的塊級元素,而後經過 clear 將這個僞元素移動到全部它以前的浮動元素的後面,畫個圖來理解一下。
能夠結合這個 codepen demo 一塊兒理解上圖的 clear 清楚浮動原理。
上面這個 demo 或者圖裏爲了展現須要因此給僞元素的內容設置爲了 ::after,實際使用的時候須要設置爲空字符串,讓它的高度爲 0,從而父元素的高度都是由實際的子元素撐開。
該方式基本上是如今人人都在用的清除浮動的方案,很是通用。
針對同一個類型的 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 有以下特色:
默認:字符太長溢出了容器
字符超出部分換行
字符超出位置使用連字符
單行文本超出省略
多行文本超出省略
查看以上這些方案的示例: codepen demo
有意思的是恰好前兩天看到 chokcoco 針對文本溢出也寫了一篇文章,主要突出的是對整塊的文本溢出處理。啥叫整塊文本?好比,下面這種技術標籤就是屬於整塊文本:
另外他還對 iOS/Safari 作了兼容處理,感興趣的能夠去閱讀下:CSS 整塊文本溢出省略特性探究。
讓元素在父元素中呈現出水平垂直居中的形態,無非就 2 種狀況:
如下列到的全部水平垂直居中方案這裏寫了個 codepen demo,配合示例閱讀效果更佳。
水平居中
此類元素須要水平居中,則父級元素必須是塊級元素(block level
),且父級元素上須要這樣設置樣式:
.parent {
text-align: center;
}
複製代碼
垂直居中
方法一:經過設置上下內間距一致達到垂直居中的效果:
.single-line {
padding-top: 10px;
padding-bottom: 10px;
}
複製代碼
方法二:經過設置 height
和 line-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,那將會讓我感受很開心。