前端面試 CSS篇

2023-02-17 10:51 更新

一、CSS基礎(chǔ)


1. CSS選擇器及其優(yōu)先級

選擇器 格式 優(yōu)先級權(quán)重
id選擇器 #id 100
類選擇器 .classname 10
屬性選擇器 a[ref=“eee”] 10
偽類選擇器 li:last-child 10
標(biāo)簽選擇器 div 1
偽元素選擇器 li:after 1
相鄰兄弟選擇器 h1+p 0
子選擇器 ul>li 0
后代選擇器 li a 0
通配符選擇器 * 0

對于選擇器的優(yōu)先級

  • 標(biāo)簽選擇器、偽元素選擇器:1
  • 類選擇器、偽類選擇器、屬性選擇器:10
  • id 選擇器:100
  • 內(nèi)聯(lián)樣式:1000

注意事項(xiàng):

  • !important聲明的樣式的優(yōu)先級最高;
  • 如果優(yōu)先級相同,則最后出現(xiàn)的樣式生效;
  • 繼承得到的樣式的優(yōu)先級最低;
  • 通用選擇器(*)、子選擇器(>)和相鄰?fù)x擇器(+)并不在這四個(gè)等級中,所以它們的權(quán)值都為 0 ;
  • 樣式表的來源不同時(shí),優(yōu)先級順序?yàn)椋簝?nèi)聯(lián)樣式 > 內(nèi)部樣式 > 外部樣式 > 瀏覽器用戶自定義樣式 > 瀏覽器默認(rèn)樣式。

2. CSS中可繼承與不可繼承屬性有哪些

一、無繼承性的屬性

  1. display:規(guī)定元素應(yīng)該生成的框的類型
  2. 文本屬性
    • vertical-align:垂直文本對齊
    • text-decoration:規(guī)定添加到文本的裝飾
    • text-shadow:文本陰影效果
    • white-space:空白符的處理
    • unicode-bidi:設(shè)置文本的方向
  3. 盒子模型的屬性:width、height、margin、border、padding
  4. 背景屬性:background、background-color、background-image、background-repeat、background-position、background-attachment
  5. 定位屬性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
  6. 生成內(nèi)容屬性:content、counter-reset、counter-increment
  7. 輪廓樣式屬性:outline-style、outline-width、outline-color、outline
  8. 頁面樣式屬性:size、page-break-before、page-break-after
  9. 聲音樣式屬性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during

二、有繼承性的屬性

  1. 字體系列屬性
    • font-family:字體系列
    • font-weight:字體的粗細(xì)
    • font-size:字體的大小
    • font-style:字體的風(fēng)格
  2. 文本系列屬性
    • text-indent:文本縮進(jìn)
    • text-align:文本水平對齊
    • line-height:行高
    • word-spacing:單詞之間的間距
    • letter-spacing:中文或者字母之間的間距
    • text-transform:控制文本大小寫(就是uppercase、lowercase、capitalize這三個(gè))
    • color:文本顏色
  3. 元素可見性
    • visibility:控制元素顯示隱藏
  4. 列表布局屬性
    • list-style:列表風(fēng)格,包括list-style-type、list-style-image等
  5. 光標(biāo)屬性
    • cursor:光標(biāo)顯示為何種形態(tài)

3. display的屬性值及其作用

屬性值 作用
none 元素不顯示,并且會(huì)從文檔流中移除。
block 塊類型。默認(rèn)寬度為父元素寬度,可設(shè)置寬高,換行顯示。
inline 行內(nèi)元素類型。默認(rèn)寬度為內(nèi)容寬度,不可設(shè)置寬高,同行顯示。
inline-block 默認(rèn)寬度為內(nèi)容寬度,可以設(shè)置寬高,同行顯示。
list-item 像塊類型元素一樣顯示,并添加樣式列表標(biāo)記。
table 此元素會(huì)作為塊級表格來顯示。
inherit 規(guī)定應(yīng)該從父元素繼承display屬性的值。

4. display的block、inline和inline-block的區(qū)別

(1)block:會(huì)獨(dú)占一行,多個(gè)元素會(huì)另起一行,可以設(shè)置width、height、margin和padding屬性;

(2)inline:元素不會(huì)獨(dú)占一行,設(shè)置width、height屬性無效。但可以設(shè)置水平方向的margin和padding屬性,不能設(shè)置垂直方向的padding和margin;

(3)inline-block:將對象設(shè)置為inline對象,但對象的內(nèi)容作為block對象呈現(xiàn),之后的內(nèi)聯(lián)對象會(huì)被排列在同一行內(nèi)。

對于行內(nèi)元素和塊級元素,其特點(diǎn)如下:

(1)行內(nèi)元素

  • 設(shè)置寬高無效;
  • 可以設(shè)置水平方向的margin和padding屬性,不能設(shè)置垂直方向的padding和margin;
  • 不會(huì)自動(dòng)換行;

(2)塊級元素

  • 可以設(shè)置寬高;
  • 設(shè)置margin和padding都有效;
  • 可以自動(dòng)換行;
  • 多個(gè)塊狀,默認(rèn)排列從上到下。

5. 隱藏元素的方法有哪些

  • display: none:渲染樹不會(huì)包含該渲染對象,因此該元素不會(huì)在頁面中占據(jù)位置,也不會(huì)響應(yīng)綁定的監(jiān)聽事件。
  • visibility: hidden:元素在頁面中仍占據(jù)空間,但是不會(huì)響應(yīng)綁定的監(jiān)聽事件。
  • opacity: 0:將元素的透明度設(shè)置為 0,以此來實(shí)現(xiàn)元素的隱藏。元素在頁面中仍然占據(jù)空間,并且能夠響應(yīng)元素綁定的監(jiān)聽事件。
  • position: absolute:通過使用絕對定位將元素移除可視區(qū)域內(nèi),以此來實(shí)現(xiàn)元素的隱藏。
  • z-index: 負(fù)值:來使其他元素遮蓋住該元素,以此來實(shí)現(xiàn)隱藏。
  • clip/clip-path :使用元素裁剪的方法來實(shí)現(xiàn)元素的隱藏,這種方法下,元素仍在頁面中占據(jù)位置,但是不會(huì)響應(yīng)綁定的監(jiān)聽事件。
  • transform: scale(0,0):將元素縮放為 0,來實(shí)現(xiàn)元素的隱藏。這種方法下,元素仍在頁面中占據(jù)位置,但是不會(huì)響應(yīng)綁定的監(jiān)聽事件。

6. link和@import的區(qū)別

兩者都是外部引用CSS的方式,它們的區(qū)別如下:

  • link是XHTML標(biāo)簽,除了加載CSS外,還可以定義RSS等其他事務(wù);@import屬于CSS范疇,只能加載CSS。
  • link引用CSS時(shí),在頁面載入時(shí)同時(shí)加載;@import需要頁面網(wǎng)頁完全載入以后加載。
  • link是XHTML標(biāo)簽,無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  • link支持使用Javascript控制DOM去改變樣式;而@import不支持。

7. transition和animation的區(qū)別

  • transition是過渡屬性,強(qiáng)調(diào)過渡,它的實(shí)現(xiàn)需要觸發(fā)一個(gè)事件(比如鼠標(biāo)移動(dòng)上去,焦點(diǎn),點(diǎn)擊等)才執(zhí)行動(dòng)畫。它類似于flash的補(bǔ)間動(dòng)畫,設(shè)置一個(gè)開始關(guān)鍵幀,一個(gè)結(jié)束關(guān)鍵幀。
  • animation是動(dòng)畫屬性,它的實(shí)現(xiàn)不需要觸發(fā)事件,設(shè)定好時(shí)間之后可以自己執(zhí)行,且可以循環(huán)一個(gè)動(dòng)畫。它也類似于flash的補(bǔ)間動(dòng)畫,但是它可以設(shè)置多個(gè)關(guān)鍵幀(用@keyframe定義)完成動(dòng)畫。

8. display:none與visibility:hidden的區(qū)別

這兩個(gè)屬性都是讓元素隱藏,不可見。兩者區(qū)別如下:

(1)在渲染樹中

  • ?display:none?會(huì)讓元素完全從渲染樹中消失,渲染時(shí)不會(huì)占據(jù)任何空間;
  • ?visibility:hidden?不會(huì)讓元素從渲染樹中消失,渲染的元素還會(huì)占據(jù)相應(yīng)的空間,只是內(nèi)容不可見。

(2)是否是繼承屬性

  • ?display:none?是非繼承屬性,子孫節(jié)點(diǎn)會(huì)隨著父節(jié)點(diǎn)從渲染樹消失,通過修改子孫節(jié)點(diǎn)的屬性也無法顯示;
  • ?visibility:hidden? 是繼承屬性,子孫節(jié)點(diǎn)消失是由于繼承了 ?hidden?,通過設(shè)置 ?visibility:visible? 可以讓子孫節(jié)點(diǎn)顯示;

(3)修改常規(guī)文檔流中元素的 ?display ?通常會(huì)造成文檔的重排,但是修改 ?visibility? 屬性只會(huì)造成本元素的重繪;

(4)如果使用讀屏器,設(shè)置為 ?display:none? 的內(nèi)容不會(huì)被讀取,設(shè)置為 ?visibility:hidden? 的內(nèi)容會(huì)被讀取。

9. 偽元素和偽類的區(qū)別和作用?

  • 偽元素:在內(nèi)容元素的前后插入額外的元素或樣式,但是這些元素實(shí)際上并不在文檔中生成。它們只在外部顯示可見,但不會(huì)在文檔的源代碼中找到它們,因此,稱為“偽”元素。例如:
p::before {content:"第一章:";}
p::after {content:"Hot!";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}
  • 偽類:將特殊的效果添加到特定選擇器上。它是已有元素上添加類別的,不會(huì)產(chǎn)生新的元素。例如:
