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為0,使內容自然溢出,再通過設置padding-bottom使元素有一定高度。
.element {
/* 16:9寬高比,則設padding-bottom:56.25% */
/* height: 0px, 防止矩形被裡面的內容撐出多餘的高度*/
width: 100vw;
height: 0px;
padding-bottom: 56.25%;
background: pink;
}利用將padding-top或padding-bottom設置成百分比,來實現高度滿足寬度的某個比例。因為,當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!
css實現寬高比[2]
3. CSS選擇器屬性選擇器(E[att], E[att=val], E[att~=val])E[att]:匹配所有具有att屬性的E元素,不考慮它的值E[att=val]:匹配所有att屬性等於"val"的E元素E[att~=val]:匹配所有att屬性具有多個空格分隔的值、其中一個值等於"val"的E元素E:first-child:匹配父元素的第一個子元素E:not(s) 反選偽類,匹配不符合當前選擇器的任何元素詳細查看CSS選擇器筆記[3]
選擇器的優先級(就近原則):!important > [ id > class > tag ]
4. css解析規則CSS選擇器是 從右向左解析 。
若從左向右的匹配,發現不符合規則,需要進行回溯,會損失很多性能。
若從右向左匹配,先找到所有的最右節點,對於每一個節點,向上尋找父節點直到找到根元素或者滿足條件的匹配規則,則結束這個分支的遍歷。
兩種匹配規則的性能差別很大,是因為從右向左的匹配在第一步就篩選掉了大量的不符合條件的最右節點(葉子節點),而從左向右的匹配規則的性能都浪費在了失敗的查找上面。
舉例說明:
.mod-nav h3 span { font-size: 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,會觸發reflow(回流),進行渲染。visibility:hidden,只會觸發repaint(重繪),因為沒有發現位置變化,不進行渲染。display:none,display不是繼承屬性,元素及其子元素都會消失。visibility:hidden,visibility是繼承屬性,若子元素使用了visibility:visible,則不繼承,這個子孫元素又會顯現出來。7. em rem vh vw calc(), line-height 百分比emem: 相對單位,參考物是父元素的font-size,具有繼承的特點。如果字體大小是16px(瀏覽器的默認值),那麼 1em = 16px
remrem:相對單位,可理解為」root em」, 相對根節點html的字體大小來計算,不會像em那樣,依賴於父元素的字體大小,而造成混亂
vw 和vhvw: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中新增的一個函數, 用於動態計算寬/高, 語法非常簡單,就像我們小時候學加 (+)、減(-)、乘(*)、除(/)一樣,使用數學表達式來表示
表達式中有「+」和「-」時,其前後必須要有空格,如"width: calc(12%+5em)"這種沒有空格的寫法是錯誤的;line-height 百分比可以直接查看MDN[7]上的相關解釋:
line-height 屬性被指定為以下任何一個:
一個 <數字>:該屬性的應用值是這個無單位數字<數字>乘以該元素的字體大小一個 <百分比>:與元素自身的字體大小有關。計算值是給定的百分比值乘以元素計算出的字體大小8.rem實現原理及相應的計算方案rem布局的本質是等比縮放,一般是基於寬度.
需要了解的基礎知識:
viewport屬性width、height、initial-scale、maximum-scale、minimum-scale、user-scalable這些屬性,分別表示寬度、高度、初始縮放比例、最大縮放比例、最小縮放比例、是否允許用戶縮放<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1.0, user-scalable=no">
dpr, dpr是設備像素比,是css裡面1px所能顯示的像素點的個數,dpr的值越大,顯示的越精細;window.devicePixelRatio獲取到當前設備的dpr。rem實現適配的原理:
核心思想:百分比布局可實現響應式布局,而rem相當於百分比布局。實現原理:動態獲取當前視口寬度width,除以一個固定的數n,得到rem的值。表達式為rem = width / n。計算方案:
var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale='+ scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');// 設置根元素字體大小。此時為寬的100等分
document.documentElement.style.fontSize = ocument.documentElement.clientWidth / 100 + 'px';實際開發過程中,可以使用 lib-flexible[8]庫,但是如果每次寫的時候都要手動去計算有點太過麻煩了,我們可以通過在webpack中配置 px2rem-loader[9], 或者 pxrem-loader[10],主要原理就是需要自己配置 px轉rem的計算規則,在編輯的時候直接計算轉成rem。所以在開發的時候直接按照設計稿的尺寸寫px,編譯後會直接轉化成rem;
Rem相關文章推薦:
使用Flexible實現手淘H5頁面的終端適配[12]9.清除浮動方法及原理為什麼要清除浮動:父元素因為子級元素浮動引起的內部高度為0的問題。
清除浮動常用的四種方式:
額外標籤法:在有浮動的父級元素的末尾插入了一個沒有內容的塊級元素div 並添加樣式clear:both。利用偽元素:父級div定義 偽類:after,我們可以寫一個.clearfix 工具樣式,當需要清除浮動時,就為其加上這個類 .clearfix:after { display: block; clear :both; content: '';}。父級添加overflow屬性:包含浮動元素的父標籤添加樣式overflow為hidden或auto,通過觸發BFC方式,實現清除浮動清除浮動的四種方式及其原理理解[14]
10. postcss我們都知道」babel「的存在,可以讓我們使用比較新的js語法,postcss則可以理解為CSS的」babel「,可以讓我們使用比較新的CSS語法
postcss 不是類似less的CSS預處理器, 而是一種允許用JS插件來轉變樣式的工具。postcss提供了一個解析器,它能夠將CSS解析成抽象語法樹(AST)。
postcss的常用插件
autoprefixer[15]:autoprefixer插件會給根據CanIUse的兼容性去檢查你的CSS代碼,然後自動為你的CSS代碼加上瀏覽器廠商的私有前綴11. css modulescss modules作用:- 避免css相互覆蓋的方法,CSS Modules 加入了局部作用域和模塊依賴實現原理CSS的規則是全局的,任何一個組件的樣式規則,對整個頁面有效;
產生局部作用域的唯一方法,就是使用一個獨一無二的class名字,不會與其他選擇器重名,這就是CSS Modules的實現原理:將每個類名編譯成獨一無二的哈希值;CSS Modules 用法教程[19]
12. css 預處理器CSS 預處理器是一個能讓你通過預處理器自己獨有的語法來生成CSS的程序。絕大多數CSS預處理器會增加一些原生CSS不具備的特性,例如代碼混合,嵌套選擇器,繼承選擇器等
最流行的CSS預處理器
13. CSS 中的 vertical-align 有哪些值?它在什麼情況下才能生效?vertical-align屬性值:
線類:baseline、top、middle、bottom數值百分比類: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只要元素滿足下面任一條件即可觸發
絕對定位元素(元素的 position 為 absolute 或 fixed)行內塊元素(元素的 display 為 inline-block)overflow 值不為 visible 的塊元素10 分鐘理解 BFC 原理[20], MDN文檔[21]
15 常見布局的實現水平垂直居中flex布局:父元素設置 display: flex; justify-content: center; slign-items: centerposition: absolute + transform: translate(-50%, -50%) , translate是基於元素本身的寬高去計算百分比的,所以同樣適用於寬度和高度都不固定的情況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內容不被遮擋」的思路不同聖杯布局3.設置負邊距, left設置負左邊距為100%, right設置負左邊距為負的自身寬度4.設置content的padding值給左右兩個子面板留出空間5.設置兩個子面板為相對定位,left面板的left值為負的left面板寬度,right面板的right值為負的right面板的值但是聖杯布局有個問題:當面板的middle部分比兩邊的子面板寬度小的時候,布局就會亂掉。因此也就有了雙飛翼布局來克服這個問題。如果不增加任何標籤,想實現更完美的布局非常困難,因此雙飛翼布局在主面板上選擇了加一個標籤
雙飛翼布局3.設置 負邊距,left設置負左邊距為100%,right設置負左邊距為負的自身寬度4.設置middle-content的margin值給左右兩個子面板留出空間。對比兩者可以發現,雙飛翼布局與聖杯布局的主要差別在於:
1.雙飛翼布局給主面板(中間元素)添加了一個父標籤用來通過margin給子面板騰出空間2.聖杯布局採用的是padding,而雙飛翼布局採用的margin, 解決了聖杯布局的問題3.雙飛翼布局不用設置相對布局,以及對應的left和right值詳解查看 常見CSS布局的實現[23]
碎碎念CSS這些題其實都不難,平常開發的時候也經常會遇到,死記硬背也是記不住的,需要自己多動手敲一下才能理解並且記憶深刻,真正融化為自己的知識,很多詞(比如BFC,聖杯布局,雙飛翼布局等)我第一次聽到的時候並不知道他們是什麼,而且感覺從名稱上很難理解,但是多看幾遍,多理解,見多了也就記住了。
上面給出的答案大多是從網上搜的,也不一定是最好的,主要是通過題目來查漏補缺,有問題或者有更好的答案,歡迎大家補充。
文章中涉及到很多文章推薦,建議直接通過查看原文來查看相關推薦文章。
CSS相關文章推薦參考資料[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