CSS 細節難點綜合

對於CSS,要知其然,還要知其所以然。本文將介紹CSS各部分出現的原因,僅限個人理解,如有不妥,歡迎交流

Why CSS

早期的大多數網站標記幾乎完全由表格和font元素組成,且對於所要表現的內容不能傳達任何實際含義,使文檔可用性降低,且不易於維護。於是1995年,W3C發佈了CSS草案,試圖解決結構與樣式混雜的問題

1、如果考慮結構與樣式徹底分離,且樣式表可能用於多個HTML文件,使用[外部樣式表]

2、如果樣式表僅用於當前頁面,且減少[HTTP]請求數量,使用[內部樣式表]
  3、如果只是想爲單個元素指定一些樣式,可以使用HTML的style屬性來設置一個[行間樣式]

Why 選擇器

通過[CSS選擇器],向文檔中的一組元素類型應用某些規則

1、通配選擇器選擇所有元素

2、元素選擇器按照HTML標籤來選擇元素

3、類選擇器通過定義類名來選擇一類元素

4、ID選擇器選擇特定ID的元素

5、屬性選擇器根據元素的屬性及屬性值來選擇元素

6、後代選擇器通過HTML層級關係來選擇元素

7、分組選擇器將具有相同規則的元素合併設置

Why 層疊

CSS(cascading style sheets)中文翻譯過來是層疊樣式表,最基本的一個特性就是[層疊]。衝突的聲明通過層疊進行排序,由此確定最終的文檔表示

在下面的例子,元素選擇器div和類選擇器.test都可以選擇出<div class="test"></div>,這就發生了衝突。由於類選擇器的特殊性大於元素選擇器,所以通過層疊進行排序,最終該元素的樣式爲{height: 200px;} ,如果去掉 .test{height: 200px;} 這條規則,則元素的樣式爲{height: 100px;}

<style>
div{height: 100px;}
.test{height: 200px;}    
</style>
<div class="test"></div>

Why 解析順序

爲什麼CSS選擇器的解析順序是從右到左呢?先給結論,因爲更快

如果正向解析,例如「div div p em」,首先要檢查當前元素到 html 的整條路徑,找到最上層的 div,再往下找,如果遇到不匹配就必須回到最上層那個 div,往下再去匹配選擇器中的第一個 div,回溯若干次才能確定匹配與否,效率很低

逆向匹配則不同,如果當前的 DOM 元素是 div,而不是 selector 最後的 em,那隻要一步就能排除。只有在匹配時,纔會不斷向上找父節點進行驗證

正向解析是在試錯,而逆向匹配則是在挑選正確的元素。因爲匹配的情況遠遠低於不匹配的情況,所以逆向匹配帶來的優勢是巨大的

Why Hack

[CSS Hack]是實現瀏覽器樣式兼容的兜底辦法,能不用就儘量不要使用。但是,針對一些瀏覽器的bug,比如老版本IE的bug,有時使用CSS Hack是不得已而爲之的做法

比如,對於IE6-瀏覽器主要使用下劃線_和中劃線-這兩種字符實現hack。如下所示,在IE6瀏覽器中,div的文本顏色爲藍色,其他瀏覽器則爲紅色

div{
color:red;
_color:blue;
}
專門建立的學習Q-q-u-n: 731771211,分享學習方法和需要注意的小細節,不停更新最新的教程和學習技巧
(從零基礎開始到前端項目實戰教程,學習工具,全棧開發學習路線以及規劃)

Why 僞類和僞元素

個人認爲,[僞類]和[僞元素]是對HTML元素的一個擴展,通過它們可以豐富元素的樣式表現

僞類即假的類,類似於通過添加一個實際的類來達到效果,比如常見的hover鼠標懸停效果

a:hover{background-color:lightblue;}/*淺藍,鼠標懸停*/

僞元素即假的元素,類似於通過添加一個實際的元素才能達到。當然,添加的不是元素,而是生成內容,生成內容主要指由瀏覽器創建的內容,比如:before和:after

Why 單位

從廣義上講,單位是一個相對概念,其爲事物座標系中的座標軸中能構成個體的抽象概念。長度單位是指丈量空間距離上的基本單元,是CSS爲了規範長度而制定的基本單位。

爲了更好的丈量和表示頁面的長度,CSS規定了絕對長度單位、字體相關的長度單位、視口相關的長度單位

【絕對長度單位】