a:hover {color: #FF00FF}
p:first-child {color: red}

總結(jié):偽類是通過在元素選擇器上加?偽類改變元素狀態(tài),?偽元素通過對元素的操作進(jìn)?對元素的改變。

10. 對requestAnimationframe的理解

實(shí)現(xiàn)動(dòng)畫效果的方法比較多,Javascript 中可以通過定時(shí)器 setTimeout 來實(shí)現(xiàn),CSS3 中可以使用 transition 和 animation 來實(shí)現(xiàn),HTML5 中的 canvas 也可以實(shí)現(xiàn)。除此之外,HTML5 提供一個(gè)專門用于請求動(dòng)畫的API,那就是 requestAnimationFrame,顧名思義就是請求動(dòng)畫幀。

MDN對該方法的描述:

window.requestAnimationFrame() 告訴瀏覽器——你希望執(zhí)行一個(gè)動(dòng)畫,并且要求瀏覽器在下次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動(dòng)畫。該方法需要傳入一個(gè)回調(diào)函數(shù)作為參數(shù),該回調(diào)函數(shù)會(huì)在瀏覽器下一次重繪之前執(zhí)行。

語法: window.requestAnimationFrame(callback); 其中,callback是下一次重繪之前更新動(dòng)畫幀所調(diào)用的函數(shù)(即上面所說的回調(diào)函數(shù))。該回調(diào)函數(shù)會(huì)被傳入DOMHighResTimeStamp參數(shù),它表示requestAnimationFrame() 開始去執(zhí)行回調(diào)函數(shù)的時(shí)刻。該方法屬于宏任務(wù),所以會(huì)在執(zhí)行完微任務(wù)之后再去執(zhí)行。

取消動(dòng)畫:使用cancelAnimationFrame()來取消執(zhí)行動(dòng)畫,該方法接收一個(gè)參數(shù)——requestAnimationFrame默認(rèn)返回的id,只需要傳入這個(gè)id就可以取消動(dòng)畫了。

優(yōu)勢:

  • CPU節(jié)能:使用SetTinterval 實(shí)現(xiàn)的動(dòng)畫,當(dāng)頁面被隱藏或最小化時(shí),SetTinterval 仍然在后臺(tái)執(zhí)行動(dòng)畫任務(wù),由于此時(shí)頁面處于不可見或不可用狀態(tài),刷新動(dòng)畫是沒有意義的,完全是浪費(fèi)CPU資源。而RequestAnimationFrame則完全不同,當(dāng)頁面處于未激活的狀態(tài)下,該頁面的屏幕刷新任務(wù)也會(huì)被系統(tǒng)暫停,因此跟著系統(tǒng)走的RequestAnimationFrame也會(huì)停止渲染,當(dāng)頁面被激活時(shí),動(dòng)畫就從上次停留的地方繼續(xù)執(zhí)行,有效節(jié)省了CPU開銷。
  • 函數(shù)節(jié)流:在高頻率事件( resize, scroll 等)中,為了防止在一個(gè)刷新間隔內(nèi)發(fā)生多次函數(shù)執(zhí)行,RequestAnimationFrame可保證每個(gè)刷新間隔內(nèi),函數(shù)只被執(zhí)行一次,這樣既能保證流暢性,也能更好的節(jié)省函數(shù)執(zhí)行的開銷,一個(gè)刷新間隔內(nèi)函數(shù)執(zhí)行多次時(shí)沒有意義的,因?yàn)槎鄶?shù)顯示器每16.7ms刷新一次,多次繪制并不會(huì)在屏幕上體現(xiàn)出來。
  • 減少DOM操作:requestAnimationFrame 會(huì)把每一幀中的所有DOM操作集中起來,在一次重繪或回流中就完成,并且重繪或回流的時(shí)間間隔緊緊跟隨瀏覽器的刷新頻率,一般來說,這個(gè)頻率為每秒60幀。

setTimeout執(zhí)行動(dòng)畫的缺點(diǎn):它通過設(shè)定間隔時(shí)間來不斷改變圖像位置,達(dá)到動(dòng)畫效果。但是容易出現(xiàn)卡頓、抖動(dòng)的現(xiàn)象;原因是:

  • settimeout任務(wù)被放入異步隊(duì)列,只有當(dāng)主線程任務(wù)執(zhí)行完后才會(huì)執(zhí)行隊(duì)列中的任務(wù),因此實(shí)際執(zhí)行時(shí)間總是比設(shè)定時(shí)間要晚;
  • settimeout的固定時(shí)間間隔不一定與屏幕刷新間隔時(shí)間相同,會(huì)引起丟幀。

11. 對盒模型的理解

CSS3中的盒模型有以下兩種:標(biāo)準(zhǔn)盒子模型、IE盒子模型


img

盒模型都是由四個(gè)部分組成的,分別是margin、border、padding和content。

標(biāo)準(zhǔn)盒模型和IE盒模型的區(qū)別在于設(shè)置width和height時(shí),所對應(yīng)的范圍不同:

  • 標(biāo)準(zhǔn)盒模型的width和height屬性的范圍只包含了content,
  • IE盒模型的width和height屬性的范圍包含了border、padding和content。

可以通過修改元素的box-sizing屬性來改變元素的盒模型:

  • ?box-sizeing: content-box?表示標(biāo)準(zhǔn)盒模型(默認(rèn)值)
  • ?box-sizeing: border-box?表示IE盒模型(怪異盒模型)

12. 為什么有時(shí)候?translate來改變位置?不是定位?

translate 是 transform 屬性的?個(gè)值。改變transform或opacity不會(huì)觸發(fā)瀏覽器重新布局(reflow)或重繪(repaint),只會(huì)觸發(fā)復(fù)合(compositions)。?改變絕對定位會(huì)觸發(fā)重新布局,進(jìn)?觸發(fā)重繪和復(fù)合。transform使瀏覽器為元素創(chuàng)建?個(gè) GPU 圖層,但改變絕對定位會(huì)使?到 CPU。 因此translate()更?效,可以縮短平滑動(dòng)畫的繪制時(shí)間。 ?translate改變位置時(shí),元素依然會(huì)占據(jù)其原始空間,絕對定位就不會(huì)發(fā)?這種情況。

13. li 與 li 之間有看不見的空白間隔是什么原因引起的?如何解決?

瀏覽器會(huì)把inline內(nèi)聯(lián)元素間的空白字符(空格、換行、Tab等)渲染成一個(gè)空格。為了美觀,通常是一個(gè) <li>放在一行,這導(dǎo)致 <li>換行后產(chǎn)生換行字符,它變成一個(gè)空格,占用了一個(gè)字符的寬度。

解決辦法:

(1)為 ?<li>?設(shè)置float:left。不足:有些容器是不能設(shè)置浮動(dòng),如左右切換的焦點(diǎn)圖等。

(2)將所有 ?<li>?寫在同一行。不足:代碼不美觀。

(3)將 ?<ul>?內(nèi)的字符尺寸直接設(shè)為0,即font-size:0。不足:?<ul>?中的其他字符尺寸也被設(shè)為0,需要額外重新設(shè)定其他字符尺寸,且在Safari瀏覽器依然會(huì)出現(xiàn)空白間隔。

(4)消除 ?<ul>?的字符間隔letter-spacing:-8px,不足:這也設(shè)置了 ?<li>?內(nèi)的字符間隔,因此需要將 ?<li>?內(nèi)的字符間隔設(shè)為默認(rèn)letter-spacing:normal。

14. CSS3中有哪些新特性

  • 新增各種CSS選擇器 (: not(.input):所有 class 不是“input”的節(jié)點(diǎn))
  • 圓角 (border-radius:8px)
  • 多列布局 (multi-column layout)
  • 陰影和反射 (Shadoweflect)
  • 文字特效 (text-shadow)
  • 文字渲染 (Text-decoration)
  • 線性漸變 (gradient)
  • 旋轉(zhuǎn) (transform)
  • 增加了旋轉(zhuǎn),縮放,定位,傾斜,動(dòng)畫,多背景

15. 替換元素的概念及計(jì)算規(guī)則

img、input、textarea、select

通過修改某個(gè)屬性值呈現(xiàn)的內(nèi)容就可以被替換的元素就稱為“替換元素”。

替換元素除了內(nèi)容可替換這一特性以外,還有以下特性:

  • 內(nèi)容的外觀不受頁面上的CSS的影響:用專業(yè)的話講就是在樣式表現(xiàn)在CSS作用域之外。如何更改替換元素本身的外觀需要類似appearance屬性,或者瀏覽器自身暴露的一些樣式接口。
  • 有自己的尺寸:在Web中,很多替換元素在沒有明確尺寸設(shè)定的情況下,其默認(rèn)的尺寸(不包括邊框)是300像素×150像素,如
  • 在很多CSS屬性上有自己的一套表現(xiàn)規(guī)則:比較具有代表性的就是vertical-align屬性,對于替換元素和非替換元素,vertical-align屬性值的解釋是不一樣的。比方說vertical-align的默認(rèn)值的baseline,很簡單的屬性值,基線之意,被定義為字符x的下邊緣,而替換元素的基線卻被硬生生定義成了元素的下邊緣。
  • 所有的替換元素都是內(nèi)聯(lián)水平元素:也就是替換元素和替換元素、替換元素和文字都是可以在一行顯示的。但是,替換元素默認(rèn)的display值卻是不一樣的,有的是inline,有的是inline-block。

替換元素的尺寸從內(nèi)而外分為三類:

  • 固有尺寸: 指的是替換內(nèi)容原本的尺寸。例如,圖片、視頻作為一個(gè)獨(dú)立文件存在的時(shí)候,都是有著自己的寬度和高度的。
  • HTML尺寸: 只能通過HTML原生屬性改變,這些HTML原生屬性包括的width和height屬性、的size屬性。
  • CSS尺寸: 特指可以通過CSS的width和height或者max-width/min-width和max-height/min-height設(shè)置的尺寸,對應(yīng)盒尺寸中的content box。

這三層結(jié)構(gòu)的計(jì)算規(guī)則具體如下:

(1)如果沒有CSS尺寸和HTML尺寸,則使用固有尺寸作為最終的寬高。

(2)如果沒有CSS尺寸,則使用HTML尺寸作為最終的寬高。

(3)如果有CSS尺寸,則最終尺寸由CSS屬性決定。

(4)如果“固有尺寸”含有固有的寬高比例,同時(shí)僅設(shè)置了寬度或僅設(shè)置了高度,則元素依然按照固有的寬高比例顯示。

(5)如果上面的條件都不符合,則最終寬度表現(xiàn)為300像素,高度為150像素。

(6)內(nèi)聯(lián)替換元素和塊級替換元素使用上面同一套尺寸計(jì)算規(guī)則。

16. 常見的圖片格式及使用場景

(1)BMP,是無損的、既支持索引色也支持直接色的點(diǎn)陣圖。這種圖片格式幾乎沒有對數(shù)據(jù)進(jìn)行壓縮,所以BMP格式的圖片通常是較大的文件。

