「建议观看」史上超长,前端css晦涩难懂的点都在这啦
前言
CSS大家肯定都是會的但是每個人所撐握的情況都不一樣,特別是已經工作幾年的前輩很多CSS玩法都不知道,可能他們已經習慣了用組件, 但是面試的時候又不可避免問,所以我整理了下CSS比較晦澀難懂的點總結寫了這篇文章,在最后也會有些面試中常問的CSS相關面試題,看完全文面試就不用慌了。
本文篇幅超長,建議轉發收藏后觀看,我這里有前端進階架構vip學習資料,包含內容有:HTML、css3、JavaScript、Vue,移動端web開發,Ajax、jQuery、canvas、等多個知識點。需要獲取這些內容的朋友可以私信回復我“前端”兩個字領取
目錄
三大特性
: css大三特性是css最重要的部分,可以說如果了解了這三大特性就對css撐握了一半,對于屬性只不過是記不記得住的事,而這個是重在理解。
- 層疊性:css樣式沖突采取的原則(后者覆蓋前者)
- 繼承性:對于部分屬性樣式會有天生的繼承
- 優先級:選擇器優先級算法
選擇器
在講這三個特性之前我們需要來全面了解下選擇器。
種類
下面我將選擇進行劃分為三大部分,對于基本選擇器我就不說了,主要講下偽類選擇器,組合選擇器及它們各自的使用場景。
- 基本選擇器 類名:.box 標簽: div 屬性: input[type="eamil"] | a[href*="http://www.beige.world"] ID: #box
- 偽類選擇器 結構偽類: :nth-child(n) | :nth-of-type(n) | :hover 偽元素: ::before | ::after
- 組合選擇器 相鄰兄弟 A + B 普通兄弟 A ~ B 子選擇器 A > B 后代選擇器 A B
基本選擇器
算了還是講下屬性選擇器吧,這個選擇器我在項目開發中還是用到過的
直接看例子:
/* 匹配包含title屬性的a標簽 => <a title> */ a[title] {color: purple;} /* 存在href屬性并且屬性值為"http://beige.world"的<a>標簽*/ /* <a href="http://beige.world"> */ a[href="http://beige.world"] {color: green;}/* 存在href屬性并且屬性值包含"baidu"的<a>標簽*//* <a href="https://baidu.com/we"> <a href="https://fanyi.baidu.com/we"> <a href="https://pan.baidu.com/we"> */ a[href*="baidu"] {font-size: 20px;}/* 存在id屬性并且屬性值結尾是"-wrapper"的<div>標簽 *//* <div id="btn-wrapper"><div id="menu-wrapper"><div id="pic-wrapper">*/ div[id$="-wrapper"] {display: flex;}/* 存在class屬性并且屬性值包含以空格分隔的"logo"的<div>元素 *//* <div id="aaa logo"><div id="bbb logo">*/ div[class~="logo"] { padding: 2px; } 復制代碼偽類選擇器
結構偽類
先講這兩比較作用類似的:nth-child(n) | nth-of-type(n)
結構
<ul><li>1</li><li><p>a1</p><div>b1</div><p>a2</p><div>b2</div></li><li>3</li><li>4</li><li>5</li> </ul> 復制代碼CSS
// 第一個li => <li>1</li> ul li:first-child { background-color: lightseagreen;} // 最后一個li => <li>5</li> ul li:last-child { background-color: lightcoral;} // 第三個li => <li>3</li> ul li:nth-child(3) { background-color: aqua; } // 第二個li下的第一個div(不是div標簽的都不算) => <div>b1</div> ul li:nth-child(2) > div:nth-of-type(1) {background-color: red}它倆的區別
- nth-child 選擇父元素里面的第幾個子元素,不管是第幾個類型
- nth-of-type 選擇指定類型的元素
下面講講nth-child()括號中的公式,這個算是這個選擇器的亮點了。
注意?:本質上就是選中第幾個子元素
- n 可以是數字、關鍵字、公式
- n 如果是數字,就是選中第幾個
- 常見的關鍵字有 even 偶數、odd 奇數
- 常見的公式如下(如果 n 是公式,則從 0 開始計算)
- 但是第 0 個元素或者超出了元素的個數會被忽略
對于這里面的公式平常也用不到太復雜的,我說下我的技巧:nth-child(3n + 3); 這里的n可以看做幾個為一組,3可以看做選這組的第幾個。
例: nth-child(5n + 3) :5個為一組,選一組中的第三個。 對于"-"號就表示選擇的是前面的。
組合選擇器
組合選擇器本質上就是通過連接符來對兩個選擇器進行組合
- 子選擇器 A > B
- 后代選擇器 A B
上面這兩我就不說了,相信大家都用爛了。主要說說下面這兩個。
- 相鄰兄弟 A + B
- 普通兄弟 A ~ B
結構
<div class="box1"><div>One</div><div>Two!</div><div>Three</div><p>pppp</p></div><div class="box2"><div>One2</div><p>pppp1</p><div>Two2!</div><p>pppp2</p></div> 復制代碼選擇器解析
<style>/*(+標識)符介于兩個選擇器之間,當第二個選擇器匹配的元素緊跟著第一個元素后面并且它們都是同一個父親.box1 div:first-of-type(A元素)div(B元素) 匹配緊跟著A的B*/.box1 div:first-of-type+div { color: red; }.box1 div:first-of-type+p { color: red;} 篩選不到的/*(~標識)符介于兩個選擇器之間,匹配第一個選擇器元素后面所有匹配第二個選擇器的同層級元素.box2 div(A元素)p(B元素)匹配所有A后面的B*/.box2 div~p { color: seagreen; }</style> 復制代碼好了,在講完這些選擇器之后我們來看看它們的使用場景。
組合選擇器可以用于:hover偽類操縱自己包含的子元素及以外的元素。舉個例子
<div?id='a'>元素1<div?id='b'>元素2</div> </div> <div?id='c'>元素3<div?id='b'>元素2</div> </div> <div>同級元素1</div> <div>同級元素2</div> <div>同級元素3</div> </body> 復制代碼 #a:hover?>?#b{....}???? #a:hover?~?div{....} // 鼠標停留在a元素的時候讓所有同層級元素有某某樣式 // 防止選擇器層級替換了下面的樣式 #a:hover?+?#c{....} // 鼠標停留在a元素的時候讓同層級中的c元素有某某樣式 #a:hover?+?#c?>?#b{....} // 鼠標停留在a元素的時候讓同層級中的c元素下的b元素有某某樣式 復制代碼上面這兩選擇器在做一些特效頁的時候應該是會用到的。
綜合例子
效果
結構
<body><div class="img-box enter-box"> <!-- 懸浮在這個盒子的時候動態添加enter-box類名 --><img src="http://resource.beige.world/imgs/beige.jpg" alt=""><div class="cover"><h3>標題名稱</h3><p class="con">Bei Ge</p><p class="brier">這里放內容簡介,內容簡介,這里放內容簡介,內容簡介,這里放內容簡介,內容簡介</p><div class="handle"><span>.</span><span>.</span><span>.</span></div></div></div><!-- 其他盒子 --><div class="img-box">2</div> <div class="img-box">3</div><div class="img-box">4</div><div class="img-box">5</div> </body> 復制代碼樣式
布局樣式
<style>.img-box {position: relative;top: 100px;left: 200px;z-index: 1;display: inline-block;overflow: hidden;background: #70adc4;cursor: pointer;transition: transform .5s, box-shadow .3s;}.img-box img {width: 200px;height: 200px;opacity: 1;float: left;}.img-box .cover {width: 200px;height: 200px;padding: 15px;position: absolute;box-sizing: border-box;color: hotpink;}.img-box .cover h3 {margin-top: 10%;font-size: 24px;font-weight: bold;text-shadow: 0 0 2px #ccc;opacity: 0;transition: opacity .5s;}.img-box .cover .con {margin: 20px 0;font-style: italic;font-weight: bold;transform: translateX(-150%);}.img-box .cover .brier {font-size: 12px;transform: translateX(150%);}.img-box .cover .handle {position: absolute;right: 10px;bottom: -50px;font-size: 25px;transition: bottom 1s;/* 對于position的過渡動畫, 不能用position, 直接用位置屬性: left right top bottom */}</style> 復制代碼定義了一個animation動畫
@keyframes textAnimation {/* 0% {transform: translateX(150%);} */100% {transform: translateX(0);} } 復制代碼懸浮在盒子設置樣式
.img-box:hover {transform: scale(1.1);box-shadow: 2px 2px 13px 3px #ccc; }.img-box:hover img {opacity: .5; }.img-box:hover .cover h3 {opacity: 1; }.img-box:hover p {animation: textAnimation .6s ease-out forwards;/* forwards讓動畫停留在最后一幀 */ }.img-box:hover .cover .handle {bottom: 5px; }.enter-box:hover ~ .img-box {background-color: transparent;color: wheat; } .enter-box:hover + .img-box {color: red; } 復制代碼上面這個例子有些還沒有講,但是相信大家之前也都學過,后文中也會說。主要會說些細節方面的東西。
- flex(彈性布局)
- transform: translate3D rodate3D
- animation(設定動畫)
- 3D or 透視(perspective)
這里需要注意在使用偽類Hover的注意點,在使用他影響子級元素的時候盡量將選擇器寫全。例:
先看下效果
上面的效果相信大家都能寫出來,所以我要講的肯定不是怎么去實現這個效果,我要說下使用Hover時的一些細節。
結構比較簡單
flex類名用于布局實現重置和水平居中,box: 綠色盒子;center: 紫色盒子 inner: 橙黃色盒子
<div class="box flex"><div class="center flex"><div class="inner"></div></div> </div> 復制代碼我們用了一個:hover讓鼠標虛浮的時候讓盒子變紅
.box:hover div {background-color: red; } 復制代碼這里有一個問題不知道大家想過沒有,為什么我這段代碼只讓center盒子變紅了,inner為什么沒有變紅呢???
展開查看
因為CSS選擇器的優先級!復制代碼我們在實現的時候一般都會像下面這樣寫吧,這個時候使用偽類選擇器改變元素樣式的時候就要注意選擇器優先級的問題了。
.box .center {width: 150px;height: 150px;background-color: blueviolet; } .box .center .inner {width: 100px;height: 100px;background-color: coral; } 復制代碼這段代碼的優先級比 .box .center高,所以他也就只能覆蓋它了。
.box:hover div { background-color: red; } 復制代碼相信我們很多人如果在寫鼠標懸浮大盒子讓最里面的inner盒子變色的時候,都會這么寫吧:
.box:hover .inner { background-color: red; } 復制代碼有用嗎?沒用!
注意?: 優先級還是沒有.box .center .inner高。
層疊性
所謂層疊性是指多種CSS樣式的疊加。是瀏覽器處理沖突的一個能力,如果一個屬性通過兩個相同選擇器設置到同一個元素上,那么這個時候一個屬性就會將另一個屬性層疊掉
- 原則: 樣式沖突,遵循的原則是就近原則。?那個樣式離著結構近,就執行那個樣式。 樣式不沖突,不會層疊
繼承性
:子標簽會繼承父標簽的某些樣式,如文本顏色和字號。 想要設置一個可繼承的屬性,只需將它應用于父元素即可。簡單的理解就是: 子承父業
CSS繼承性口訣: 龍生龍,鳳生鳳,老鼠生的孩子會打洞我們恰當地使用繼承可以簡化代碼,降低CSS樣式的復雜性。比如有很多后代元素都需要某個樣式,可以給父級指定一個,這些孩子繼承過來就好了。
注意點:在CSS的繼承中不僅僅是兒子可以繼承, 只要是后代都可以繼承
可繼承的屬性
控制繼承
注意點: 對于天生自帶的繼承屬性我們可以控制它是否需要繼承
四個屬性
- inherit: 被應用屬性繼承父級的該屬性(默認就是該值)
- initial初始化,把應用屬性初始為它默認的樣式,并且排除繼承的干擾(默認會繼承的屬性也不在默認繼承,而是表現出沒有任何設置時候的默認樣式)
- unset:意思是恢復其原本的繼承方式。對color屬性而言,就相當于inherit;而對于諸如border這樣默認不繼承的屬性,就相當于initial。
- revert: 效果等同于unset且瀏覽器支持有限,這里不做演示
效果圖
演示
<ul style="color: green;"><li class="default">Default <a href="#">link</a> color</li><li class="inherit">Inherit the <a style="color: inherit;" href="#">link</a> color</li><li class="initial">Reset the <a style="color: initial;" href="#">link</a> color</li><li class="unset">Unset the <a style="color: unset;" href="#">link</a> color</li> </ul> 復制代碼- default中的a標簽沒有寫默認為inherit屬性,但是使用了瀏覽器預設樣式表:可以理解為瀏覽器幫我們為<a>寫了個style,其優先級自然就高于其父元素了。
- inherit中的a標簽在行內寫了inherit,于是使用其父(或祖父,etc)元素的顏色值,在這里是綠色;
- initial中的a標簽使用color屬性初始值(黑色), 注意不要混淆屬性初始值和瀏覽器樣式表指定值,樣式預設表是瀏覽器事先寫好的樣式,但是我color默認值就是黑色啊。
- unset,意思是恢復其原本的繼承方式。對color屬性而言,就相當于inherit;而對于諸如border這樣默認不繼承的屬性,就相當于initial。
如果我們需要控制元素所有屬性的繼承使用all屬性
.inherit a {all: initial; /* 將所有的屬性都恢復成默認值(天生繼承也不再繼承) *//* 行內設置過的除外:你的層級干不過人家 */ } 復制代碼繼承的權重是0
這個不難,但是忽略很容易繞暈。其實,我們修改樣式,一定要看該標簽有沒有被選中。
(1) 如果選中了,那么以上面的公式來計權重。誰大聽誰的。 (2) 如果沒有選中,那么權重是0,因為繼承的權重為0.
控制繼承在我們封裝自己的組件的時候是會用到的,我們在封裝組件需要沿用樣式,有些默認情況下不可繼承父元素的屬性:box-sizing,這個其實用的就很多。
優先級
要想了解優先級,肯定得了解選擇器;但是選擇器非常多的,前面列舉的是日常開發用的比較多,其他的你可能一輩子都用不到,這里貼出C1~C4的選擇器,感興趣的同學可以看看。
定義CSS樣式時,經常出現兩個或更多選擇器應用在同一元素上,此時,
- 選擇器相同,則執行層疊性(后者覆蓋前者)
- 選擇器不同,就會出現優先級的問題。
權重計算公式
關于CSS權重,我們需要一套計算公式來去計算,這個就是 CSS Specificity(特殊性)
標簽選擇器計算權重公式繼承或者 *0,0,0,0每個元素(標簽選擇器)0,0,0,1每個類,結構偽類(如:hover),屬性選擇器[type="number"]0,0,1,0每個ID0,1,0,0每個行內樣式 style=""1,0,0,0h1 + p::first-line0,0,0,3li > a[href*="beige.world"] > .inline-warning0,0,2,2每個!important 重要的∞ 無窮大
值從左到右,左面的最大,一級大于一級,數位之間沒有進制,級別之間不可超越。
常用的選擇器記法:
- 行內: 1,0,0,0
- #id: 0,1,0,0
- .class | :hover | :nth-child(): 0,0,1,0 (:hover這種一個冒號叫結構偽類)
- ::after | ::before | ::first-line: 0,0,0,1 (這種兩冒號的叫偽元素,在書寫的時候雖然你可以寫一個冒號但是瀏覽器還是給你補上去了,本質上就是兩冒號)
權重疊加
我們經常用組合選擇器,是有多個基礎選擇器組合而成,那么此時,就會出現權重疊加。
就是一個簡單的加法計算
- div ul li ------> 0,0,0,3
- .nav ul li ------> 0,0,1,2
- a:hover -----—> 0,0,1,1
- .nav a ------> 0,0,1,1
注意?: 數位之間沒有進制 比如說: 0,0,0,5 + 0,0,0,5 = 0,0,0,10 而不是 0,0, 1, 0, 所以不會存在10個div能趕上一個類選擇器的情況。
important適用優先級
#id .box div {color: red !important; }#id div.box div {color: green !important; // 使用這個選擇器中的顏色 } 復制代碼通關答題
下面來幾道題,全對才算通過了噢
<style type="text/css">.c1 .c2 div{ color: blue;}div #box3 { color:green;}#box1 div { color:yellow;} </style> </head> <body> <div id="box1" class="c1"><div id="box2" class="c2"><div id="box3" class="c3">文字</div></div> </div> </body> 復制代碼什么顏色??
展開查看答案
yellow 上面兩選擇器的層級都是一樣的, 后者覆蓋前者 復制代碼 <style type="text/css">#father #son{ color:blue;}#father p.c2{ color:black;}div.c1 p.c2{ color:red;}#father{color:green !important;} </style> </head> <body> <div id="father" class="c1"><p id="son" class="c2">試問這行字體是什么顏色的?</p> </div> </body> 復制代碼展開查看答案
blue 復制代碼 <body><style>div.parent {width: 300px;height: 300px;border: 10px solid #000;font-size: 46px;text-shadow: 3px 13px 4px green;box-sizing: border-box}div.child {width: 200px;height: 200px;background-color: brown;border: 5px solid #000;width: inherit;box-sizing: inherit;font-size: 80px;}</style> </head><div class="parent"><div id="child" class="child">123</div></div><!-- child: 字體多大? 有沒有文字陰影? 真實內容的寬高是多少?--> </body> 復制代碼展開查看答案
字體:80,有文字陰影,真實內容的寬:290px 高190px復制代碼講下這最后一題
文字陰影有:因為從父元素中繼承到了,字體: 80px;
真實內容寬290px, 高190px
常問的屬性
- flex(彈性布局)
- transform: translate3D rodate3D
- animation(設定動畫)
- 3D or 透視(perspective)
flex
flex布局相信大家也都用爛了,用來讓盒子垂直和水平居中好用的一批
父項常用屬性
- flex-direction:設置主軸的方向
- justify-content:設置主軸上的子元素排列方式
- flex-wrap:設置子元素是否換行
- align-content:設置側軸上的子元素的排列方式(多行)
- align-items:設置側軸上的子元素排列方式(單行)
- flex-flow:復合屬性,相當于同時設置了 flex-direction 和 flex-wrap
flex-direction
在 flex 布局中,是分為主軸和側軸兩個方向,同樣的叫法有 : 行和列、x 軸和y 軸
- 默認主軸方向就是 x 軸方向,水平向右
- 默認側軸方向就是 y 軸方向,水平向下
: 主軸和側軸是會變化的,就看 flex-direction 設置誰為主軸,剩下的就是側軸。而我們的子元素是跟著主軸來排列的
flex-wrap設置是否換行
- 默認情況下,項目都排在一條線(又稱”軸線”)上。flex-wrap屬性定義,flex布局中默認是不換行的。
- nowrap 不換行
- wrap 換行
justify-content 設置主軸上的子元素排列方式
效果圖
: 這里講下space-around和space-evenly
- space-around:項目之間的間距為左右兩側項目到容器間距的2倍。
- space-evenly:項目兩側之間的間距與項目與容器兩側的間距相等,相當于除去項目寬度和容器和項目的兩側間距,剩下的平均分配了剩余寬度作為項目左右margin。
**設置側軸上的子元素排列方式:align-items(單行)/align-content(多行) **
上圖寫能設置多行只能用于子項出現 換行 的情況(多行),在單行下是沒有效果的。
效果跟上面是一樣的只不過是方向換了,上面是元素在主軸上排列,這個是在側抽上,至于側軸是不是Y軸就看你的flex-direciton怎么設置的了
子項常見屬性
- flex(復合屬性): 默認: flex: 0 1 auto; flex-grow flex-shrink flex-basis
- align-self:控制子項自己在側軸的排列方式
- order:定義子項的排列順序(前后順序), 0是第一個
flex-grow
默認0,用于決定項目在有剩余空間的情況下是否放大,默認不放大;注意,即便設置了固定寬度,也會放大。
假設第一個項目默認為0,第二個項目為flex-grow:2,最后一個項目為1,則第二個項目在放大時所占空間是最后項目的兩倍。
可以這么理解:
- flex: 1 => 在剩余的空間里我就占一份
- flex: 2 => 在剩余的空間里我就占兩份
- flex: 3 => 在剩余的空間里我就占三份
flex-shrink
默認1,用于決定項目在空間不足時是否縮小,默認項目都是1,即空間不足時大家一起等比縮小;注意,即便設置了固定寬度,也會縮小。但如果某個項目flex-shrink設置為0,則即便空間不夠,自身也不縮小。
上圖中第二個項目flex-shrink為0,所以自身不會縮小。
flex-basis
默認auto,用于設置項目寬度,默認auto時,項目會保持默認寬度,或者以width為自身的寬度,但如果設置了flex-basis,權重會width屬性高,因此會覆蓋widtn屬性。
上圖中先設置了flex-basis屬性,后設置了width屬性,但寬度依舊以flex-basis屬性為準。
注意?: 如果當容器中有多個盒子并且還寬度100%, flex-basis會被影響, 如下圖
解決辦法就是在我們設置flex-basis寬度時, 最好給他設置flex-shrink為0不縮放
transform
2D的屬性相信大家都會用了, 本文主要深究transform的3D屬性
- 透視:perspctive
- 3D呈現:transfrom-style
- 3D 位移:translate3d(x, y, z)
- 3D旋轉:rotate3d(x, y, z)
透視(perspective)
在講3D之間先來了解一下透視(視距),只有了解了透視我們才能理解3D的物體投影在2D平面上
- 透視也稱為視距,所謂的視距就是人的眼睛到屏幕的距離
- 實際上模仿人類的視覺位置,可視為安排一直眼睛去看
- 距離透視點越近的在電腦平面成像越大,越遠成像越小
- 透視的單位是像素
注意: 透視需要寫在被視察元素的父盒子上面
拿圖說話
- d:就是視距,視距就是指人的眼睛到屏幕的距離
- z:就是 z 軸,z 軸越大(正值),我們看到的物體就越大
來個栗子
給實例的父元素設置: perspective: 200px;上面我們在div的父盒子上設置了perspective,也就是說從3D成像的角度來講我們人眼距離屏幕div是200的視距,translate3D設置Z軸讓div往前挪了100,視距變小距離我們人眼距離也就越小,所以看到的div也就變大了。 (可以想像成在500米遠看見的人, 和5米看見的人。)
translate3d(x, y, z)
3D的特點
- 近大遠小
- 物體和面遮擋不可見
三維坐標系
- x 軸:水平向右 --?注意:x 軸右邊是正值,左邊是負值
- y 軸:垂直向下 --?注意:y 軸下面是正值,上面是負值
- z 軸:垂直屏幕 --?注意:往外邊的是正值,往里面的是負值
3D 呈現 transform-style
transform-style:控制子元素是否開啟三維立體環境,代碼寫給父級,但是影響的是子盒子
- transform-style: flat 代表子元素不開啟 3D 立體空間,默認的
- transform-style: preserve-3d 子元素開啟立體空間
效果圖
body {perspective: 500px; }.box {position: relative;width: 200px;height: 200px;margin: 100px auto;transition: all 2s;/* 讓子元素保持3d立體空間環境 */transform-style: preserve-3d; }.box:hover {transform: rotateY(60deg); }.box div {position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: pink; }.box div:last-child {background-color: purple;transform: rotateX(60deg); } 復制代碼rotate3d(x, y, z)
3D 旋轉指可以讓元素在三維平面內沿著 x 軸、y 軸、z 軸 或者自定義軸進行旋轉
- transform: rotate3d(x, y, z, 45deg)` -- 沿著自定義軸旋轉 45 deg 為角度
animation
動畫(animation)是 CSS3 中最具顛覆性的特征之一,可通過設置多個節點來精確的控制一個或者一組動畫,從而實現復雜的動畫效果, 先定義動畫在調用定義好的動畫
動畫序列
0% 是動畫的開始,100 % 是動畫的完成,這樣的規則就是動畫序列
- 在 @keyframs 中規定某項 CSS 樣式,就由創建當前樣式逐漸改為新樣式的動畫效果
- 動畫是使元素從一個樣式逐漸變化為另一個樣式的效果,可以改變任意多的樣式任意多的次數
- 用百分比來規定變化發生的時間,或用 from 和 to,等同于 0% 和 100%
動畫常見屬性
動畫簡寫方式
/* animation: 動畫名稱 持續時間 運動曲線 何時開始 播放次數 是否反方向 起始與結束狀態 */ animation: name duration timing-function delay iteration-count direction fill-mode 復制代碼除了名字,持續時間,何時開始有嚴格順序要求其它隨意
CSS實現掃描二維碼
代碼篇幅過長放到gitHub倉庫了,大家可以pull下來自行研究。
地址:https://github.com/it-beige/blog
面試常問題
BFC相關
BFC(Block formatting context)直譯為"塊級格式化上下文"。
在講BFC之前得先說下display的屬性值,只有它符合成為條件才資格觸發BFC機制
那些屬性值會具有BFC的條件
不是所有的元素模式都能產生BFC,w3c 規范: display 屬性為 block, list-item, table 的元素,會產生BFC.
大家有沒有發現這個三個都是用來布局最為合理的元素,因為他們就是用來可視化布局。注意其他的,display屬性,比如 line 等等,他們創建的是 IFC ,我們下面研究。
這個BFC 有著具體的布局特性:
有寬度和高度,有 外邊距margin 有內邊距padding 有邊框 border。就好比,你有了練習武術的體格了。 有潛力,有資質。
什么情況下可以讓元素產生BFC
以上盒子具有BFC條件了,就是說有資質了,但是怎樣觸發才會產生BFC,從而創造這個封閉的環境呢?
就好比,你光有資質還不行,你需要一定額外效果才能出發的武學潛力,要么你掉到懸崖下面,撿到了一本九陰真經,要么你學習葵花寶典,欲練此功必先....
同樣,要給這些元素添加如下屬性就可以觸發BFC。
- float屬性不為none
- position為absolute或fixed
- display為inline-block, table-cell, table-caption, flex, inline-flex
- overflow不為visible。
BFC元素所具有的特性
BFC布局規則特性:
- 在BFC中,盒子從頂端開始垂直地一個接一個地排列
- 盒子垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰盒子的margin會發生重疊
- 在BFC中,每一個盒子的左外邊緣(margin-left)會觸碰到容器的左邊緣(border-left)(對于從右到左的格式來說,則觸碰到右邊緣)。 BFC的區域不會與浮動盒子產生交集,而是緊貼浮動邊緣。 計算BFC的高度時,自然也會檢測浮動或者定位的盒子高度
它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何布局,并且與這個區域外部毫不相干。
白話文: 孩子在家里愿意怎么折騰都行,但是出了家門口,你就的乖乖的,不能影響外面的任何人。BFC的主要用途
(1) 清除元素內部浮動
只要把父元素設為BFC就可以清理子元素的浮動了,最常見的用法就是在父元素上設置overflow: hidden樣式
主要用到
計算BFC的高度時,自然也會檢測浮動或者定位的盒子高度。 復制代碼(2) 解決外邊距合并(塌陷)問題
主要用到
盒子垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰盒子的margin會發生重疊 復制代碼屬于同一個sBFC的兩個相鄰盒子的margin會發生重疊,那么我們創建不屬于同一個BFC,就不會發生margin重疊了。
(3) 制作右側自適應的盒子問題
主要用到
普通流體元素BFC后,為了和浮動元素不產生任何交集,順著浮動邊緣形成自己的封閉上下文 復制代碼BFC 總結
BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。包括浮動,和外邊距合并等等,因此,有了這個特性,我們布局的時候就不會出現意外情況了。
IFC相關
IFC(inline Formatting Context)叫做“行級格式化上下”相對BFC比較簡單且問的也不是很多,這里大該做個了解
布局規則如下:
- 內部的盒子會在水平方向,一個個地放置(默認就是IFC);
- IFC的高度,由里面最高盒子的高度決定(里面的內容會撐開父盒子);
- 當一行不夠放置的時候會自動切換到下一行;
哪些屬性開啟了性能加速
何為硬件加速:就是將瀏覽器的渲染過程交給GPU(Graphics Processing Unit)處理,而不是使用自帶的比較慢的渲染器。這樣就可以使得animation與transition更加順暢
我們可以在瀏覽器中用CSS開啟硬件加速,使GPU發揮功能,從而提升性能
所謂GPU,就是圖形處理器的縮寫,相當于PC中的顯卡。手機中的GPU也是為了對圖形、圖像處理而存在的,所謂強制渲染,就是hwa(hardware acceleration硬件加載)的一種,其存在的意義就是為了分擔cpu的負擔,其原理是通過GPU對軟件圖形的處理來減輕CPU的負擔。從而使應用軟件能夠以更快的速度被處理,以達到提速的目的。
硬件加速的原理
瀏覽器接收到頁面文檔后,會將文檔中的標記語言解析為DOM樹。DOM樹和CSS結合后形成瀏覽器構建頁面的渲染樹。渲染樹中包含大量的渲染元素,每個渲染元素會被分到一個圖層中,每個圖層又會被加載到GPU形成渲染紋理,而圖層在GPU中transform是不會觸發repaint的,最終這些使用transform的圖層都會由獨立的合成器進程進行處理, CSS transform會創建了一個新的復合圖層,可以被GPU直接用來執行transform操作。
瀏覽器什么時候會創建一個獨立的復合圖層呢?事實上一般是在以下幾種情況下:
- 3D或者CSS transform
- <video>和<canvas>標簽
- css filters(濾鏡效果)
- 元素覆蓋時,比如使用了z-index屬性
為什么硬件加速會使頁面流暢
因為transform屬性不會觸發瀏覽器的repaint(重繪),而絕對定位absolute中的left和top則會一直觸發repaint(重繪)。
為什么transform沒有觸發repaint呢?
簡而言之,transform動畫由GPU控制,支持硬件加載,并不需要軟件方面的渲染。并不是所有的CSS屬性都能觸發GPU的硬件加載,事實上只有少數的屬性可以,比如transform、opacity、filter
如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
我這里有前端進階架構vip學習資料,包含內容有:HTML、css3、JavaScript、Vue,移動端web開發,Ajax、jQuery、canvas、等多個知識點。需要獲取這些內容的朋友可以私信回復我“前端”兩個字領取
總結
以上是生活随笔為你收集整理的「建议观看」史上超长,前端css晦涩难懂的点都在这啦的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1214线段覆盖问题——贪心法
- 下一篇: 史上最烂 spring aop 原理分析