絕對長度單位代表一個物理測量,包括像素px(pixels)、英寸in(inches)、英寸in(inches)、英寸in(inches)、英寸in(inches)、1/4毫米q(quarter-millimeters)、點pt(points)、派卡pc(picas)

在web上,像素px是典型的度量單位,很多其他長度單位直接映射成像素。最終,他們被按照像素處理

1in = 2.54cm = 96px 
1cm = 10mm = 96px/2.54 = 37.8px
1mm = 0.1cm = 3.78px
1q = 1/4mm = 0.945px
1pt = 1/72in = =0.0139in = 1/72*2.54cm = 1/72*96px = 1.33px
1pc = 12pt = 1/6in = 1/6*96px = 16px

【字體相關的長度單位】

字體相關的相對長度單位包括em、ex、ch、rem

em表示元素的font-size屬性的計算值,如果用於font-size屬性本身,相對於父元素的font-size;若用於其他屬性,相對於本身元素的font-size

rem是相對於根元素html的font-size屬性的計算值

ex是指所用字體中小寫x的高度。但不同字體x的高度可能不同。實際上,很多瀏覽器取em值一半作爲ex值

ch與ex類似,被定義爲數字0的寬度。當無法確定數字0寬度時,取em值的一半作爲ch值

【視口相關的長度單位】

視口相關的長度值相對於初始包含塊的大小。當初始包含塊的寬高變化時,他們都會相應地縮放。然而,當根元素的overflow值爲auto時,任何滾動條會假定不存在

關於視口相關的單位有vh、vw、vmin、vmax4個單位

vh:佈局視口高度的 1/100
vw:佈局視口寬度的 1/100
vmin:佈局視口高度和寬度之間的最小值的 1/100
vmax:佈局視口高度和寬度之間的最大值的 1/100

Why 盒模型

[盒模型]是CSS佈局的基礎,它描述了一個元素在文檔佈局中所佔的空間大小。而且,每個框影響着其他元素框的位置和大小

【box-sizing】

在CSS中[盒模型]被分爲兩種,第一種是W3C的標準模型,第二種是IE怪異盒模型。不同之處在於後者的寬高定義的是可見元素框的尺寸,而不是元素框的內容區尺寸。目前對於瀏覽器大多數元素都是基於W3C標準的盒模型,但對於表單form中的部分元素還是基於IE的怪異盒模型,如input裏的radio、checkbox、button等元素,如果給其設置border和padding它們也只會往元素盒內延伸

在W3C的標準模型下,寬度和高度僅僅包含了內容寬度,除去了邊框和內邊距兩個區域,這樣爲web設計師處理效果帶來了不少麻煩。爲了解決這個問題,CSS3新增了一個盒模型屬性box-sizing,能夠事先定義盒模型的尺寸解析方式

Why margin重疊

在網頁佈局中,因爲margin重疊的原因,我們常常把margin作爲一個“問題樣式”而儘量少地使用它。但實際上,它是在很大的作用的

HTML文檔創建的初衷只是用來展示信息的。HTML文檔只使用默認樣式的前提下,如果上下margin不發生重疊,則會出現以下幾個問題:1、連續段落或列表之類,如果沒有margin重疊,首尾項間距會和其他兄弟元素呈現1:2的關係,排版不自然;2、web中任何地方嵌套或直接放入任何裸div,都會影響原生的佈局,與web設計原則相違背;3、遺落的空的任意多個p標籤,會影響原來的閱讀排版

所以,我們要善用重疊,可以在列表項中同時使用margin-top和margin-bottom。這樣,使頁面結構更具有健壯性,最後一個元素移除或位置調換,都不會破壞原生的佈局

【-webkit-margin-collapse】

-webkit-margin-collapse: <collapse>(默認重疊) | <discard>(取消) | <separate>(分隔)

該屬性用於設置margin是否重疊,作用於發生margin重疊的兩個元素之一。如果,兩個都使用該屬性,一個設置爲discard,一個設置爲separate,則最終效果爲重疊collase

Why auto

理解[視覺格式化],可以確定得到的效果是應該顯示的正確效果,還是瀏覽器兼容性的bug。視覺格式化中比較重要的一個概念就是auto,auto值是用來彌補實際值與所需總和的差距

【爲什麼塊級元素的寬度默認撐滿父級元素】

因爲塊級元素width默認值爲auto,而margin、border和padding默認值都爲0,依據塊級元素框的水平總和等於父元素的width的計算公式,塊級元素的寬度width默認等於包含塊也就是父元素的寬度width