(2)GIF是無損的、采用索引色的點(diǎn)陣圖。采用LZW壓縮算法進(jìn)行編碼。文件小,是GIF格式的優(yōu)點(diǎn),同時(shí),GIF格式還具有支持動(dòng)畫以及透明的優(yōu)點(diǎn)。但是GIF格式僅支持8bit的索引色,所以GIF格式適用于對色彩要求不高同時(shí)需要文件體積較小的場景。

(3)JPEG是有損的、采用直接色的點(diǎn)陣圖。JPEG的圖片的優(yōu)點(diǎn)是采用了直接色,得益于更豐富的色彩,JPEG非常適合用來存儲(chǔ)照片,與GIF相比,JPEG不適合用來存儲(chǔ)企業(yè)Logo、線框類的圖。因?yàn)橛袚p壓縮會(huì)導(dǎo)致圖片模糊,而直接色的選用,又會(huì)導(dǎo)致圖片文件較GIF更大。

(4)PNG-8是無損的、使用索引色的點(diǎn)陣圖。PNG是一種比較新的圖片格式,PNG-8是非常好的GIF格式替代者,在可能的情況下,應(yīng)該盡可能的使用PNG-8而不是GIF,因?yàn)樵谙嗤膱D片效果下,PNG-8具有更小的文件體積。除此之外,PNG-8還支持透明度的調(diào)節(jié),而GIF并不支持。除非需要?jiǎng)赢嫷闹С郑駝t沒有理由使用GIF而不是PNG-8。

(5)PNG-24是無損的、使用直接色的點(diǎn)陣圖。PNG-24的優(yōu)點(diǎn)在于它壓縮了圖片的數(shù)據(jù),使得同樣效果的圖片,PNG-24格式的文件大小要比BMP小得多。當(dāng)然,PNG24的圖片還是要比JPEG、GIF、PNG-8大得多。

(6)SVG是無損的矢量圖。SVG是矢量圖意味著SVG圖片由直線和曲線以及繪制它們的方法組成。當(dāng)放大SVG圖片時(shí),看到的還是線和曲線,而不會(huì)出現(xiàn)像素點(diǎn)。SVG圖片在放大時(shí),不會(huì)失真,所以它適合用來繪制Logo、Icon等。

(7)WebP是谷歌開發(fā)的一種新圖片格式,WebP是同時(shí)支持有損和無損壓縮的、使用直接色的點(diǎn)陣圖。從名字就可以看出來它是為Web而生的,什么叫為Web而生呢?就是說相同質(zhì)量的圖片,WebP具有更小的文件體積?,F(xiàn)在網(wǎng)站上充滿了大量的圖片,如果能夠降低每一個(gè)圖片的文件大小,那么將大大減少瀏覽器和服務(wù)器之間的數(shù)據(jù)傳輸量,進(jìn)而降低訪問延遲,提升訪問體驗(yàn)。目前只有Chrome瀏覽器和Opera瀏覽器支持WebP格式,兼容性不太好。

  • 在無損壓縮的情況下,相同質(zhì)量的WebP圖片,文件大小要比PNG小26%;
  • 在有損壓縮的情況下,具有相同圖片精度的WebP圖片,文件大小要比JPEG小25%~34%;
  • WebP圖片格式支持圖片透明度,一個(gè)無損壓縮的WebP圖片,如果要支持透明度只需要22%的格外文件大小。

17. 對 CSSSprites 的理解

CSSSprites(精靈圖),將一個(gè)頁面涉及到的所有圖片都包含到一張大圖中去,然后利用CSS的 background-image,background-repeat,background-position屬性的組合進(jìn)行背景定位。

優(yōu)點(diǎn):

  • 利用 ?CSS Sprites?能很好地減少網(wǎng)頁的http請求,從而大大提高了頁面的性能,這是 ?CSS Sprites?最大的優(yōu)點(diǎn);
  • ?CSS Sprites?能減少圖片的字節(jié),把3張圖片合并成1張圖片的字節(jié)總是小于這3張圖片的字節(jié)總和。

缺點(diǎn):

  • 在圖片合并時(shí),要把多張圖片有序的、合理的合并成一張圖片,還要留好足夠的空間,防止板塊內(nèi)出現(xiàn)不必要的背景。在寬屏及高分辨率下的自適應(yīng)頁面,如果背景不夠?qū)?,很容易出現(xiàn)背景斷裂;
  • ?CSSSprites?在開發(fā)的時(shí)候相對來說有點(diǎn)麻煩,需要借助 ?photoshop?或其他工具來對每個(gè)背景單元測量其準(zhǔn)確的位置。
  • 維護(hù)方面:?CSS Sprites?在維護(hù)的時(shí)候比較麻煩,頁面背景有少許改動(dòng)時(shí),就要改這張合并的圖片,無需改的地方盡量不要?jiǎng)?,這樣避免改動(dòng)更多的 ?CSS?,如果在原來的地方放不下,又只能(最好)往下加圖片,這樣圖片的字節(jié)就增加了,還要改動(dòng) ?CSS?。

18. 什么是物理像素,邏輯像素和像素密度,為什么在移動(dòng)端開發(fā)時(shí)需要用到@3x, @2x這種圖片?

以 iPhone XS 為例,當(dāng)寫 CSS 代碼時(shí),針對于單位 px,其寬度為 414px & 896px,也就是說當(dāng)賦予一個(gè) DIV元素寬度為 414px,這個(gè) DIV 就會(huì)填滿手機(jī)的寬度;

而如果有一把尺子來實(shí)際測量這部手機(jī)的物理像素,實(shí)際為 1242*2688 物理像素;經(jīng)過計(jì)算可知,1242/414=3,也就是說,在單邊上,一個(gè)邏輯像素=3個(gè)物理像素,就說這個(gè)屏幕的像素密度為 3,也就是常說的 3 倍屏。

對于圖片來說,為了保證其不失真,1 個(gè)圖片像素至少要對應(yīng)一個(gè)物理像素,假如原始圖片是 500300 像素,那么在 3 倍屏上就要放一個(gè) 1500900 像素的圖片才能保證 1 個(gè)物理像素至少對應(yīng)一個(gè)圖片像素,才能不失真。


當(dāng)然,也可以針對所有屏幕,都只提供最高清圖片。雖然低密度屏幕用不到那么多圖片像素,而且會(huì)因?yàn)橄螺d多余的像素造成帶寬浪費(fèi)和下載延遲,但從結(jié)果上說能保證圖片在所有屏幕上都不會(huì)失真。

還可以使用 CSS 媒體查詢來判斷不同的像素密度,從而選擇不同的圖片:

my-image { background: (low.png); }
@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

19. margin 和 padding 的使用場景

  • 需要在border外側(cè)添加空白,且空白處不需要背景(色)時(shí),使用 margin;
  • 需要在border內(nèi)測添加空白,且空白處需要背景(色)時(shí),使用 padding。

20. 對line-height 的理解及其賦值方式

(1)line-height的概念:

  • line-height 指一行文本的高度,包含了字間距,實(shí)際上是下一行基線到上一行基線距離;
  • 如果一個(gè)標(biāo)簽沒有定義 height 屬性,那么其最終表現(xiàn)的高度由 line-height 決定;
  • 一個(gè)容器沒有設(shè)置高度,那么撐開容器高度的是 line-height,而不是容器內(nèi)的文本內(nèi)容;
  • 把 line-height 值設(shè)置為 height 一樣大小的值可以實(shí)現(xiàn)單行文字的垂直居中;
  • line-height 和 height 都能撐開一個(gè)高度;

(2)line-height 的賦值方式:

  • 帶單位:px 是固定值,而 em 會(huì)參考父元素 font-size 值計(jì)算自身的行高
  • 純數(shù)字:會(huì)把比例傳遞給后代。例如,父級行高為 1.5,子元素字體為 18px,則子元素行高為 1.5 * 18 = 27px
  • 百分比:將計(jì)算后的值傳遞給后代

21. CSS 優(yōu)化和提高性能的方法有哪些?

加載性能:

(1)css壓縮:將寫好的css進(jìn)行打包壓縮,可以減小文件體積。

(2)css單一樣式:當(dāng)需要下邊距和左邊距的時(shí)候,很多時(shí)候會(huì)選擇使用 margin:top 0 bottom 0;但margin-bottom:bottom;margin-left:left;執(zhí)行效率會(huì)更高。

(3)減少使用@import,建議使用link,因?yàn)楹笳咴陧撁婕虞d時(shí)一起加載,前者是等待頁面加載完成之后再進(jìn)行加載。

選擇器性能:

(1)關(guān)鍵選擇器(key selector)。選擇器的最后面的部分為關(guān)鍵選擇器(即用來匹配目標(biāo)元素的部分)。CSS選擇符是從右到左進(jìn)行匹配的。當(dāng)使用后代選擇器的時(shí)候,瀏覽器會(huì)遍歷所有子元素來確定是否是指定的元素等等;

(2)如果規(guī)則擁有ID選擇器作為其關(guān)鍵選擇器,則不要為規(guī)則增加標(biāo)簽。過濾掉無關(guān)的規(guī)則(這樣樣式系統(tǒng)就不會(huì)浪費(fèi)時(shí)間去匹配它們了)。

(3)避免使用通配規(guī)則,如*{}計(jì)算次數(shù)驚人,只對需要用到的元素進(jìn)行選擇。

(4)盡量少的去對標(biāo)簽進(jìn)行選擇,而是用class。

(5)盡量少的去使用后代選擇器,降低選擇器的權(quán)重值。后代選擇器的開銷是最高的,盡量將選擇器的深度降到最低,最高不要超過三層,更多的使用類來關(guān)聯(lián)每一個(gè)標(biāo)簽元素。

(6)了解哪些屬性是可以通過繼承而來的,然后避免對這些屬性重復(fù)指定規(guī)則。

渲染性能:

(1)慎重使用高性能屬性:浮動(dòng)、定位。

(2)盡量減少頁面重排、重繪。

(3)去除空規(guī)則:{}??找?guī)則的產(chǎn)生原因一般來說是為了預(yù)留樣式。去除這些空規(guī)則無疑能減少css文檔體積。

(4)屬性值為0時(shí),不加單位。

(5)屬性值為浮動(dòng)小數(shù)0.**,可以省略小數(shù)點(diǎn)之前的0。

