目錄
- 僞類和僞元素
- 實作固定寬高比(
)的div,怎麼設定width: height = 4: 3
- CSS選擇器
- CSS解析規則
-
完整寫法flex: 1
-
和display: none
的差別visibility:hidden
-
em
rem
vh
vw
calc()
百分比line-height
-
實作原理及相應的計算方案rem
- 清除浮動方法及原理
-
是什麼postcss
-
css modules
-
預處理器CSS
- CSS 中的
有哪些值?它在什麼情況下才能生效?vertical-align
- BFC(塊格式化上下文)
- 常見布局的實作
1. 僞類和僞元素
為什麼引入?
css
引入僞類和僞元素概念是為了格式化文檔樹以外的資訊。僞類和僞元素是用來修飾不在文檔樹中的部分。
僞類
僞類 用于當元素處于某個狀态時,為其添加對應的樣式,這個狀态是根據使用者行為而動态變化的。比如說,使用者懸停在指定的元素時,我們可以通:hover來描述這個元素的狀态。雖然它和普通的css類類似,可以為已有的元素添加樣式,但是它隻有處于dom樹無法描述的狀态下才能為元素添加樣式,是以将其稱為僞類。
圖檔來源網絡
僞元素
僞元素 用于建立不在文檔樹中的元素,并為其添加樣式,比如說,我們可以通過:before來在一個元素前添加一些文本,并為這些文本添加樣式。雖然使用者可以看到這些文本,但是這些文本實際上不在文檔樹中。
圖檔來源網絡
CSS3 規範中的要求使用雙冒号 (::) 表示僞元素,以此來區分僞元素和僞類,比如::before 和::after 等僞元素使用雙冒号 (::),:hover 和:active 等僞類使用單冒号 (:)。雖然 CSS3 标準要求僞元素使用雙冒号的寫法,但也依然支援單冒号的寫法。
總結僞類和僞元素[1]
2. 實作固定寬高比(width: height = 4: 3 )的div,怎麼設定
利用css中
padding
百分比的計算方法:
padding
設定為百分比,是以元素的寬度乘以
100%
進而得到的
padding
值的。
在
div
的
width
為固定的情況下,設定
height
為
,使内容自然溢出,再通過設定
padding-bottom
使元素有一定高度。
利用将
padding-top
或
padding-bottom
設定成百分比,來實作高度滿足寬度的某個比例。因為,當
margin/padding
取形式為百分比的值時,無論是
left/right
,還是
top/bottom
,都是以父元素的
width
為參照物的!
css實作寬高比[2]
3. CSS選擇器
- 通用選擇器(*)
- 标簽選擇器(div)
- class選擇器(.wrap)
- id選擇器(#wrap)
- 屬性選擇器(E[att], E[att=val], E[att~=val])
- E[att]:比對所有具有att屬性的E元素,不考慮它的值
- E[att=val]:比對所有att屬性等于"val"的E元素
- E[att~=val]:比對所有att屬性具有多個空格分隔的值、其中一個值等于"val"的E元素
- 相鄰選擇器(h1 + p)
- 子選擇器(ul > li)
- 後代選擇器(li a)
- 僞類選擇器
- E:first-child:比對父元素的第一個子元素
- E:link 比對所有未被點選的連結
- E:focus 比對獲得目前焦點的E元素
- E:not(s) 反選僞類,比對不符合目前選擇器的任何元素
詳細檢視CSS選擇器筆記[3]
選擇器的優先級(就近原則):!important > [ id > class > tag ]
4. css解析規則
CSS選擇器是 從右向左解析 。
若從左向右的比對,發現不符合規則,需要進行回溯,會損失很多性能。
若從右向左比對,先找到所有的最右節點,對于每一個節點,向上尋找父節點直到找到根元素或者滿足條件的比對規則,則結束這個分支的周遊。
兩種比對規則的性能差别很大,是因為從右向左的比對在第一步就篩選掉了大量的不符合條件的最右節點(葉子節點),而從左向右的比對規則的性能都浪費在了失敗的查找上面。
舉例說明:
16px; }
為什麼從右向左的規則要比從左向右的高效?
若從左向右的比對,過程是:從
.mod-nav
開始,周遊子節點
header
和子節點
div
,然後各自向子節點周遊。在右側
div
的分支中,最後周遊到葉子節點
a
,發現不符合規則,需要回溯到
ul
節點,再周遊下一個
li-a
,假如有1000個
li
,則這
1000
次的周遊與回溯會損失很多性能。
再看看從右至左的比對:先找到所有的最右節點span,對于每一個
span
,向上尋找節點
h3
,由
h3
再向上尋找
class=mod-nav
的節點,最後找到根元素html則結束這個分支的周遊。
很明顯,兩種比對規則的性能差别很大。之是以會差别很大,是因為從右向左的比對在第一步就篩選掉了大量的不符合條件的最右節點(葉子節點);而從左向右的比對規則的性能都浪費在了失敗的查找上面。
答案來源于 CSS選擇器從右向左的比對規則[4]
5. flex: 1 完整寫法
Flex 布局概念: 采用 Flex 布局的元素,稱為 Flex 容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"
flex: 1 完整寫法
flex
屬性是
flex-grow
,
flex-shrink
和
flex-basis
, 預設值為
0 1 auto
。後兩個屬性可選。
flex-grow
屬性定義項目的放大比例,預設為0,即如果存在剩餘空間,也不放大。
flex-shrink
屬性定義了項目的縮小比例,預設為1,即如果空間不足,該項目将縮小。
flex-basis
屬性定義了在配置設定多餘空間之前,項目占據的主軸空間(main size)。浏覽器根據這個屬性,計算主軸是否有多餘空間。它的預設值為auto,即項目的本來大小。
Flex 布局教程:文法篇[5] 、Flex 布局教程:執行個體篇[6]
6. display: none和 visibility:hidden的差別
- 是否占據空間
- display: none 不占據空間
- visibility:hidden 占據空間
是否渲染
- display:none,會觸發reflow(回流),進行渲染。
- visibility:hidden,隻會觸發repaint(重繪),因為沒有發現位置變化,不進行渲染。
是否是繼承屬性(株連性)
- display:none,display不是繼承屬性,元素及其子元素都會消失。
- visibility:hidden,visibility是繼承屬性,若子元素使用了visibility:visible,則不繼承,這個子孫元素又會顯現出來。
7. em rem vh vw calc(), line-height 百分比
em
em: 相對機關,參考物是父元素的font-size,具有繼承的特點。如果字型大小是16px(浏覽器的預設值),那麼 1em = 16px
rem
rem:相對機關,可了解為”root em”, 相對根節點html的字型大小來計算,不會像em那樣,依賴于父元素的字型大小,而造成混亂
vw 和vh
vw:viewpoint width,視窗寬度,1vw等于視窗寬度的1%。
vh:viewpoint height,視窗高度,1vh等于視窗高度的1%。
vmin:取目前vw和Vh中較小的那一個值, vmax:取目前Vw和Vh中較大的那一個值
vw、vh 與 % 百分比的差別:
- % 是相對于父元素的大小設定的比率,vw、vh 是視窗大小決定的。
- vw、vh 優勢在于能夠直接擷取高度,而用 % 在沒有設定 body 高度的情況下,是無法正确獲得可視區域的高度的,是以這是挺不錯的優勢。
calc()
calc(): CSS3中新增的一個函數, 用于動态計算寬/高, 文法非常簡單,就像我們小時候學加 (+)、減(-)、乘(*)、除(/)一樣,使用數學表達式來表示
- 使用“+”、“-”、“*” 和 “/”四則運算;
- 可以使用百分比、px、em、rem等機關;
- 可以混合使用各種機關進行計算;
- 表達式中有“+”和“-”時,其前後必須要有空格,如"width: calc(12%+5em)"這種沒有空格的寫法是錯誤的;
line-height 百分比
可以直接檢視MDN[7]上的相關解釋:
line-height 屬性被指定為以下任何一個:
- 一個 :該屬性的應用值是這個無機關數字乘以該元素的字型大小
- 一個 :與元素自身的字型大小有關。計算值是給定的百分比值乘以元素計算出的字型大小
- 一個
- 關鍵詞 normal。
8.rem實作原理及相應的計算方案
rem布局的本質是等比縮放,一般是基于寬度.
需要了解的基礎知識:
- 預設浏覽器設定的字型大小為16px
- viewport屬性 width、height、initial-scale、maximum-scale、minimum-scale、user-scalable這些屬性,分别表示寬度、高度、初始縮放比例、最大縮放比例、最小縮放比例、是否允許使用者縮放
- dpr, dpr是裝置像素比,是css裡面1px所能顯示的像素點的個數,dpr的值越大,顯示的越精細;window.devicePixelRatio擷取到目前裝置的dpr。
rem實作适配的原理:
- 核心思想:百分比布局可實作響應式布局,而rem相當于百分比布局。
- 實作原理:動态擷取目前視口寬度width,除以一個固定的數n,得到rem的值。表達式為rem = width / n。
- 通過此方法,rem大小始終為width的n等分。
計算方案:
- 通過dpr設定縮放比,實作布局視口大小
var scale =
- 動态計算html的font-size
// 設定根元素字型大小。此時為寬的100等分
實際開發過程中,可以使用 lib-flexible[8]庫,但是如果每次寫的時候都要手動去計算有點太過麻煩了,我們可以通過在webpack中配置 px2rem-loader[9], 或者 pxrem-loader[10],主要原理就是需要自己配置 px轉rem的計算規則,在編輯的時候直接計算轉成rem。是以在開發的時候直接按照設計稿的尺寸寫px,編譯後會直接轉化成rem;
Rem相關文章推薦:
- 移動端頁面開發适配 rem布局原理[11]
- 使用Flexible實作手淘H5頁面的終端适配[12]
- Rem布局的原了解析[13]
9.清除浮動方法及原理
為什麼要清除浮動:父元素因為子級元素浮動引起的内部高度為0的問題。
清除浮動常用的四種方式:
- 父級
定義div
height
- 額外标簽法:在有浮動的父級元素的末尾插入了一個沒有内容的塊級元素div 并添加樣式
。clear:both
- 利用僞元素:父級div定義 僞類:after,我們可以寫一個
工具樣式,當需要清除浮動時,就為其加上這個類.clearfix
。.clearfix:after { display: block; clear :both; content: '';}
- 父級添加
屬性:包含浮動元素的父标簽添加樣式overflow
為overflow
或hidden
,通過觸發BFC方式,實作清除浮動auto
清除浮動的四種方式及其原理了解[14]
10. postcss
我們都知道”babel“的存在,可以讓我們使用比較新的js文法,postcss則可以了解為CSS的”babel“,可以讓我們使用比較新的CSS文法
postcss 不是類似less的CSS預處理器, 而是一種允許用JS插件來轉變樣式的工具。postcss提供了一個解析器,它能夠将CSS解析成抽象文法樹(AST)。
postcss的常用插件
- autoprefixer[15]:autoprefixer插件會給根據CanIUse的相容性去檢查你的CSS代碼,然後自動為你的CSS代碼加上浏覽器廠商的私有字首
- precss[16]
- postcss-cssnext[17]
- PostCSS 是個什麼鬼東西?[18]
11. css modules
css modules作用: - 避免css互相覆寫的方法,CSS Modules 加入了局部作用域和子產品依賴 實作原理 CSS的規則是全局的,任何一個元件的樣式規則,對整個頁面有效;
産生局部作用域的唯一方法,就是使用一個獨一無二的class名字,不會與其他選擇器重名,這就是CSS Modules的實作原理:将每個類名編譯成獨一無二的哈希值;
CSS Modules 用法教程[19]
12. css 預處理器
CSS 預處理器是一個能讓你通過預處理器自己獨有的文法來生成CSS的程式。絕大多數CSS預處理器會增加一些原生CSS不具備的特性,例如代碼混合,嵌套選擇器,繼承選擇器等
最流行的CSS預處理器
- less
- sass
- stylus
- postcss
13. CSS 中的 vertical-align 有哪些值?它在什麼情況下才能生效?
vertical-align屬性值:
- 線類:baseline、top、middle、bottom
- 文本類:text-top、text-bottom
- 上标下标類:sub、super
- 數值百分比類:20px、2em、20%等(對于基線往上或往下偏移)
負值相對于基線往下偏移,正值往上偏移,事實上vertical-align:base-line等同于vertical-align:0。這個負值真的是 CSS 神器!vertical-align生效前提:
- 内聯元素span、strong、em、img、button、input等
- display值為inline、inline-block、inline-table或table-cell的元素
- 需要注意浮動和絕對定位會讓元素塊狀化,是以此元素絕對不會生效
14.BFC(塊格式化上下文)
概念
格式化上下文, 它是頁面中的一塊渲染區域,并且有一套渲染規則,它決定了其子元素将如何定位,以及和其他元素的關系和互相渲染作用 BFC 即 Block Formatting Contexts (塊級格式化上下文),它屬于上述定位方案的普通流。
觸發BFC
隻要元素滿足下面任一條件即可觸發
- 根元素( )
- 浮動元素(元素的 float 不是 none)
- 絕對定位元素(元素的 position 為 absolute 或 fixed)
- 行内塊元素(元素的 display 為 inline-block)
- overflow 值不為 visible 的塊元素
10 分鐘了解 BFC 原理[20], MDN文檔[21]
15 常見布局的實作
- 水準垂直居中
- 兩列布局
水準垂直居中
- flex布局:父元素設定
display: flex; justify-content: center; slign-items: center
-
+position: absolute
, translate是基于元素本身的寬高去計算百分比的,是以同樣适用于寬度和高度都不固定的情況transform: translate(-50%, -50%)
-
+position: absolute
;let: 0; right: 0; top: 0; bottom: 0; margin: auto
兩列布局
左邊寬度固定, 右邊寬度自适應
- 左邊浮動, 下個元素就會獨占位置,并排一行
- left元素浮動, right元素設定
元素的寬度; 右邊寬度固定, 左邊寬度自适應width: 100%; padding-left:left
- 左右都浮動,左邊自适應元素設定外層div 100%寬度, 這樣就會獨占一行, 然後裡層設定右邊的margin, 把右邊元素位置空出來
三列布局
中間自适應, 左右兩邊固定有如下幾種方法
- flex布局:
display: flex; ustify-content: space-between;
- position實作: 左右邊設定絕對定位,設定一個最外級div (給父元素設定relative,相對于最外層定位);
- 注意絕對定位的元素脫離文檔流,相對于最近的已經定位的元素進行定位, 無需考慮HTML中結構的順序
- 缺點:有頂部對齊問題,需要進行調整,注意中間的高度為整個内容的高度
- float實作: 需要将中間的内容放在html結構的最後,否則右側會沉在中間内容的下側
- 原理: 元素浮動後,脫離文檔流,後面的元素受浮動影響,設定受影響元素的margin值即可
- 聖杯布局和雙飛翼布局
聖杯布局和雙飛翼布局
- 共同點:三欄全部float浮動,但左右兩欄加上負margin讓其跟中間欄div并排,以形成三欄布局。負邊距[22]是這兩種布局中的重中之重
- 不同點:解決“中間欄div内容不被遮擋”的思路不同
聖杯布局
- 1.三者都設定向左浮動
- 2.設定middle寬度為100%;
- 3.設定負邊距, left設定負左邊距為100%, right設定負左邊距為負的自身寬度
- 4.設定content的padding值給左右兩個子面闆留出空間
- 5.設定兩個子面闆為相對定位,
的left值為負的left面闆
寬度,left面闆
的right值為負的right面闆
的值right面闆
但是聖杯布局有個問題:當面闆的middle部分比兩邊的子面闆寬度小的時候,布局就會亂掉。是以也就有了雙飛翼布局來克服這個問題。如果不增加任何标簽,想實作更完美的布局非常困難,是以雙飛翼布局在主面闆上選擇了加一個标簽
雙飛翼布局
- 1.三者都設定向左浮動。
- 2.設定middle寬度為100%。
- 3.設定 負邊距,left設定負左邊距為100%,right設定負左邊距為負的自身寬度
- 4.設定middle-content的margin值給左右兩個子面闆留出空間。
對比兩者可以發現,雙飛翼布局與聖杯布局的主要差别在于:
- 1.雙飛翼布局給主面闆(中間元素)添加了一個父标簽用來通過margin給子面闆騰出空間
- 2.聖杯布局采用的是padding,而雙飛翼布局采用的margin, 解決了聖杯布局的問題
- 3.雙飛翼布局不用設定相對布局,以及對應的left和right值
詳解檢視 常見CSS布局的實作[23]
碎碎念
CSS這些題其實都不難,平常開發的時候也經常會遇到,死記硬背也是記不住的,需要自己多動手敲一下才能了解并且記憶深刻,真正融化為自己的知識,很多詞(比如BFC,聖杯布局,雙飛翼布局等)我第一次聽到的時候并不知道他們是什麼,而且感覺從名稱上很難了解,但是多看幾遍,多了解,見多了也就記住了。
上面給出的答案大多是從網上搜的,也不一定是最好的,主要是通過題目來查漏補缺,有問題或者有更好的答案,歡迎大家補充。
文章中涉及到很多文章推薦,建議直接通過檢視原文來檢視相關推薦文章。
CSS相關文章推薦
- 50道 CSS 基礎面試題(附答案)[24]
- 你未必知道的49個CSS知識點[25]
- 你未必知道的CSS知識點(第二季)[26]
- 個人總結(css3新特性)[27]
- 前端基礎篇之CSS世界[28]
參考資料
[1]
總結僞類和僞元素: http://www.alloyteam.com/2016/05/summary-of-pseudo-classes-and-pseudo-elements/#prettyPhoto
[2]
css實作寬高比: https://blog.csdn.net/Honeymao/article/details/77884744
[3]
CSS選擇器筆記: http://www.ruanyifeng.com/blog/2009/03/css_selectors.html
[4]
CSS選擇器從右向左的比對規則: http://www.cnblogs.com/zhaodongyu/p/3341080.html
[5]
Flex 布局教程:文法篇: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
[6]
Flex 布局教程:執行個體篇: http://www.ruanyifeng.com/blog/2015/07/flex-examples.html
[7]
MDN: https://developer.mozilla.org/zh-CN/docs/Web/CSS/line-height
[8]
lib-flexible: https://github.com/amfe/lib-flexible
[9]
px2rem-loader: https://github.com/Jinjiang/px2rem-loader
[10]
pxrem-loader: https://github.com/cupools/pxrem-loader#readme
[11]
移動端頁面開發适配 rem布局原理: https://segmentfault.com/a/1190000007526917
[12]
使用Flexible實作手淘H5頁面的終端适配: https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html
[13]
Rem布局的原了解析: https://zhuanlan.zhihu.com/p/30413803
[14]
清除浮動的四種方式及其原理了解: https://juejin.im/post/59e7190bf265da4307025d91
[15]
autoprefixer: https://github.com/postcss/autoprefixer
[16]
precss: https://github.com/jonathantneal/precss
[17]
postcss-cssnext: https://github.com/MoOx/postcss-cssnext/
[18]
PostCSS 是個什麼鬼東西?: https://segmentfault.com/a/1190000003909268
[19]
CSS Modules 用法教程: http://www.ruanyifeng.com/blog/2016/06/css_modules.html
[20]
10 分鐘了解 BFC 原理: https://zhuanlan.zhihu.com/p/25321647
[21]
MDN文檔: https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
[22]
負邊距: http://www.cnblogs.com/2050/archive/2012/08/13/2636467.html
[23]
常見CSS布局的實作: https://github.com/funnycoderstar/blog/issues/125
[24]
50道 CSS 基礎面試題(附答案): https://www.itcodemonkey.com/article/2853.html
[25]
你未必知道的49個CSS知識點: https://juejin.im/post/5d3eca78e51d4561cb5dde12
[26]
你未必知道的CSS知識點(第二季): https://juejin.im/post/5d9ec8b0518825651b1dffa3
[27]
個人總結(css3新特性): https://juejin.im/post/5a0c184c51882531926e4294
[28]
前端基礎篇之CSS世界: https://juejin.im/post/5ce607a7e51d454f6f16eb3d