【爲什麼塊級元素設置寬度後,默認居左顯示】

因爲爲塊級元素設置寬度後,而margin、border和padding默認值都爲0,依據塊級元素框的水平總和等於父元素的width的計算公式。 這種情況,叫做格式化屬性過分受限(overconstrained),此時總會把margin-right強制爲auto,從而使居左顯示,margin-right來補足剩餘的寬度

【爲什麼固定寬度的塊級元素設置margin:auto可以實現水平居中顯示】

同樣依據塊級元素框的水平總和等於父元素的width的計算公式,border、padding爲0,設置固定寬度後,margin-left和margin-right平分剩餘的寬度

【爲什麼塊級元素的高度默認爲元素自身高度】

個人認爲,這與瀏覽器先從左到右,再從上到下的渲染機制有關。這種渲染機制決定了寬度值是確定的,高度值是元素自身高度。如果高度值也是確定的,即視口高度,則每渲染一個塊級元素,就要佔滿整個屏幕大小,無疑是一個災難;所以,瀏覽器在保證足夠寬的情況下,就需要儘量小的高度,這個儘量小的高度就是元素自身高度

【爲什麼塊級元素設置margin:auto無法實現垂直居中顯示】

瀏覽器對於margin-top、margin-bottom爲auto時,會自動將其重置爲0。如果要實現垂直居中,可以利用calc()自己計算,如果height爲100px,border爲0,padding爲10px,包含塊的高度爲200px,則margin-top = calc((200px - 100px - 10px -10px) / 2)

注意:要考慮垂直方向上的margin重疊問題

【爲什麼圖片設置margin:auto不可以實現水平居中顯示】

圖片無法水平居中,類似於塊級元素無法垂直居中。因爲圖片的寬度width默認是自身寬度,左右margin設置爲auto,會被重置爲0;如果要實現水平居中顯示,把圖片display設置爲block即可

Why 行高和垂直對齊

普通流下,塊級元素的佈局主要基礎是盒模型,而行內元素(包括inline-block元素)的佈局則主要依靠line-height和vertical-align

line-height行高是指文本行基線之間的距離。vertical-align用來設置垂直對齊方式,所有垂直對齊的元素都會影響行高

【爲什麼inline-block元素會存在底部空隙】

inline-block元素在塊級元素中留空隙是因爲圖像的默認垂直對齊方式是基線對齊(基線對齊在原理上相當於圖像底邊與匿名文本大寫英文字母X的底邊對齊);而匿名文本是有行高的,繼承父級元素設置的行高,默認爲normal(chrome下爲font-size的1.334倍),所以X的底邊距離行框的底邊有一段距離,這段距離就是圖像留出的空隙

於是,解決這個問題有以下3種解決辦法

1、設置display:block,因爲垂直對齊方式只能作用於替換元素和行內元素,更改爲塊級元素,會使垂直對齊方式失效

2、設置父級的line-height: 0,這樣使匿名文本與行框的距離爲0

3、設置vertical-align爲top/middle/bottom

【爲什麼行內元素垂直margin無效】

因爲行內元素垂直佈局主要是通過行高line-height和垂直對齊vertical-align來影響的,垂直margin並不會影響它們,所以不會影響垂直佈局。而在顯示方式,margin區域不會顯示元素背景,所以也不會影響自身元素的顯示,所以行內元素垂直margin無效

Why 浮動

[浮動]最早的使用是出自<img src="#" align="right">,用於文本環繞圖片的排版處理。如今浮動作爲CSS中常用的佈局方式

浮動元素脫離普通流,然後按照指定方向,向左或者向右移動,碰到父級邊界或者另外一個浮動元素停止。浮動具有以下4個特性:

1、浮動流:正常流中元素一個接一個排列;浮動元素也構成浮動流

2、塊級框:浮動元素自身會生成一個塊級框,不論這個元素本身是什麼,使浮動元素周圍的外邊距不會合並

3、包裹性:浮動元素的包含塊是指其最近的塊級祖先元素,後代浮動元素不應該超出包含塊的上、左、右邊界。若不設置包含塊的高度,包含塊若浮動,則包含塊會延伸,進而包含其所有後代浮動元素;若不設置包含塊的寬度,包含塊若浮動,則包含塊寬度由後代浮動元素撐開

4、破壞性:浮動動元素脫離正常流,並破壞了自身的行框屬性,使其包含塊元素的高度塌陷,使浮動框旁邊的行框被縮短,從而給浮動框留出空間,行框圍繞浮動框重新排列