(6)標(biāo)準(zhǔn)化各種瀏覽器前綴:帶瀏覽器前綴的在前。標(biāo)準(zhǔn)屬性在后。

(7)不使用@import前綴,它會(huì)影響css的加載速度。

(8)選擇器優(yōu)化嵌套,盡量避免層級過深。

(9)css雪碧圖,同一頁面相近部分的小圖標(biāo),方便使用,減少頁面的請求次數(shù),但是同時(shí)圖片本身會(huì)變大,使用時(shí),優(yōu)劣考慮清楚,再使用。

(10)正確使用display的屬性,由于display的作用,某些樣式組合會(huì)無效,徒增樣式體積的同時(shí)也影響解析性能。

(11)不濫用web字體。對于中文網(wǎng)站來說WebFonts可能很陌生,國外卻很流行。web fonts通常體積龐大,而且一些瀏覽器在下載web fonts時(shí)會(huì)阻塞頁面渲染損傷性能。

可維護(hù)性、健壯性:

(1)將具有相同屬性的樣式抽離出來,整合并通過class在頁面中進(jìn)行使用,提高css的可維護(hù)性。

(2)樣式與內(nèi)容分離:將css代碼定義到外部css中。

22. CSS預(yù)處理器/后處理器是什么?為什么要使用它們?

預(yù)處理器,如:less,sassstylus,用來預(yù)編譯 sass或者 less,增加了 css代碼的復(fù)用性。層級,mixin, 變量,循環(huán), 函數(shù)等對編寫以及開發(fā)UI組件都極為方便。

后處理器, 如: postCss,通常是在完成的樣式表中根據(jù) css規(guī)范處理 css,讓其更加有效。目前最常做的是給 css屬性添加瀏覽器私有前綴,實(shí)現(xiàn)跨瀏覽器兼容性的問題。

css預(yù)處理器為 css增加一些編程特性,無需考慮瀏覽器的兼容問題,可以在 CSS中使用變量,簡單的邏輯程序,函數(shù)等在編程語言中的一些基本的性能,可以讓 css更加的簡潔,增加適應(yīng)性以及可讀性,可維護(hù)性等。

其它 css預(yù)處理器語言:Sass(Scss)LessStylusTurbineSwithch cssCSS CacheerDT Css。

使用原因:

  • 結(jié)構(gòu)清晰, 便于擴(kuò)展
  • 可以很方便的屏蔽瀏覽器私有語法的差異
  • 可以輕松實(shí)現(xiàn)多重繼承
  • 完美的兼容了 ?CSS?代碼,可以應(yīng)用到老項(xiàng)目中

23. ::before 和 :after 的雙冒號和單冒號有什么區(qū)別?

(1)冒號(:)用于 CSS3偽類,雙冒號(::)用于 CSS3偽元素。

(2)::before就是以一個(gè)子元素的存在,定義在元素主體內(nèi)容之前的一個(gè)偽元素。并不存在于 dom之中,只存在在頁面之中。

注意: :before 和 :after 這兩個(gè)偽元素,是在 CSS2.1里新出現(xiàn)的。起初,偽元素的前綴使用的是單冒號語法,但隨著 Web的進(jìn)化,在 CSS3的規(guī)范里,偽元素的語法被修改成使用雙冒號,成為 ::before、::after。

24. display:inline-block 什么時(shí)候會(huì)顯示間隙?

  • 有空格時(shí)會(huì)有間隙,可以刪除空格解決;
  • ?margin?正值時(shí),可以讓 ?margin?使用負(fù)值解決;
  • 使用 ?font-size?時(shí),可通過設(shè)置 ?font-size:0?、?letter-spacing?、?word-spacing?解決;

25. 單行、多行文本溢出隱藏

  • 單行文本溢出
overflow: hidden;            // 溢出隱藏
text-overflow: ellipsis;      // 溢出用省略號顯示
white-space: nowrap;         // 規(guī)定段落中的文本不進(jìn)行換行
  • 多行文本溢出
overflow: hidden;            // 溢出隱藏
text-overflow: ellipsis;     // 溢出用省略號顯示
display:-webkit-box;         // 作為彈性伸縮盒子模型顯示。
-webkit-box-orient:vertical; // 設(shè)置伸縮盒子的子元素排列方式:從上到下垂直排列
-webkit-line-clamp:3;        // 顯示的行數(shù)

注意:由于上面的三個(gè)屬性都是 CSS3 的屬性,沒有瀏覽器可以兼容,所以要在前面加一個(gè) -webkit- 來兼容一部分瀏覽器。

26. Sass、Less 是什么?為什么要使用他們?

他們都是 CSS 預(yù)處理器,是 CSS 上的一種抽象層。他們是一種特殊的語法/語言編譯成 CSS。 例如 Less 是一種動(dòng)態(tài)樣式語言,將 CSS 賦予了動(dòng)態(tài)語言的特性,如變量,繼承,運(yùn)算, 函數(shù),LESS 既可以在客戶端上運(yùn)行 (支持 IE 6+, Webkit, Firefox),也可以在服務(wù)端運(yùn)行 (借助 Node.js)。

為什么要使用它們?

  • 結(jié)構(gòu)清晰,便于擴(kuò)展。 可以方便地屏蔽瀏覽器私有語法差異。封裝對瀏覽器語法差異的重復(fù)處理, 減少無意義的機(jī)械勞動(dòng)。
  • 可以輕松實(shí)現(xiàn)多重繼承。 完全兼容 CSS 代碼,可以方便地應(yīng)用到老項(xiàng)目中。LESS 只是在 CSS 語法上做了擴(kuò)展,所以老的 CSS 代碼也可以與 LESS 代碼一同編譯。

27. 對媒體查詢的理解?

媒體查詢由?個(gè)可選的媒體類型和零個(gè)或多個(gè)使?媒體功能的限制了樣式表范圍的表達(dá)式組成,例如寬度、?度和顏?。媒體查詢,添加?CSS3,允許內(nèi)容的呈現(xiàn)針對?個(gè)特定范圍的輸出設(shè)備?進(jìn)?裁剪,?不必改變內(nèi)容本身,適合web??應(yīng)對不同型號的設(shè)備?做出對應(yīng)的響應(yīng)適配。

媒體查詢包含?個(gè)可選的媒體類型和滿?CSS3規(guī)范的條件下,包含零個(gè)或多個(gè)表達(dá)式,這些表達(dá)式描述了媒體特征,最終會(huì)被解析為true或false。如果媒體查詢中指定的媒體類型匹配展示?檔所使?的設(shè)備類型,并且所有的表達(dá)式的值都是true,那么該媒體查詢的結(jié)果為true。那么媒體查詢內(nèi)的樣式將會(huì)?效。

<!-- link元素中的CSS媒體查詢 --> 
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" /> 
<!-- 樣式表中的CSS媒體查詢 --> 
<style> 
@media (max-width: 600px) { 
  .facet_sidebar { 
    display: none; 
  } 
}
</style>

簡單來說,使用 @media 查詢,可以針對不同的媒體類型定義不同的樣式。@media 可以針對不同的屏幕尺寸設(shè)置不同的樣式,特別是需要設(shè)置設(shè)計(jì)響應(yīng)式的頁面,@media 是非常有用的。當(dāng)重置瀏覽器大小的過程中,頁面也會(huì)根據(jù)瀏覽器的寬度和高度重新渲染頁面。

28. 對 CSS 工程化的理解

CSS 工程化是為了解決以下問題:

  1. 宏觀設(shè)計(jì):CSS 代碼如何組織、如何拆分、模塊結(jié)構(gòu)怎樣設(shè)計(jì)?
  2. 編碼優(yōu)化:怎樣寫出更好的 CSS?
  3. 構(gòu)建:如何處理我的 CSS,才能讓它的打包結(jié)果最優(yōu)?
  4. 可維護(hù)性:代碼寫完了,如何最小化它后續(xù)的變更成本?如何確保任何一個(gè)同事都能輕松接手?

以下三個(gè)方向都是時(shí)下比較流行的、普適性非常好的 CSS 工程化實(shí)踐:

  • 預(yù)處理器:Less、 Sass 等;
  • 重要的工程化插件: PostCss;
  • Webpack loader 等 。

基于這三個(gè)方向,可以衍生出一些具有典型意義的子問題,這里我們逐個(gè)來看:

(1)預(yù)處理器:為什么要用預(yù)處理器?它的出現(xiàn)是為了解決什么問題?

預(yù)處理器,其實(shí)就是 CSS 世界的“輪子”。預(yù)處理器支持我們寫一種類似 CSS、但實(shí)際并不是 CSS 的語言,然后把它編譯成 CSS 代碼:


那為什么寫 CSS 代碼寫得好好的,偏偏要轉(zhuǎn)去寫“類 CSS”呢?這就和本來用 JS 也可以實(shí)現(xiàn)所有功能,但最后卻寫 React 的 jsx 或者 Vue 的模板語法一樣——為了爽!要想知道有了預(yù)處理器有多爽,首先要知道的是傳統(tǒng) CSS 有多不爽。隨著前端業(yè)務(wù)復(fù)雜度的提高,前端工程中對 CSS 提出了以下的訴求:

  1. 宏觀設(shè)計(jì)上:我們希望能優(yōu)化 CSS 文件的目錄結(jié)構(gòu),對現(xiàn)有的 CSS 文件實(shí)現(xiàn)復(fù)用;
  2. 編碼優(yōu)化上:我們希望能寫出結(jié)構(gòu)清晰、簡明易懂的 CSS,需要它具有一目了然的嵌套層級關(guān)系,而不是無差別的一鋪到底寫法;我們希望它具有變量特征、計(jì)算能力、循環(huán)能力等等更強(qiáng)的可編程性,這樣我們可以少寫一些無用的代碼;
  3. 可維護(hù)性上:更強(qiáng)的可編程性意味著更優(yōu)質(zhì)的代碼結(jié)構(gòu),實(shí)現(xiàn)復(fù)用意味著更簡單的目錄結(jié)構(gòu)和更強(qiáng)的拓展能力,這兩點(diǎn)如果能做到,自然會(huì)帶來更強(qiáng)的可維護(hù)性。

這三點(diǎn)是傳統(tǒng) CSS 所做不到的,也正是預(yù)處理器所解決掉的問題。預(yù)處理器普遍會(huì)具備這樣的特性:

  • 嵌套代碼的能力,通過嵌套來反映不同 css 屬性之間的層級關(guān)系 ;
  • 支持定義 css 變量;
  • 提供計(jì)算函數(shù);
  • 允許對代碼片段進(jìn)行 extend 和 mixin;
  • 支持循環(huán)語句的使用;
  • 支持將 CSS 文件模塊化,實(shí)現(xiàn)復(fù)用。

