前言
不論是寒冬還是暖冬,找工作之前都需要做好充足的準備,面試的時候才能做到遊刃有餘。此文是把我最近找工作準備的以及筆試面試中涉及到的手寫題做一個總結。給自己,也給需要的同學。
CSS是前端必須要掌握的技能之一。一般面試也都會從CSS開始。所以CSS問題答的好壞會直接影響你在面試官心中的形象。
本文主要介紹面試中常會遇到的CSS問題及給出建議性的答案。
往期
- “寒冬”三年經驗前端面試總結(含頭條、百度、餓了麼、滴滴等)
- "寒冬"三年經驗前端面試總結(含頭條、百度、餓了麼、滴滴等)之手寫題(一)
- "寒冬"三年經驗前端面試總結(含頭條、百度、餓了麼、滴滴等)之手寫題(二)
- "寒冬"三年經驗前端面試總結(含頭條、百度、餓了麼、滴滴等)之手寫題(promise篇)
盒模型
盒模型感覺是剛學前端的時候就會接觸到的問題。元素都是按照盒模型的規則佈局在頁面中的。盒模型由 margin + border + padding + content 四個屬性組成,分為兩種:W3C的標準盒模型和IE盒模型。
W3C的標準盒模型
width = content,不包含 border + padding
IE盒模型
width = border + padding + content
相互轉換
二者之間可以通過CSS3的 box-sizing 屬性來轉換。
box-sizing: content-box 是W3C盒模型
box-sizing: border-box 是IE盒模型
垂直居中的方法
垂直居中的方法,如果全寫出來,有10多種。面試的時候一般都會説比較常用的幾種。flex、position + transform、position + 負margin是最常見的三種情況。
<div class="outer">
<div class="inner"></div>
</div>
方法一:flex
.outer{
display: flex;
justify-content: center;
align-items: center
}
方法二: position + transform, inner寬高未知
.outer{
position:relative;
}
.inner{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
方法三:position + 負margin, inner寬高已知
.outer{
position: relative;
}
.inner{
width: 100px;
height: 100px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
方法四:設置各個方向的距離都是0,再將margin設為auto,也可以實現,前提是inner寬高已知
.outer {
position: relative;
}
.inner {
width: 100px;
height: 100px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
三欄佈局
三欄佈局是很常見的一種頁面佈局方式。左右固定,中間自適應。實現方式有很多種方法。
第一種:flex
<div class="container">
<div class="left">left</div>
<div class="main">main</div>
<div class="right">right</div>
</div>
.container{
display: flex;
}
.left{
flex-basis:200px;
background: green;
}
.main{
flex: 1;
background: red;
}
.right{
flex-basis:200px;
background: green;
}
第二種:position + margin
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
<div class="main">main</div>
</div>
body,html{
padding: 0;
margin: 0;
}
.left,.right{
position: absolute;
top: 0;
background: red;
}
.left{
left: 0;
width: 200px;
}
.right{
right: 0;
width: 200px;
}
.main{
margin: 0 200px ;
background: green;
}
第三種:float + margin
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
<div class="main">main</div>
</div>
body,html{
padding:0;
margin: 0;
}
.left{
float:left;
width:200px;
background:red;
}
.main{
margin:0 200px;
background: green;
}
.right{
float:right;
width:200px;
background:red;
}
CSS權重計算方式
CSS基本選擇器包含ID選擇器、類選擇器、標籤選擇器、通配符選擇器。
正常情況下,一般都能答出!important > 行內樣式 > ID選擇器 > 類選擇器 > 標籤選擇器 > 通配符選擇器。
但如果這幾種選擇器同時作用於一個元素時,該元素最後應用哪個樣式呢?這就涉及到權重計算的問題。
關於權重計算,有兩種不同的計算方式:一種是以二進制的規則計算,一種是以1,10,100,1000這種的計算方式。我更傾向於二進制的這種方式。
各選擇器權值:
- 內聯樣式,權值為1000
- ID選擇器,權值為0100
- 類,偽類和屬性選擇器,權值為0010
- 標籤選擇器和偽元素選擇器,權值為0001
- 通配符、子選擇器、相鄰選擇器等,權值為0000
- 繼承的樣式沒有權值
比較方式:
如果層級相同,繼續往後比較,如果層級不同,層級高的權重大,不論低層級有多少個選擇器。
BFC
BFC的全稱為 Block Formatting Context,也就是塊級格式化上下文的意思。
以下方式都會創建BFC:
- 根元素(html)
- 浮動元素(元素的 float 不是 none)
- 絕對定位元素(元素的 position 為 absolute 或 fixed)
- 行內塊元素(元素的 display 為 inline-block)
- 表格單元格(元素的 display為 table-cell,HTML表格單元格默認為該值)
- 表格標題(元素的 display 為 table-caption,HTML表格標題默認為該值)
- 匿名錶格單元格元素(元素的 display為 table、table-row、table-row-group、table-header-group、table-footer-group(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或 inline-table)
- overflow 值不為 visible 的塊元素
- display 值為 flow-root 的元素
- contain 值為 layout、content或 paint 的元素
- 彈性元素(display為 flex 或 inline-flex元素的直接子元素)
- 網格元素(display為 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不為 auto,包括 column-count 為 1)
column-span 為 all 的元素始終會創建一個新的BFC,即使該元素沒有包裹在一個多列容器中(標準變更,Chrome bug)。
BFC佈局規則:
- 內部的box會在垂直方向,一個接一個的放置。
- box垂直方向的距離有margin決定。屬於同一個BFC的兩個相鄰box的margin會發生重疊。3. 每個元素的左外邊距與包含塊的左邊界相接觸,即使浮動元素也是如此。
- BFC的區域不會與float的元素區域重疊。
- 計算BFC的高度時,浮動子元素也參與計算。
- BFC就是頁面上一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然。
BFC能解決的問題:
- 父元素塌陷
- 外邊距重疊
- 清除浮動
清除浮動的方法
清除浮動主要是為了防止父元素塌陷。清除浮動的方法有很多,常用的是 clearfix 偽類。
方法一:clearfix
<div class="outer clearfix">
<div class="inner">inner</div>
</div>
.outer{
background: blue;
}
.inner{
width: 100px;
height: 100px;
background: red;
float: left;
}
.clearfix:after{
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
方法二:額外加一個div,clear:both
<div class="container">
<div class="inner"></div>
<div class="clear"></div>
</div>
.container{
background: blue;
}
.inner {
width: 100px;
height: 100px;
background: red;
float: left;
}
.clear{
clear:both;
}
方法三:觸發父盒子BFC,overflow:hidden
<div class="outer">
<div class="inner">inner</div>
</div>
.outer{
background: blue;
overflow: hidden;
}
.inner {
width: 100px;
height: 100px;
background: red;
float: left;
}
flex佈局
flex 佈局現在已經很普及的在用了。垂直居中用 flex 實現起來很簡單。關於 flex 的屬性也不是很多,父容器和子容器各6個,一共12個,比較好記。
下面是我複習flex屬性時的一張導圖。
position屬性
position屬性的重要性應該沒啥可説的了。想必誰都回答的上來。
absolute絕對定位,相對於static定位以外的第一個父元素進行定位。relative相對定位,相對於其自身正常位置進行定位。fixed固定定位,相對於瀏覽器窗口進行定位。static默認值。沒有定位,元素出現在正常的流中。inherit規定應該從父元素繼承 position 屬性的值。
但是要注意一個問題,absolute 是相對於父元素的哪個屬性進行定位的?通過下面的例子我們來看一看。
.container{
position: relative;
width: 30px;
height: 30px;
margin: 20px;
border: 10px solid red;
padding: 10px;
background: blue;
}
.inner {
position: absolute;
width: 10px;
height: 10px;
top: 0;
left: 0;
background: pink;
}
從上圖可以看出,是相對於 static 定位以外的第一個父元素的 padding 來定位的。
CSS3中新增了一個 position:sticky 屬性,該屬性的作用類似 position:relative 和 position:fixed的結合。元素在跨越特定閾值前為相對定位,之後為固定定位。必須指定 top, right, bottom 或 left 四個閾值其中之一,才可使粘性定位生效。否則其行為與相對定位相同。但 sticky 尚在實驗性階段。
如何實現一個自適應的正方形
方法1:利用CSS3的vw單位
vw 會把視口的寬度平均分為100份
.square {
width: 10vw;
height: 10vw;
background: red;
}
方法2:利用margin或者padding的百分比計算是參照父元素的width屬性
.square {
width: 10%;
padding-bottom: 10%;
height: 0; // 防止內容撐開多餘的高度
background: red;
}
如何用css實現一個三角形
方法1: 利用border屬性
利用盒模型的 border 屬性上下左右邊框交界處會呈現出平滑的斜線這個特點,通過設置不同的上下左右邊框寬度或者顏色即可得到三角形或者梯形。
.triangle {
height:0;
width:0;
border-color:red blue green pink;
border-style:solid;
border-width:30px;
}
如果想實現其中的任一個三角形,把其他方向上的 border-color 都設置成透明即可。
.triangle {
height:0;
width:0;
border-color:red transparent transparent transparent;
border-style:solid;
border-width:30px;
}
方法二: 利用CSS3的clip-path屬性
不瞭解 clip-path 屬性的可以先看看 MDN 上的介紹:chip-path
.triangle {
width: 30px;
height: 30px;
background: red;
clip-path: polygon(0px 0px, 0px 30px, 30px 0px); // 將座標(0,0),(0,30),(30,0)連成一個三角形
transform: rotate(225deg); // 旋轉225,變成下三角
}
寫在最後
有錯誤之處還請小夥伴們及時指出,以免誤人子弟。想看往期內容,翻到頁面最上面有鏈接~