【爲什麼需要清除浮動】

[清浮動],其實就是解決浮動元素的包含塊高度塌陷的問題

對於標準瀏覽器來說,清浮動其實就兩種方法,一種是在浮動元素下面添加新元素設置clear屬性;另一種是觸發包含塊的BFC,使其包含浮動元素

Why BFC

經常地,我們使用[BFC]來清除浮動,但實際上BFC還有很多其他的用途

在解釋BFC之前,先說一下文檔流。我們常說的文檔流其實分爲定位流、浮動流和普通流三種。而普通流其實就是指BFC中的FC。FC是formatting context的首字母縮寫,直譯過來是格式化上下文,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其他元素之間的關係和作用。常見的FC有BFC、IFC,還有GFC和FFC。BFC是block formatting context,也就是塊級格式化上下文,是用於佈局塊級盒子的一塊渲染區域

滿足下列條件之一就可觸發BFC

1、根元素,即HTML元素

2、float的值不爲none

3、overflow的值不爲visible

4、display的值爲inline-block、table-cell、table-caption

5、position的值爲absolute或fixed

BFC是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素,反之亦然。經常使用BFC實現以下3個用途

1、阻止元素被浮動元素覆蓋

<說明>通過改變內容爲BFC背景爲紅色的盒子的屬性值,使其成爲BFC,以此阻止被綠色的浮動盒子覆蓋

2、包含浮動元素

<說明>通過改變高度塌陷的黑色邊框的盒子的屬性值,使其成爲BFC,以此來包含綠色的浮動盒子

3、屬於同一個BFC的兩個相鄰塊級子元素的上下margin會發生重疊,(設置writing-mode:tb-rl時,水平margin會發生重疊)。所以當兩個相鄰塊級子元素分屬於不同的BFC時可以阻止margin重疊

<說明>淡紅色背景的塊級盒子二的外面包一個div,通過改變此div的屬性使紅色盒子與綠色盒子分屬於兩個不同的BFC,以此來阻止margin重疊

Why 定位

CSS有三種基本的佈局機制:普通流、浮動流和定位流。利用定位,可以準確地定義元素框相對於其正常位置應該出現的位置,或者相對於父元素、另一個元素甚至瀏覽器窗口本身的位置

當元素絕對定位時,會從文檔流中完全刪除。元素位置相對於最近的已定位祖先元素,如果元素沒有已定位的祖先元素,那麼它的位置相對於初始包含塊document,其邊界根據偏移屬性放置。元素定位後生成一個塊級框,而不論原來它在正常流中生成何種類型的框。定位元素不會流入其他元素的內容,反之亦然

當元素相對定位時,它會從其正常位置移走,不過,原來所佔的空間並不會因此消失。相對定位元素,會爲其所有子元素建立一個新的包含塊。這個包含塊對應於該元素原本所在的位置

固定定位與絕對定位很類似,元素會完全從文檔流中去除,但固定元素的偏移是相對於視窗

【爲什麼clip屬性無效】

[絕對定位]或固定定位元素纔可以使用[clip]屬性。絕對定位元素常配合clip屬性達到元素隱藏的效果

.hide{
    position:absolute;
    clip: rect(0,0,0,0);
}
專門建立的學習Q-q-u-n: 731771211,分享學習方法和需要注意的小細節,不停更新最新的教程和學習技巧
(從零基礎開始到前端項目實戰教程,學習工具,全棧開發學習路線以及規劃)

【爲什麼靜態位置的元素會發生跳動】

對於居中對齊的行內元素來說,將元素設置爲absolute或fixed會發生[靜態位置]跳動問題。而relative或static則不會有此問題。這是因爲元素默認的居中對齊是元素的內容中線對應父級塊級元素中線,而當元素絕對定位或固定定位之後,定位元素左邊界將與其父級塊級元素的中線對齊

【爲什麼overflow屬性會失效】

當overflow在絕對定位元素和其包含塊之間時,絕對定位元素不會被父級overflow屬性剪裁

解決辦法就是有兩種, 一種是讓overflow元素自身成爲包含塊,給父級設置position:absolute或fixed或relative;另一種是設置overflow元素的子元素爲包含塊,在絕對定位元素和overflow元素之間增加一個元素並設置position:absolute或fixed或relative

Why z-index

對於所有定位,最後都不免遇到兩個元素試圖放在同一位置上的情況。顯然,其中一個必須蓋住另一個。但,如何控制哪個元素放在上層,這就引入了屬性[z-index]