(2)PostCss:PostCss 是如何工作的?我們在什么場景下會(huì)使用 PostCss?

PostCss 仍然是一個(gè)對 CSS 進(jìn)行解析和處理的工具,它會(huì)對 CSS 做這樣的事情:

img

它和預(yù)處理器的不同就在于,預(yù)處理器處理的是 類CSS,而 PostCss 處理的就是 CSS 本身。Babel 可以將高版本的 JS 代碼轉(zhuǎn)換為低版本的 JS 代碼。PostCss 做的是類似的事情:它可以編譯尚未被瀏覽器廣泛支持的先進(jìn)的 CSS 語法,還可以自動(dòng)為一些需要額外兼容的語法增加前綴。更強(qiáng)的是,由于 PostCss 有著強(qiáng)大的插件機(jī)制,支持各種各樣的擴(kuò)展,極大地強(qiáng)化了 CSS 的能力。

PostCss 在業(yè)務(wù)中的使用場景非常多:

  • 提高 CSS 代碼的可讀性:PostCss 其實(shí)可以做類似預(yù)處理器能做的工作;
  • 當(dāng)我們的 CSS 代碼需要適配低版本瀏覽器時(shí),PostCss 的 Autoprefixer 插件可以幫助我們自動(dòng)增加瀏覽器前綴;
  • 允許我們編寫面向未來的 CSS:PostCss 能夠幫助我們編譯 CSS next 代碼;

(3)Webpack 能處理 CSS 嗎?如何實(shí)現(xiàn)?

Webpack 能處理 CSS 嗎:

  • Webpack 在裸奔的狀態(tài)下,是不能處理 CSS 的,Webpack 本身是一個(gè)面向 JavaScript 且只能處理 JavaScript 代碼的模塊化打包工具;
  • Webpack 在 loader 的輔助下,是可以處理 CSS 的。

如何用 Webpack 實(shí)現(xiàn)對 CSS 的處理:

  • Webpack 中操作 CSS 需要使用的兩個(gè)關(guān)鍵的 loader:css-loader 和 style-loader
  • 注意,答出“用什么”有時(shí)候可能還不夠,面試官會(huì)懷疑你是不是在背答案,所以你還需要了解每個(gè) loader 都做了什么事情:
    • css-loader:導(dǎo)入 CSS 模塊,對 CSS 代碼進(jìn)行編譯處理;
    • style-loader:創(chuàng)建style標(biāo)簽,把 CSS 內(nèi)容寫入標(biāo)簽。

在實(shí)際使用中,css-loader 的執(zhí)行順序一定要安排在 style-loader 的前面。因?yàn)橹挥型瓿闪司幾g過程,才可以對 css 代碼進(jìn)行插入;若提前插入了未編譯的代碼,那么 webpack 是無法理解這坨東西的,它會(huì)無情報(bào)錯(cuò)。

29. 如何判斷元素是否到達(dá)可視區(qū)域

以圖片顯示為例:

  • ?window.innerHeight? 是瀏覽器可視區(qū)的高度;
  • ?document.body.scrollTop || document.documentElement.scrollTop? 是瀏覽器滾動(dòng)的過的距離;
  • ?imgs.offsetTop? 是元素頂部距離文檔頂部的高度(包括滾動(dòng)條的距離);
  • 內(nèi)容達(dá)到顯示區(qū)域的:?img.offsetTop < window.innerHeight + document.body.scrollTop;?

img

30. z-index屬性在什么情況下會(huì)失效

通常 z-index 的使用是在有兩個(gè)重疊的標(biāo)簽,在一定的情況下控制其中一個(gè)在另一個(gè)的上方或者下方出現(xiàn)。z-index值越大就越是在上層。z-index元素的position屬性需要是relative,absolute或是fixed。

z-index屬性在下列情況下會(huì)失效:

  • 父元素position為relative時(shí),子元素的z-index失效。解決:父元素position改為absolute或static;
  • 元素沒有設(shè)置position屬性為非static屬性。解決:設(shè)置該元素的position屬性為relative,absolute或是fixed中的一種;
  • 元素在設(shè)置z-index的同時(shí)還設(shè)置了float浮動(dòng)。解決:float去除,改為display:inline-block;

二、頁面布局


1. 常見的CSS布局單位

首先將獲得1px 與 vw之前的比例關(guān)系 再將html標(biāo)簽中的font-size定義為多少vw 然后就使用rem來作為單位 常用的布局單位包括像素(px),百分比(%),emrem,vw/vh。

(1)像素px)是頁面布局的基礎(chǔ),一個(gè)像素表示終端(電腦、手機(jī)、平板等)屏幕所能顯示的最小的區(qū)域,像素分為兩種類型:CSS像素和物理像素:

  • CSS像素:為web開發(fā)者提供,在CSS中使用的一個(gè)抽象單位;
  • 物理像素:只與設(shè)備的硬件密度有關(guān),任何設(shè)備的物理像素都是固定的。

(2)百分比%),當(dāng)瀏覽器的寬度或者高度發(fā)生變化時(shí),通過百分比單位可以使得瀏覽器中的組件的寬和高隨著瀏覽器的變化而變化,從而實(shí)現(xiàn)響應(yīng)式的效果。一般認(rèn)為子元素的百分比相對于直接父元素。

(3)em和rem相對于px更具靈活性,它們都是相對長度單位,它們之間的區(qū)別:em相對于父元素,rem相對于根元素。

  • em: 文本相對長度單位。相對于當(dāng)前對象內(nèi)文本的字體尺寸。如果當(dāng)前行內(nèi)文本的字體尺寸未被人為設(shè)置,則相對于瀏覽器的默認(rèn)字體尺寸(默認(rèn)16px)。(相對父元素的字體大小倍數(shù))。
  • rem: rem是CSS3新增的一個(gè)相對單位,相對于根元素(html元素)的font-size的倍數(shù)。作用:利用rem可以實(shí)現(xiàn)簡單的響應(yīng)式布局,可以利用html元素中字體的大小與屏幕間的比值來設(shè)置font-size的值,以此實(shí)現(xiàn)當(dāng)屏幕分辨率變化時(shí)讓元素也隨之變化。

(4)vw/vh是與視圖窗口有關(guān)的單位,vw表示相對于視圖窗口的寬度,vh表示相對于視圖窗口高度,除了vw和vh外,還有vmin和vmax兩個(gè)相關(guān)的單位。

  • vw:相對于視窗的寬度,視窗寬度是100vw;
  • vh:相對于視窗的高度,視窗高度是100vh;
  • vmin:vw和vh中的較小值;
  • vmax:vw和vh中的較大值;

vw/vh 和百分比很類似,兩者的區(qū)別:

  • 百分比(?%?):大部分相對于祖先元素,也有相對于自身的情況比如(border-radius、translate等)
  • vw/vm:相對于視窗的尺寸

2. px、em、rem的區(qū)別及使用場景

三者的區(qū)別:

  • px是固定的像素,一旦設(shè)置了就無法因?yàn)檫m應(yīng)頁面大小而改變。
  • em和rem相對于px更具有靈活性,他們是相對長度單位,其長度不是固定的,更適用于響應(yīng)式布局。
  • em是相對于其父元素來設(shè)置字體大小,這樣就會(huì)存在一個(gè)問題,進(jìn)行任何元素設(shè)置,都有可能需要知道他父元素的大小。而rem是相對于根元素,這樣就意味著,只需要在根元素確定一個(gè)參考值。

使用場景:

  • 對于只需要適配少部分移動(dòng)設(shè)備,且分辨率對頁面影響不大的,使用px即可 。
  • 對于需要適配各種移動(dòng)設(shè)備,使用rem,例如需要適配iPhone和iPad等分辨率差別比較挺大的設(shè)備。

3. 兩欄布局的實(shí)現(xiàn)

一般兩欄布局指的是左邊一欄寬度固定,右邊一欄寬度自適應(yīng),兩欄布局的具體實(shí)現(xiàn):

  • 利用浮動(dòng),將左邊元素寬度設(shè)置為200px,并且設(shè)置向左浮動(dòng)。將右邊元素的margin-left設(shè)置為200px,寬度設(shè)置為auto(默認(rèn)為auto,撐滿整個(gè)父元素)。
.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  background: tomato;
}
.right {
  margin-left: 200px;
  width: auto;
  background: gold;
}
  • 利用浮動(dòng),左側(cè)元素設(shè)置固定大小,并左浮動(dòng),右側(cè)元素設(shè)置overflow: hidden; 這樣右邊就觸發(fā)了BFC,BFC的區(qū)域不會(huì)與浮動(dòng)元素發(fā)生重疊,所以兩側(cè)就不會(huì)發(fā)生重疊。
.left{
     width: 100px;
     height: 200px;
     background: red;
     float: left;
 }
 .right{
     height: 300px;
     background: blue;
     overflow: hidden;
 }
  • 利用flex布局,將左邊元素設(shè)置為固定寬度200px,將右邊的元素設(shè)置為flex:1。
.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  background: tomato;
}
.right {
  flex: 1;
  background: gold;
}
  • 利用絕對定位,將父級元素設(shè)置為相對定位。左邊元素設(shè)置為absolute定位,并且寬度設(shè)置為200px。將右邊元素的margin-left的值設(shè)置為200px。
.outer {
  position: relative;
  height: 100px;
}
.left {
  position: absolute;
  width: 200px;
  height: 100px;
  background: tomato;
}
.right {
  margin-left: 200px;
  background: gold;
}
  • 利用絕對定位,將父級元素設(shè)置為相對定位。左邊元素寬度設(shè)置為200px,右邊元素設(shè)置為絕對定位,左邊定位為200px,其余方向定位為0。
.outer {
  position: relative;
  height: 100px;
}
.left {
  width: 200px;
  background: tomato;
}
.right {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 200px;
  background: gold;
}

4. 三欄布局的實(shí)現(xiàn)

三欄布局一般指的是頁面中一共有三欄,左右兩欄寬度固定,中間自適應(yīng)的布局,三欄布局的具體實(shí)現(xiàn):

  • 利用絕對定位,左右兩欄設(shè)置為絕對定位,中間設(shè)置對應(yīng)方向大小的margin的值。
