您好,登錄后才能下訂單哦!
這篇文章主要講解了“CSS的核心知識點總結”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“CSS的核心知識點總結”吧!
CSS 的核心功能是將 CSS 屬性設定為特定的值。一個屬性與值的鍵值對被稱為聲明(declaration)。
color: red;
而如果將一個或者多個聲明用 {} 包裹起來后,那就組成了一個聲明塊(declaration block)。
{ color: red; text-align: center; }
span { color: red; text-align: center; }
“規則集中最后一條聲明可以省略分號,但是并不建議這么做,因為容易出錯。
CSS 中的注釋:
/* 單行注釋 */ /* 多行 注釋 */
在 CSS 文件中,除了注釋、CSS 規則集以及 @規則 外,定義的一些別的東西都將被瀏覽器忽略。
CSS 規則是樣式表的主體,通常樣式表會包括大量的規則列表。但有時候也需要在樣式表中包括其他的一些信息,比如字符集,導入其它的外部樣式表,字體等,這些需要專門的語句表示。
而 @規則 就是這樣的語句。CSS 里包含了以下 @規則:
@namespace 告訴 CSS 引擎必須考慮XML命名空間。
@media, 如果滿足媒體查詢的條件則條件規則組里的規則生效。
@page, 描述打印文檔時布局的變化.
@font-face, 描述將下載的外部的字體。
@keyframes, 描述 CSS 動畫的關鍵幀。
@document, 如果文檔樣式表滿足給定條件則條件規則組里的規則生效。 (推延至 CSS Level 4 規范)
除了以上這幾個之外,下面還將對幾個比較生澀的 @規則 進行介紹。
@charset[1] 用于定義樣式表使用的字符集。它必須是樣式表中的第一個元素。如果有多個 @charset 被聲明,只有第一個會被使用,而且不能在HTML元素或HTML頁面的 <style> 元素內使用。
注意:值必須是雙引號包裹,且和
@charset "UTF-8";
平時寫樣式文件都沒寫 @charset 規則,那這個 CSS 文件到底是用的什么字符編碼的呢?
某個樣式表文件到底用的是什么字符編碼,瀏覽器有一套識別順序(優先級由高到低):
文件開頭的 Byte order mark[2] 字符值,不過一般編輯器并不能看到文件頭里的 BOM 值;
HTTP 響應頭里的 content-type 字段包含的 charset 所指定的值,比如:
Content-Type: text/css; charset=utf-8
CSS 文件頭里定義的 @charset 規則里指定的字符編碼;
標簽里的 charset 屬性,該條已在 HTML5 中廢除;
默認是 UTF-8。
@import[3] 用于告訴 CSS 引擎引入一個外部樣式表。
link 和 @import 都能導入一個樣式文件,它們有什么區別嘛?
link 是 HTML 標簽,除了能導入 CSS 外,還能導入別的資源,比如圖片、腳本和字體等;而 @import 是 CSS 的語法,只能用來導入 CSS;
link 導入的樣式會在頁面加載時同時加載,@import 導入的樣式需等頁面加載完成后再加載;
link 沒有兼容性問題,@import 不兼容 ie5 以下;
link 可以通過 JS 操作 DOM 動態引入樣式表改變樣式,而@import不可以。
@supports[4] 用于查詢特定的 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[5]。
標簽選擇器:h2
類選擇器:.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; } h2 { 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 中的流式布局,又叫文檔流。文檔流就像水一樣,能夠自適應所在的容器,一般它有如下幾個特性:
塊級元素默認會占滿整行,所以多個塊級盒子之間是從上到下排列的;
內聯元素默認會在一行里一列一列的排布,當一行放不下的時候,會自動切換到下一行繼續按照列排布;
脫流文檔流指節點脫流正常文檔流后,在正常文檔流中的其他節點將忽略該節點并填補其原先空間。文檔一旦脫流,計算其父節點高度時不會將其高度納入,脫流節點不占據空間。有兩種方式可以讓元素脫離文檔流:浮動和定位。
使用浮動(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[6]。所以這里就簡單介紹下盒子類型。
盒子類型由 display 決定,同時給一個元素設置 display 后,將會決定這個盒子的 2 個顯示類型(display type):
outer display type(對外顯示):決定了該元素本身是如何布局的,即參與何種格式化上下文;
inner 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 還有什么更具體的區別呢?
占滿一行,默認繼承父元素的寬度;多個塊元素將從上到下進行排列;
設置 width/height 將會生效;
設置 padding 和 margin 將會生效;
不會占滿一行,寬度隨著內容而變化;多個 inline 元素將按照從左到右的順序在一行里排列顯示,如果一行顯示不下,則自動換行;
設置 width/height 將不會生效;
設置豎直方向上的 padding 和 margin 將不會生效;
是行內塊元素,不單獨占滿一行,可以看成是能夠在一行里進行左右排列的塊元素;
設置 width/height 將會生效;
設置 padding 和 margin 將會生效;
對內方面,其實就是把元素當成了容器,里面包裹著文本或者其他子元素。container box 的類型依據 display 的值不同,分為 4 種:
block container:建立 BFC 或者 IFC;
flex container:建立 FFC;
grid container:建立 GFC;
ruby container:接觸不多,不做介紹。
值得一提的是如果把 img 這種替換元素(replaced element)申明為 block 是不會產生 container box 的,因為替換元素比如 img 設計的初衷就僅僅是通過 src 把內容替換成圖片,完全沒考慮過會把它當成容器。
參考:
CSS 原理 - 你所不知道的 display[7]
格式化上下文[8]
格式化上下文(Formatting Context)是 CSS2.1 規范中的一個概念,大概說的是頁面中的一塊渲染區域,規定了渲染區域內部的子元素是如何排版以及相互作用的。
不同類型的盒子有不同格式化上下文,大概有這 4 類:
BFC (Block Formatting Context) 塊級格式化上下文;
IFC (Inline Formatting Context) 行內格式化上下文;
FFC (Flex Formatting Context) 彈性格式化上下文;
GFC (Grid Formatting Context) 格柵格式化上下文;
其中 BFC 和 IFC 在 CSS 中扮演著非常重要的角色,因為它們直接影響了網頁布局,所以需要深入理解其原理。
塊格式化上下文,它是一個獨立的渲染區域,只有塊級盒子參與,它規定了內部的塊級盒子如何布局,并且與這個區域外部毫不相干。
圖來源于 yachen168
內部的盒子會在垂直方向,一個接一個地放置;
盒子垂直方向的距離由 margin 決定,屬于同一個 BFC 的兩個相鄰盒子的 margin 會發生重疊;
每個元素的 margin 的左邊,與包含塊 border 的左邊相接觸(對于從左往右的格式化,否則相反),即使存在浮動也是如此;
BFC 的區域不會與 float 盒子重疊;
BFC 就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
計算 BFC 的高度時,浮動元素也參與計算。
根元素:html
非溢出的可見元素:overflow 不為 visible
設置浮動:float 屬性不為 none
設置定位:position 為 absolute 或 fixed
定義成塊級的非塊級元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid
1、 自適應兩欄布局
應用原理: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; }
2、清除內部浮動
浮動造成的問題就是父元素高度坍塌,所以清除浮動需要解決的問題就是讓父元素的高度恢復正常。而用 BFC 清除浮動的原理就是:計算 BFC 的高度時,浮動元素也參與計算。只要觸發父元素的 BFC 即可。
.parent { overflow: hidden; }
3、 防止垂直 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[9]
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[10]
水平居中:當一個塊要在環境中水平居中時,設置其為 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 的元素:
鴻蒙官方戰略合作共建——HarmonyOS技術社區
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[11]
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 等。那他們有什么區別呢?又應該在什么時候使用它們呢?
屏幕分辨率是指在屏幕的橫縱方向上的像素點數量,比如分辨率 1920×1080 意味著水平方向含有 1920 個像素數,垂直方向含有 1080 個像素數。
而 px 表示的是 CSS 中的像素,在 CSS 中它是絕對的長度單位,也是最基礎的單位,其他長度單位會自動被瀏覽器換算成 px。但是對于設備而言,它其實又是相對的長度單位,比如寬高都為 2px,在正常的屏幕下,其實就是 4 個像素點,而在設備像素比(devicePixelRatio) 為 2 的 Retina 屏幕下,它就有 16 個像素點。所以屏幕尺寸一致的情況下,屏幕分辨率越高,顯示效果就越細膩。
講到這里,還有一些相關的概念需要理清下:
設備屏幕的物理像素,表示的是屏幕的橫縱有多少像素點;和屏幕分辨率是差不多的意思。
設備像素比表示 1 個 CSS 像素等于幾個物理像素。
計算公式:DPR = 物理像素數 / 邏輯像素數;
在瀏覽器中可以通過 window.devicePixelRatio 來獲取當前屏幕的 DPR。
像素密度也叫顯示密度或者屏幕密度,縮寫為 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。從技術角度說,PPI 只存在于計算機顯示領域,而 DPI 只出現于打印或印刷領域。
計算公式:像素密度 = 屏幕對角線的像素尺寸 / 物理尺寸
比如,對于分辨率為 750 * 1334 的 iPhone 6 來說,它的像素密度為:
Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi
DIP 是特別針對 Android設備而衍生出來的,原因是安卓屏幕的尺寸繁多,因此為了顯示能盡量和設備無關,而提出的這個概念。它是基于屏幕密度而計算的,認為當屏幕密度是 160 的時候,px = DIP。
計算公式:dip = px * 160 / dpi
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(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 分別是相對于屏幕視口寬度和高度而言的長度單位:
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 顏色草案[12] 中提到的顏色值類型,大概可以把它們分為這幾類:
顏色關鍵字
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 個,這里可以查看 完整的色彩關鍵字列表[13]。
VGA 顏色
需要注意的是如果聲明的時候的顏色關鍵字是錯誤的,瀏覽器會忽略它。
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 會取當前元素繼承父級元素的文本顏色值或聲明的文本顏色值,即 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)-不透明度組成的顏色體系。
色相(H)是色彩的基本屬性,值范圍是 0~360 或者 0deg~360deg, 0 (或 360) 為紅色, 120 為綠色, 240 為藍色;
飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取 0~100% 的數值;0% 為灰色, 100% 全色;
亮度(L),取 0~100%,0% 為暗,100% 為白;
不透明度(A),取 0~100%,或者0~1及之間的小數;
寫法上可以參考 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 + 鼠標左鍵可以切換顏色的表示方式。
媒體查詢是指針對不同的設備、特定的設備特征或者參數進行定制化的修改網站的樣式。
你可以通過給 加上 media 屬性來指定該樣式文件只能對什么設備生效,不指定的話默認是 all,即對所有設備都生效:
<link rel="stylesheet" src="styles.css" media="screen" /> <link rel="stylesheet" src="styles.css" media="print" />
都支持哪些設備類型?
all:適用于所有設備;
print:適用于在打印預覽模式下在屏幕上查看的分頁材料和文檔;
screen:主要用于屏幕;
speech:主要用于語音合成器。
“需要注意的是:通過 media 指定的 資源盡管不匹配它的設備類型,但是瀏覽器依然會加載它。
除了通過 讓指定設備生效外,還可以通過 @media 讓 CSS 規則在特定的條件下才能生效。響應式頁面就是使用了 @media 才讓一個頁面能夠同時適配 PC、Pad 和手機端。
@media (min-width: 1000px) {}
媒體查詢支持邏輯操作符:
and:查詢條件都滿足的時候才生效;
not:查詢條件取反;
only:整個查詢匹配的時候才生效,常用語兼容舊瀏覽器,使用時候必須指定媒體類型;
逗號或者 or:查詢條件滿足一項即可匹配;
媒體查詢還支持眾多的媒體特性[14],使得它可以寫出很復雜的查詢條件:
/* 用戶設備的最小高度為680px或為縱向模式的屏幕設備 */ @media (min-height: 680px), screen and (orientation: portrait) {}
之前我們通常是在預處理器里才可以使用變量,而現在 CSS 里也支持了變量的用法。通過自定義屬性就可以在想要使用的地方引用它。
自定義屬性也和普通屬性一樣具有級聯性,申明在 :root 下的時候,在全文檔范圍內可用,而如果是在某個元素下申明自定義屬性,則只能在它及它的子元素下才可以使用。
自定義屬性必須通過 --x 的格式申明,比如:--theme-color: red; 使用自定義屬性的時候,需要用 var 函數。比如:
<!-- 定義自定義屬性 --> :root { --theme-color: red; } <!-- 使用變量 --> h2 { color: var(--theme-color); }
上圖這個是使用 CSS 自定義屬性配合 JS 實現的動態調整元素的 box-shadow,具體可以看這個 codepen demo。
Retina 顯示屏比普通的屏幕有著更高的分辨率,所以在移動端的 1px 邊框就會看起來比較粗,為了美觀通常需要把這個線條細化處理。這里有篇文章列舉了 7 中方案可以參考一下:7種方法解決移動端Retina屏幕1px邊框問題[15]
而這里附上最后一種通過偽類和 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,從而父元素的高度都是由實際的子元素撐開。
該方式基本上是現在人人都在用的清除浮動的方案,非常通用。
參考:CSS中的浮動和清除浮動,梳理一下[16]
針對同一個類型的 HTML 標簽,不同的瀏覽器往往有不同的表現,所以在網站制作的時候,開發者通常都是需要將這些瀏覽器的默認樣式清除,讓網頁在不同的瀏覽器上能夠保持一致。
針對清除瀏覽器默認樣式這件事,在很早之前 CSS 大師 Eric A. Meyer 就干過。它就是寫一堆通用的樣式用來重置瀏覽器默認樣式,這些樣式通常會放到一個命名為 reset.css 文件中。比如大師的 reset.css[17] 是這么寫的:
html, body, div, span, applet, object, iframe, h2, h3, h4, h5, h6, h7, 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[18] 。關于 Normalize.css, 其作者 necolas 專門寫了一篇文章介紹了它,并談到了它和 reset.css 的區別。這個是他寫那篇文章的翻譯版:讓我們談一談 Normalize.css[19]。
文章介紹到: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
啥叫整塊文本?比如,下面這種技術標簽就是屬于整塊文本:
另外他還對 iOS/Safari 做了兼容處理,感興趣的可以去閱讀下:CSS 整塊文本溢出省略特性探究[20]。
讓元素在父元素中呈現出水平垂直居中的形態,無非就 2 種情況:
單行的文本、inline 或者 inline-block 元素;
固定寬高的塊級盒子;
不固定寬高的塊級盒子;
以下列到的所有水平垂直居中方案這里寫了個 codepen demo,配合示例閱讀效果更佳。
單行的文本、inline 或 inline-block 元素
此類元素需要水平居中,則父級元素必須是塊級元素(block level),且父級元素上需要這樣設置樣式:
.parent { text-align: center; }
方法一:通過設置上下內間距一致達到垂直居中的效果:
.single-line { padding-top: 10px; padding-bottom: 10px; }
方法二:通過設置 height 和 line-height 一致達到垂直居中:
.single-line { height: 100px; line-height: 100px; }
固定寬高的塊級盒子
針對以下這些方案寫了幾個示例: codepen demo
針對以下這些方案寫了幾個示例: codepen demo
列了 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; }
感謝各位的閱讀,以上就是“CSS的核心知識點總結”的內容了,經過本文的學習后,相信大家對CSS的核心知識點總結這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。