利用z-index,可以改變元素相互覆蓋的順序。這個屬性的名字由座標系統得來,其中從左向右是x軸,從上到下是y軸。從屏幕到用戶是z軸。在這個座標系中,較高z-index值的元素比較低z-index值的元素離用戶更近,這會導致較高z-index值的元素覆蓋其他元素,這也稱爲堆疊或疊放

對於CSS2.1來說,頁面元素的堆疊規則如下圖所示

對於定位元素(position不是static的元素)來說,不設置z-index或z-index相同時,後面元素覆蓋前面元素;對於處於同一堆疊上下文中的同一層次的元素來說,默認z-index較大值覆蓋z-index較小值

一旦爲一個元素指定了z-index值(不是auto),該元素會建立自己的局部堆疊上下文。這意味着,元素的所有後代相對於該祖先元素都有其自己的疊放順序

注意:auto值指當前堆疊上下文中生成的棧層次與其父框的層次相同,這個框不會建立新的局部疊放上下文。z-index:auto與z-index:0的值相等,但z-index:0會建立新的局部堆疊上下文

CSS3的出現對過去的很多規則發出了挑戰。對層疊上下文z-index的影響更加顯著,主要包括以下8個屬性

1、z-index值不爲auto的flex項(父元素display:flex | inline-flex)

2、元素的透明度opacity值不等於1

3、元素的變形transform不是none

4、元素的mix-blend-mode值不是normal

5、元素的filter值不是none

6、元素的isolation值是isolate

7、will-change指定的屬性值爲上面的任意一個

8、元素的-webkit-overflow-scrolling設置爲touch

9、元素的mask屬性不是none

設置以上9個屬性的任意一個,都和設置absolute類似,層疊上下文z-index會生效

Why 溢出

當一個元素固定爲某個特定大小,但內容在元素中放不下。此時可以利用[溢出(overflow)]來控制這種情況

overflow-x和overflow-y的屬性原本是IE瀏覽器獨自拓展的屬性,後來被CSS3採用,並標準化。overflow-x主要用來定義對水平方向內容溢出的剪切,而overflow-y主要用來定義對垂直方向內容溢出的剪切

當overflow設置爲auto或scroll或hidden時可以觸發BFC,使得overflow可以實現一些相關應用

【爲什麼會出現滾動條】

滾動條和overflow是緊密相關的。只有當父級的overflow的值是auto或scroll,並且元素的內容超出元素區域時,纔有可能出現滾動條

無論什麼瀏覽器,默認滾動條均來自<html>,而不是<body>。因爲<body>元素默認有8px的margin。若滾動條來自元素,則滾動條與頁面則應該有8px的間距,實際上並沒有間距,所以滾動條來自<html>元素

chrome/firefox/IE瀏覽器的默認滾動條寬度是17px,safari瀏覽器則是21px

Why flex

CSS3引入了一種新的佈局模型——[flex佈局]。flex是flexible box的縮寫,一般稱之爲彈性盒模型。flex佈局提供一種更加有效的方式來進行容器內的項目佈局,以適應各種類型的顯示設備和各種尺寸的屏幕

伸縮容器默認存在兩條軸: 水平的主軸(main axis) 和垂直的側軸(cross axis)

注意:主軸方向不一定是水平的,它主要取決於justify-content屬性

主軸起點叫main start,主軸終點叫main end;側軸起點叫cross start,側軸終點叫cross end

伸縮項目默認沿主軸排列。單個伸縮項目佔據的主軸空間叫main size ,佔據的側軸空間叫cross size

注意:伸縮項目的main size和cross size主要由寬度或高度決定

利用flex可以簡單的實現各種佈局形式,詳細情況[移步至此]

Why 多列布局

浮動作爲常見排版方式只是不得已爲之的行爲,最初只是用來實現圖文混排,也最好只用於圖文混排,而不是更復雜的佈局結構

定位用於對元素的精準定位佈局

個人認爲,flex佈局提供的靈活佈局方式可以用來替代被氾濫使用的浮動佈局

而多列布局則提供了類似於報紙、雜誌類的排版方式

CSS新增了多列布局特性,可以讓瀏覽器確定何時結束一列和開始下一列,無需任何額外的標記。簡單來說,就是CSS3多列布局可以自動將內容按指定的列數排列,這種特性實現的佈局效果和報紙、雜誌類排版非常相似

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章