.outer {
  position: relative;
  height: 100px;
}

.left {
  position: absolute;
  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  position: absolute;
  top: 0;
  right: 0;
  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  margin-left: 100px;
  margin-right: 200px;
  height: 100px;
  background: lightgreen;
}
  • 利用flex布局,左右兩欄設(shè)置固定大小,中間一欄設(shè)置為flex:1。
.outer {
  display: flex;
  height: 100px;
}

.left {
  width: 100px;
  background: tomato;
}

.right {
  width: 100px;
  background: gold;
}

.center {
  flex: 1;
  background: lightgreen;
}
  • 利用浮動(dòng),左右兩欄設(shè)置固定大小,并設(shè)置對應(yīng)方向的浮動(dòng)。中間一欄設(shè)置左右兩個(gè)方向的margin值,注意這種方式,中間一欄必須放到最后:
.outer {
  height: 100px;
}

.left {
  float: left;
  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: right;
  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  height: 100px;
  margin-left: 100px;
  margin-right: 200px;
  background: lightgreen;
}
  • 圣杯布局,利用浮動(dòng)和負(fù)邊距來實(shí)現(xiàn)。父級元素設(shè)置左右的 padding,三列均設(shè)置向左浮動(dòng),中間一列放在最前面,寬度設(shè)置為父級元素的寬度,因此后面兩列都被擠到了下一行,通過設(shè)置 margin 負(fù)值將其移動(dòng)到上一行,再利用相對定位,定位到兩邊。
.outer {
  height: 100px;
  padding-left: 100px;
  padding-right: 200px;
}

.left {
  position: relative;
  left: -100px;

  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  position: relative;
  left: 200px;

  float: right;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}
  • 雙飛翼布局,雙飛翼布局相對于圣杯布局來說,左右位置的保留是通過中間列的 margin 值來實(shí)現(xiàn)的,而不是通過父元素的 padding 來實(shí)現(xiàn)的。本質(zhì)上來說,也是通過浮動(dòng)和外邊距負(fù)值來實(shí)現(xiàn)的。
.outer {
  height: 100px;
}

.left {
  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: left;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.wrapper {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}

.center {
  margin-left: 100px;
  margin-right: 200px;
  height: 100px;
}

水平垂直居中的實(shí)現(xiàn)

  • 利用絕對定位,先將元素的左上角通過top:50%和left:50%定位到頁面的中心,然后再通過translate來調(diào)整元素的中心點(diǎn)到頁面的中心。該方法需要考慮瀏覽器兼容問題。
.parent {
    position: relative;
}
 
.child {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}
  • 利用絕對定位,設(shè)置四個(gè)方向的值都為0,并將margin設(shè)置為auto,由于寬高固定,因此對應(yīng)方向?qū)崿F(xiàn)平分,可以實(shí)現(xiàn)水平和垂直方向上的居中。該方法適用于盒子有寬高的情況:
.parent {
    position: relative;
}
 
.child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
  • 利用絕對定位,先將元素的左上角通過top:50%和left:50%定位到頁面的中心,然后再通過margin負(fù)值來調(diào)整元素的中心點(diǎn)到頁面的中心。該方法適用于盒子寬高已知的情況
.parent {
    position: relative;
}
 
.child {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;     /* 自身 height 的一半 */
    margin-left: -50px;    /* 自身 width 的一半 */
}
  • 使用flex布局,通過align-items:center和justify-content:center設(shè)置容器的垂直和水平方向上為居中對齊,然后它的子元素也可以實(shí)現(xiàn)垂直和水平的居中。該方法要考慮兼容的問題,該方法在移動(dòng)端用的較多:
.parent {
    display: flex;
    justify-content:center;
    align-items:center;
}

6. 如何根據(jù)設(shè)計(jì)稿進(jìn)行移動(dòng)端適配?

移動(dòng)端適配主要有兩個(gè)維度:

  • 適配不同像素密度,針對不同的像素密度,使用 CSS 媒體查詢,選擇不同精度的圖片,以保證圖片不會(huì)失真;
  • 適配不同屏幕大小,由于不同的屏幕有著不同的邏輯像素大小,所以如果直接使用 px 作為開發(fā)單位,會(huì)使得開發(fā)的頁面在某一款手機(jī)上可以準(zhǔn)確顯示,但是在另一款手機(jī)上就會(huì)失真。為了適配不同屏幕的大小,應(yīng)按照比例來還原設(shè)計(jì)稿的內(nèi)容。

為了能讓頁面的尺寸自適應(yīng),可以使用 rem,em,vw,vh 等相對單位。

7. 對Flex布局的理解及其使用場景

Flex是FlexibleBox的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。任何一個(gè)容器都可以指定為Flex布局。行內(nèi)元素也可以使用Flex布局。注意,設(shè)為Flex布局以后,子元素的float、clear和vertical-align屬性將失效。采用Flex布局的元素,稱為Flex容器(flex container),簡稱"容器"。它的所有子元素自動(dòng)成為容器成員,稱為Flex項(xiàng)目(flex item),簡稱"項(xiàng)目"。容器默認(rèn)存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis),項(xiàng)目默認(rèn)沿水平主軸排列。

以下6個(gè)屬性設(shè)置在容器上

  • flex-direction屬性決定主軸的方向(即項(xiàng)目的排列方向)。
  • flex-wrap屬性定義,如果一條軸線排不下,如何換行。
  • flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,默認(rèn)值為row nowrap。
  • justify-content屬性定義了項(xiàng)目在主軸上的對齊方式。
  • align-items屬性定義項(xiàng)目在交叉軸上如何對齊。
  • align-content屬性定義了多根軸線的對齊方式。如果項(xiàng)目只有一根軸線,該屬性不起作用。

以下6個(gè)屬性設(shè)置在項(xiàng)目上

  • order屬性定義項(xiàng)目的排列順序。數(shù)值越小,排列越靠前,默認(rèn)為0。
  • flex-grow屬性定義項(xiàng)目的放大比例,默認(rèn)為0,即如果存在剩余空間,也不放大。
  • flex-shrink屬性定義了項(xiàng)目的縮小比例,默認(rèn)為1,即如果空間不足,該項(xiàng)目將縮小。
  • flex-basis屬性定義了在分配多余空間之前,項(xiàng)目占據(jù)的主軸空間。瀏覽器根據(jù)這個(gè)屬性,計(jì)算主軸是否有多余空間。它的默認(rèn)值為auto,即項(xiàng)目的本來大小。
  • flex屬性是flex-grow,flex-shrink和flex-basis的簡寫,默認(rèn)值為0 1 auto。
  • align-self屬性允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對齊方式,可覆蓋align-items屬性。默認(rèn)值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同于stretch。

簡單來說:

flex布局是CSS3新增的一種布局方式,可以通過將一個(gè)元素的display屬性值設(shè)置為flex從而使它成為一個(gè)flex容器,它的所有子元素都會(huì)成為它的項(xiàng)目。一個(gè)容器默認(rèn)有兩條軸:一個(gè)是水平的主軸,一個(gè)是與主軸垂直的交叉軸??梢允褂胒lex-direction來指定主軸的方向??梢允褂胘ustify-content來指定元素在主軸上的排列方式,使用align-items來指定元素在交叉軸上的排列方式。還可以使用flex-wrap來規(guī)定當(dāng)一行排列不下時(shí)的換行方式。對于容器中的項(xiàng)目,可以使用order屬性來指定項(xiàng)目的排列順序,還可以使用flex-grow來指定當(dāng)排列空間有剩余的時(shí)候,項(xiàng)目的放大比例,還可以使用flex-shrink來指定當(dāng)排列空間不足時(shí),項(xiàng)目的縮小比例。

8. 響應(yīng)式設(shè)計(jì)的概念及基本原理

響應(yīng)式網(wǎng)站設(shè)計(jì) (Responsive Web design)是一個(gè)網(wǎng)站能夠兼容多個(gè)終端,而不是為每一個(gè)終端做一個(gè)特定的版本。

關(guān)于原理: 基本原理是通過媒體查詢 (@media)查詢檢測不同的設(shè)備屏幕尺寸做處理。

關(guān)于兼容: 頁面頭部必須有mate聲明的 viewport。

<meta name="’viewport’" content="”width=device-width," initial-scale="1." maximum-scale="1,user-scalable=no”"/>

三、定位與浮動(dòng)


1. 為什么需要清除浮動(dòng)?清除浮動(dòng)的方式

浮動(dòng)的定義: 非IE瀏覽器下,容器不設(shè)高度且子元素浮動(dòng)時(shí),容器高度不能被內(nèi)容撐開。 此時(shí),內(nèi)容會(huì)溢出到容器外面而影響布局。這種現(xiàn)象被稱為浮動(dòng)(溢出)。

浮動(dòng)的工作原理:

  • 浮動(dòng)元素脫離文檔流,不占據(jù)空間(引起“高度塌陷”現(xiàn)象)
  • 浮動(dòng)元素碰到包含它的邊框或者其他浮動(dòng)元素的邊框停留

浮動(dòng)元素可以左右移動(dòng),直到遇到另一個(gè)浮動(dòng)元素或者遇到它外邊緣的包含框。浮動(dòng)框不屬于文檔流中的普通流,當(dāng)元素浮動(dòng)之后,不會(huì)影響塊級元素的布局,只會(huì)影響內(nèi)聯(lián)元素布局。此時(shí)文檔流中的普通流就會(huì)表現(xiàn)得該浮動(dòng)框不存在一樣的布局模式。當(dāng)包含框的高度小于浮動(dòng)框的時(shí)候,此時(shí)就會(huì)出現(xiàn)“高度塌陷”。

浮動(dòng)元素引起的問題?

  • 父元素的高度無法被撐開,影響與父元素同級的元素
  • 與浮動(dòng)元素同級的非浮動(dòng)元素會(huì)跟隨其后
  • 若浮動(dòng)的元素不是第一個(gè)元素,則該元素之前的元素也要浮動(dòng),否則會(huì)影響頁面的顯示結(jié)構(gòu)

清除浮動(dòng)的方式如下:

  • 給父級div定義 ?height?屬性
  • 最后一個(gè)浮動(dòng)元素之后添加一個(gè)空的div標(biāo)簽,并添加 ?clear:both?樣式
  • 包含浮動(dòng)元素的父級標(biāo)簽添加 ?overflow:hidden?或者 ?overflow:auto ?
  • 使用 :after 偽元素。由于IE6-7不支持 :after,使用 zoom:1 觸發(fā) hasLayout
.clearfix:after{
    content: "\200B";
    display: table; 
    height: 0;
    clear: both;
  }
  .clearfix{
    *zoom: 1;
  }

2. 使用 clear 屬性清除浮動(dòng)的原理?

使用clear屬性清除浮動(dòng),其語法如下:

clear:none|left|right|both

如果單看字面意思,clear:left 是“清除左浮動(dòng)”,clear:right 是“清除右浮動(dòng)”,實(shí)際上,這種解釋是有問題的,因?yàn)楦?dòng)一直還在,并沒有清除。

官方對clear屬性解釋:“元素盒子的邊不能和前面的浮動(dòng)元素相鄰”,對元素設(shè)置clear屬性是為了避免浮動(dòng)元素對該元素的影響,而不是清除掉浮動(dòng)。

還需要注意 clear 屬性指的是元素盒子的邊不能和前面的浮動(dòng)元素相鄰,注意這里“前面的”3個(gè)字,也就是clear屬性對“后面的”浮動(dòng)元素是不聞不問的??紤]到float屬性要么是left,要么是right,不可能同時(shí)存在,同時(shí)由于clear屬性對“后面的”浮動(dòng)元素不聞不問,因此,當(dāng)clear:left有效的時(shí)候,clear:right必定無效,也就是此時(shí)clear:left等同于設(shè)置clear:both;同樣地,clear:right如果有效也是等同于設(shè)置clear:both。由此可見,clear:left和clear:right這兩個(gè)聲明就沒有任何使用的價(jià)值,至少在CSS世界中是如此,直接使用clear:both吧。

一般使用偽元素的方式清除浮動(dòng):

.clear::after{
  content:'';
  display: block; 
  clear:both;
}

clear屬性只有塊級元素才有效的,而::after等偽元素默認(rèn)都是內(nèi)聯(lián)水平,這就是借助偽元素清除浮動(dòng)影響時(shí)需要設(shè)置display屬性值的原因。

3. 對BFC的理解,如何創(chuàng)建BFC

先來看兩個(gè)相關(guān)的概念:

  • Box: Box 是 CSS 布局的對象和基本單位,?個(gè)??是由很多個(gè) Box 組成的,這個(gè)Box就是我們所說的盒模型。
  • Formatting context:塊級上下?格式化,它是??中的?塊渲染區(qū)域,并且有?套渲染規(guī)則,它決定了其?元素將如何定位,以及和其他元素的關(guān)系和相互作?。

塊格式化上下文(Block Formatting Context,BFC)是Web頁面的可視化CSS渲染的一部分,是布局過程中生成塊級盒子的區(qū)域,也是浮動(dòng)元素與其他元素的交互限定區(qū)域。

通俗來講:BFC是一個(gè)獨(dú)立的布局環(huán)境,可以理解為一個(gè)容器,在這個(gè)容器中按照一定規(guī)則進(jìn)行物品擺放,并且不會(huì)影響其它環(huán)境中的物品。如果一個(gè)元素符合觸發(fā)BFC的條件,則BFC中的元素布局不受外部影響。

創(chuàng)建BFC的條件:

  • 根元素:body;
  • 元素設(shè)置浮動(dòng):float 除 none 以外的值;
  • 元素設(shè)置絕對定位:position (absolute、fixed);
  • display 值為:inline-block、table-cell、table-caption、flex等;
  • overflow 值為:hidden、auto、scroll;

BFC的特點(diǎn):

  • 垂直方向上,自上而下排列,和文檔流的排列方式一致。
  • 在BFC中上下相鄰的兩個(gè)容器的margin會(huì)重疊
  • 計(jì)算BFC的高度時(shí),需要計(jì)算浮動(dòng)元素的高度
  • BFC區(qū)域不會(huì)與浮動(dòng)的容器發(fā)生重疊
  • BFC是獨(dú)立的容器,容器內(nèi)部元素不會(huì)影響外部元素
  • 每個(gè)元素的左margin值和容器的左border相接觸

BFC的作用:

  • 解決margin的重疊問題:由于BFC是一個(gè)獨(dú)立的區(qū)域,內(nèi)部的元素和外部的元素互不影響,將兩個(gè)元素變?yōu)閮蓚€(gè)BFC,就解決了margin重疊的問題。
  • 解決高度塌陷的問題:在對子元素設(shè)置浮動(dòng)后,父元素會(huì)發(fā)生高度塌陷,也就是父元素的高度變?yōu)?。解決這個(gè)問題,只需要把父元素變成一個(gè)BFC。常用的辦法是給父元素設(shè)置 ?overflow:hidden?。
  • 創(chuàng)建自適應(yīng)兩欄布局:可以用來創(chuàng)建自適應(yīng)兩欄布局:左邊的寬度固定,右邊的寬度自適應(yīng)。
.left{
     width: 100px;
     height: 200px;
     background: red;
     float: left;
 }
 .right{
     height: 300px;
     background: blue;
     overflow: hidden;
 }
 
<div class="left"></div>
<div class="right"></div>

左側(cè)設(shè)置 float:left,右側(cè)設(shè)置 overflow: hidden。這樣右邊就觸發(fā)了BFC,BFC的區(qū)域不會(huì)與浮動(dòng)元素發(fā)生重疊,所以兩側(cè)就不會(huì)發(fā)生重疊,實(shí)現(xiàn)了自適應(yīng)兩欄布局。

4. 什么是margin重疊問題?如何解決?

問題描述:

兩個(gè)塊級元素的上外邊距和下外邊距可能會(huì)合并(折疊)為一個(gè)外邊距,其大小會(huì)取其中外邊距值大的那個(gè),這種行為就是外邊距折疊。需要注意的是,浮動(dòng)的元素和絕對定位這種脫離文檔流的元素的外邊距不會(huì)折疊。重疊只會(huì)出現(xiàn)在垂直方向。

計(jì)算原則:

折疊合并后外邊距的計(jì)算原則如下:

  • 如果兩者都是正數(shù),那么就去最大者
  • 如果是一正一負(fù),就會(huì)正值減去負(fù)值的絕對值
  • 兩個(gè)都是負(fù)值時(shí),用0減去兩個(gè)中絕對值大的那個(gè)

解決辦法:

對于折疊的情況,主要有兩種:兄弟之間重疊父子之間重疊

(1)兄弟之間重疊

  • 底部元素變?yōu)樾袃?nèi)盒子:?display: inline-block?
  • 底部元素設(shè)置浮動(dòng):?float?
  • 底部元素的position的值為 ?absolute/fixed?

(2)父子之間重疊

  • 父元素加入:?overflow: hidden?
  • 父元素添加透明邊框:?border:1px solid transparent?
  • 子元素變?yōu)樾袃?nèi)盒子:?display: inline-block?
  • 子元素加入浮動(dòng)屬性或定位

5. 元素的層疊順序

層疊順序,英文稱作 stacking order,表示元素發(fā)生層疊時(shí)有著特定的垂直顯示順序。下面是盒模型的層疊規(guī)則:

img

對于上圖,由上到下分別是:

(1)背景和邊框:建立當(dāng)前層疊上下文元素的背景和邊框。

(2)負(fù)的z-index:當(dāng)前層疊上下文中,z-index屬性值為負(fù)的元素。

(3)塊級盒:文檔流內(nèi)非行內(nèi)級非定位后代元素。

(4)浮動(dòng)盒:非定位浮動(dòng)元素。

(5)行內(nèi)盒:文檔流內(nèi)行內(nèi)級非定位后代元素。

(6)z-index:0:層疊級數(shù)為0的定位元素。

(7)正z-index:z-index屬性值為正的定位元素。

注意: 當(dāng)定位元素z-index:auto,生成盒在當(dāng)前層疊上下文中的層級為 0,不會(huì)建立新的層疊上下文,除非是根元素。

6. position的屬性有哪些,區(qū)別是什么

position有以下屬性值:

屬性值 概述
absolute 生成絕對定位的元素,相對于static定位以外的一個(gè)父元素進(jìn)行定位。元素的位置通過left、top、right、bottom屬性進(jìn)行規(guī)定。
relative 生成相對定位的元素,相對于其原來的位置進(jìn)行定位。元素的位置通過left、top、right、bottom屬性進(jìn)行規(guī)定。
fixed 生成絕對定位的元素,指定元素相對于屏幕視?(viewport)的位置來指定元素位置。元素的位置在屏幕滾動(dòng)時(shí)不會(huì)改變,?如回到頂部的按鈕?般都是?此定位?式。
static 默認(rèn)值,沒有定位,元素出現(xiàn)在正常的文檔流中,會(huì)忽略 top, bottom, left, right 或者 z-index 聲明,塊級元素從上往下縱向排布,?級元素從左向右排列。
inherit 規(guī)定從父元素繼承position屬性的值

前面三者的定位方式如下:

relative:元素的定位永遠(yuǎn)是相對于元素自身位置的,和其他元素沒關(guān)系,也不會(huì)影響其他元素。

img

fixed:元素的定位是相對于 window (或者 iframe)邊界的,和其他元素沒有關(guān)系。但是它具有破壞性,會(huì)導(dǎo)致其他元素位置的變化。

img

absolute:元素的定位相對于前兩者要復(fù)雜許多。如果為 absolute 設(shè)置了 top、left,瀏覽器會(huì)根據(jù)什么去確定它的縱向和橫向的偏移量呢?答案是瀏覽器會(huì)遞歸查找該元素的所有父元素,如果找到一個(gè)設(shè)置了 position:relative/absolute/fixed的元素,就以該元素為基準(zhǔn)定位,如果沒找到,就以瀏覽器邊界定位。如下兩個(gè)圖所示:

img

img

7. display、float、position的關(guān)系

(1)首先判斷display屬性是否為none,如果為none,則position和float屬性的值不影響元素最后的表現(xiàn)。

(2)然后判斷position的值是否為absolute或者fixed,如果是,則float屬性失效,并且display的值應(yīng)該被設(shè)置為table或者block,具體轉(zhuǎn)換需要看初始轉(zhuǎn)換值。

(3)如果position的值不為absolute或者fixed,則判斷float屬性的值是否為none,如果不是,則display的值則按上面的規(guī)則轉(zhuǎn)換。注意,如果position的值為relative并且float屬性的值存在,則relative相對于浮動(dòng)后的最終位置定位。

(4)如果float的值為none,則判斷元素是否為根元素,如果是根元素則display屬性按照上面的規(guī)則轉(zhuǎn)換,如果不是,則保持指定的display屬性值不變。

總的來說,可以把它看作是一個(gè)類似優(yōu)先級的機(jī)制,"position:absolute"和"position:fixed"優(yōu)先級最高,有它存在的時(shí)候,浮動(dòng)不起作用,'display'的值也需要調(diào)整;其次,元素的'float'特性的值不是"none"的時(shí)候或者它是根元素的時(shí)候,調(diào)整'display'的值;最后,非根元素,并且非浮動(dòng)元素,并且非絕對定位的元素,'display'特性值同設(shè)置值。

8. absolute與fixed共同點(diǎn)與不同點(diǎn)

共同點(diǎn):

  • 改變行內(nèi)元素的呈現(xiàn)方式,將display置為inline-block
  • 使元素脫離普通文檔流,不再占據(jù)文檔物理空間
  • 覆蓋非定位文檔元素

不同點(diǎn):

  • abuselute與fixed的根元素不同,abuselute的根元素可以設(shè)置,fixed根元素是瀏覽器。
  • 在有滾動(dòng)條的頁面中,absolute會(huì)跟著父元素進(jìn)行移動(dòng),fixed固定在頁面的具體位置。

9. 對 sticky 定位的理解

sticky 英文字面意思是粘貼,所以可以把它稱之為粘性定位。語法:position: sticky; 基于用戶的滾動(dòng)位置來定位。

粘性定位的元素是依賴于用戶的滾動(dòng),在 position:relative 與 position:fixed 定位之間切換。它的行為就像 position:relative; 而當(dāng)頁面滾動(dòng)超出目標(biāo)區(qū)域時(shí),它的表現(xiàn)就像 position:fixed;,它會(huì)固定在目標(biāo)位置。元素定位表現(xiàn)為在跨越特定閾值前為相對定位,之后為固定定位。這個(gè)特定閾值指的是 top, right, bottom 或 left 之一,換言之,指定 top, right, bottom 或 left 四個(gè)閾值其中之一,才可使粘性定位生效。否則其行為與相對定位相同。

四、場景應(yīng)用


1. 實(shí)現(xiàn)一個(gè)三角形

CSS繪制三角形主要用到的是border屬性,也就是邊框。

平時(shí)在給盒子設(shè)置邊框時(shí),往往都設(shè)置很窄,就可能誤以為邊框是由矩形組成的。實(shí)際上,border屬性是右三角形組成的,下面看一個(gè)例子:

div {
    width: 0;
    height: 0;
    border: 100px solid;
    border-color: orange blue red green;
}

將元素的長寬都設(shè)置為0,顯示出來的效果是這樣的:

image

所以可以根據(jù)border這個(gè)特性來繪制三角形:

(1)三角1

div {
    width: 0;
    height: 0;
    border-top: 50px solid red;
    border-right: 50px solid transparent;
    border-left: 50px solid transparent;
}

img

(2)三角2

div {
    width: 0;
    height: 0;
    border-bottom: 50px solid red;
    border-right: 50px solid transparent;
    border-left: 50px solid transparent;
}

img

(3)三角3

div {
    width: 0;
    height: 0;
    border-left: 50px solid red;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
}

img

(4)三角4

div {
    width: 0;
    height: 0;
    border-right: 50px solid red;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
}

img

(5)三角5

div {
    width: 0;
    height: 0;
    border-top: 100px solid red;
    border-right: 100px solid transparent;
}

img

還有很多,就不一一實(shí)現(xiàn)了,總體的原則就是通過上下左右邊框來控制三角形的方向,用邊框的寬度比來控制三角形的角度。

2. 實(shí)現(xiàn)一個(gè)扇形

用CSS實(shí)現(xiàn)扇形的思路和三角形基本一致,就是多了一個(gè)圓角的樣式,實(shí)現(xiàn)一個(gè)90°的扇形:

div{
    border: 100px solid transparent;
    width: 0;
    heigt: 0;
    border-radius: 100px;
    border-top-color: red;
}

img

3. 實(shí)現(xiàn)一個(gè)寬高自適應(yīng)的正方形

  • 利用vw來實(shí)現(xiàn):
.square {
  width: 10%;
  height: 10vw;
  background: tomato;
}
  • 利用元素的margin/padding百分比是相對父元素width的性質(zhì)來實(shí)現(xiàn):
.square {
  width: 20%;
  height: 0;
  padding-top: 20%;
  background: orange;
}
  • 利用子元素的margin-top的值來實(shí)現(xiàn):
.square {
  width: 30%;
  overflow: hidden;
  background: yellow;
}
.square::after {
  content: '';
  display: block;
  margin-top: 100%;
}

4. 畫一條0.5px的線

  • 采用transform: scale()的方式,該方法用來定義元素的2D 縮放轉(zhuǎn)換:
transform: scale(0.5,0.5);
  • 采用meta viewport的方式
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>

這樣就能縮放到原來的0.5倍,如果是1px那么就會(huì)變成0.5px。viewport只針對于移動(dòng)端,只在移動(dòng)端上才能看到效果

5. 設(shè)置小于12px的字體

在谷歌下css設(shè)置字體大小為12px及以下時(shí),顯示都是一樣大小,都是默認(rèn)12px。

解決方法:

  • 使用Webkit的內(nèi)核的-webkit-text-size-adjust的私有CSS屬性來解決,只要加了-webkit-text-size-adjust:none;字體大小就不受限制了。但是chrome更新到27版本之后就不可以用了。所以高版本chrome谷歌瀏覽器已經(jīng)不再支持-webkit-text-size-adjust樣式,所以要使用時(shí)候慎用。
  • 使用css3的transform縮放屬性-webkit-transform:scale(0.5); 注意-webkit-transform:scale(0.75);收縮的是整個(gè)元素的大小,這時(shí)候,如果是內(nèi)聯(lián)元素,必須要將內(nèi)聯(lián)元素轉(zhuǎn)換成塊元素,可以使用display:block/inline-block/...;
  • 使用圖片:如果是內(nèi)容固定不變情況下,使用將小于12px文字內(nèi)容切出做圖片,這樣不影響兼容也不影響美觀。

6. 如何解決 1px 問題?

1px 問題指的是:在一些 Retina屏幕 的機(jī)型上,移動(dòng)端頁面的 1px 會(huì)變得很粗,呈現(xiàn)出不止 1px 的效果。原因很簡單——CSS 中的 1px 并不能和移動(dòng)設(shè)備上的 1px 劃等號。它們之間的比例關(guān)系有一個(gè)專門的屬性來描述:

window.devicePixelRatio = 設(shè)備的物理像素 / CSS像素。

打開 Chrome 瀏覽器,啟動(dòng)移動(dòng)端調(diào)試模式,在控制臺(tái)去輸出這個(gè) devicePixelRatio 的值。這里選中 iPhone6/7/8 這系列的機(jī)型,輸出的結(jié)果就是2:

image

這就意味著設(shè)置的 1px CSS 像素,在這個(gè)設(shè)備上實(shí)際會(huì)用 2 個(gè)物理像素單元來進(jìn)行渲染,所以實(shí)際看到的一定會(huì)比 1px 粗一些。

解決1px 問題的三種思路:

思路一:直接寫 0.5px

如果之前 1px 的樣式這樣寫:

border:1px solid #333

可以先在 JS 中拿到 window.devicePixelRatio 的值,然后把這個(gè)值通過 JSX 或者模板語法給到 CSS 的 data 里,達(dá)到這樣的效果(這里用 JSX 語法做示范):

<div id="container" data-device={{window.devicePixelRatio}}></div>

然后就可以在 CSS 中用屬性選擇器來命中 devicePixelRatio 為某一值的情況,比如說這里嘗試命中 devicePixelRatio 為2的情況:

#container[data-device="2"] {
  border:0.5px solid #333
}

直接把 1px 改成 1/devicePixelRatio 后的值,這是目前為止最簡單的一種方法。這種方法的缺陷在于兼容性不行,IOS 系統(tǒng)需要8及以上的版本,安卓系統(tǒng)則直接不兼容。

思路二:偽元素先放大后縮小

這個(gè)方法的可行性會(huì)更高,兼容性也更好。唯一的缺點(diǎn)是代碼會(huì)變多。

思路是先放大、后縮?。?strong>在目標(biāo)元素的后面追加一個(gè) ::after 偽元素,讓這個(gè)元素布局為 absolute 之后、整個(gè)伸展開鋪在目標(biāo)元素上,然后把它的寬和高都設(shè)置為目標(biāo)元素的兩倍,border值設(shè)為 1px。接著借助 CSS 動(dòng)畫特效中的放縮能力,把整個(gè)偽元素縮小為原來的 50%。此時(shí),偽元素的寬高剛好可以和原有的目標(biāo)元素對齊,而 border 也縮小為了 1px 的二分之一,間接地實(shí)現(xiàn)了 0.5px 的效果。

代碼如下:

#container[data-device="2"] {
    position: relative;
}
#container[data-device="2"]::after{
      position:absolute;
      top: 0;
      left: 0;
      width: 200%;
      height: 200%;
      content:"";
      transform: scale(0.5);
      transform-origin: left top;
      box-sizing: border-box;
      border: 1px solid #333;
    }
}

思路三:viewport 縮放來解決

這個(gè)思路就是對 meta 標(biāo)簽里幾個(gè)關(guān)鍵屬性下手:

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

這里針對像素比為2的頁面,把整個(gè)頁面縮放為了原來的1/2大小。這樣,本來占用2個(gè)物理像素的 1px 樣式,現(xiàn)在占用的就是標(biāo)準(zhǔn)的一個(gè)物理像素。根據(jù)像素比的不同,這個(gè)縮放比例可以被計(jì)算為不同的值,用 js 代碼實(shí)現(xiàn)如下:

const scale = 1 / window.devicePixelRatio;
// 這里 metaEl 指的是 meta 標(biāo)簽對應(yīng)的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);

這樣解決了,但這樣做的副作用也很大,整個(gè)頁面被縮放了。這時(shí) 1px 已經(jīng)被處理成物理像素大小,這樣的大小在手機(jī)上顯示邊框很合適。但是,一些原本不需要被縮小的內(nèi)容,比如文字、圖片等,也被無差別縮小掉了。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號