前言
系列首發(fā)于公眾號(hào)『前端進(jìn)階圈』 ,更多精彩內(nèi)容敬請(qǐng)關(guān)注公眾號(hào)最新消息。
最近一周面試實(shí)錄CSS篇
1. CSS 選擇器以及優(yōu)先級(jí)?
-
CSS 選擇器
選擇器 格式 優(yōu)先級(jí)權(quán)重 id 選擇器 #id 100 類選擇器 .classname 10 屬性選擇器 [title]/[title="one"] 10 偽類選擇器 div:hover 10 標(biāo)簽選擇器 div 1 偽元素選擇器 input::after 1 子選擇器 ul>li 0 后代選擇器 li a 0 通配符選擇器 * 0 -
CSS 選擇器優(yōu)先級(jí)
- 參考 MDN:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity
- !important 例外,優(yōu)先級(jí)最高
- 內(nèi)聯(lián)樣式
- id 選擇器
- 類選擇器,屬性選擇器,偽類選擇器
- 標(biāo)簽選擇器,偽元素選擇器
- 子選擇器,后代選擇器,通配符選擇器
- 參考 MDN:
-
選擇器權(quán)重
- 參考 W3C:
https://www.w3.org/TR/selectors/#specificity - 例子:
./Demo/css_selector_and_priority.html
- 參考 W3C:
2. link 和 @import 的區(qū)別?
-
link: 鏈接外部資源的標(biāo)簽,此標(biāo)簽決定了文檔與外部資源的關(guān)系,常用于鏈接樣式表(css),網(wǎng)頁(yè)站點(diǎn)圖標(biāo)(favicon)。- 用法;
<link rel="stylesheet,icon,image/png,shortlink,help,author,image/svg+xml" href="網(wǎng)絡(luò)路徑/相對(duì)路徑/絕對(duì)路徑"/> - 屬性:
- rel: 表示關(guān)系:realtionship,
- href: 網(wǎng)絡(luò)路徑/相對(duì)路徑/絕對(duì)路徑
- size: icon 的大小
- disabled: 僅對(duì) rel = "stylesheet" 類型生效
- 用法;
- 區(qū)別:
- 從屬差異:link 為 html 標(biāo)簽,可以加載 css, 也可以引入網(wǎng)站圖標(biāo)(facaion), 定義 rel 鏈接屬性,而 @import 是 css 提供,只能用于加載 css
- 加載差異:link 引用的 css,在頁(yè)面加載時(shí)同時(shí)加載。而 @import 在頁(yè)面加載完后才加載
- 兼容性:link 是 html 標(biāo)簽,沒(méi)有兼容問(wèn)題。而 @ import 是 css2.1 提出的,IE5 以下的瀏覽器不支持。
- 可操作性:link 可使用 js 來(lái)控制 DOM 去改變樣式,而 @import 不支持,因?yàn)?DOM 方法是基于文檔的。
- 權(quán)重差異:
- 在樣式中:link 樣式的權(quán)重高于 @import 的權(quán)重嗎,例如:
/* @import "03.css"; */
body,
html {
background-color: aquamarine;
}
/* @import "03.css"; */
- 在頁(yè)面中:不存在權(quán)重問(wèn)題,誰(shuí)在最低下就使用誰(shuí)的樣式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Document</title>
</head>
<body>
<div class="container"></div>
</body>
</html>
<link rel="stylesheet" href="./01.css" />
<style>
@import "./03.css";
</style>
3. 對(duì)盒模型的理解?
- 組成:由四部分組成:margin, padding, border, content
- 分類:標(biāo)準(zhǔn)盒模型 和 怪異盒模型(IE 盒模型)
- 兩者區(qū)別:在于 width 和 height 所包含的范圍不同
- 標(biāo)準(zhǔn)盒模型:width 和 height 的范圍只包含了 content
[圖片上傳失敗...(image-c74a86-1680407876023)] - 怪異盒模型:width 和 height 的范圍只包含了 border, padding, content
[圖片上傳失敗...(image-4736d0-1680407876023)]
- 標(biāo)準(zhǔn)盒模型:width 和 height 的范圍只包含了 content
- 兩者區(qū)別:在于 width 和 height 所包含的范圍不同
- 屬性:
- 標(biāo)準(zhǔn)盒模型:
box-sizing: content-box; - 怪異盒模型:
box-sizing: border-box;
- 標(biāo)準(zhǔn)盒模型:
4. 隱藏元素的方法有哪些?
-
display: none;: 不會(huì)渲染該元素,不會(huì)占位,也不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件 -
visibility: hidden;: 會(huì)渲染,但是不會(huì)顯示且會(huì)占位,也不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件 -
opacity: 0;: 將元素的透明度設(shè)置為 0, 以此來(lái)達(dá)到隱藏元素的效果,會(huì)占位,能夠響應(yīng)綁定的監(jiān)聽(tīng)事件 -
position: absolute;: 使用絕對(duì)定位將元素移除了可視區(qū)域外,不會(huì)占位,以此來(lái)實(shí)現(xiàn)元素的隱藏 -
z-index:負(fù)值;: 使用其他元素將該元素隱藏,會(huì)占位 -
clip:position:absolute; clip: rect(200px, 200px, 200px, 200px);/clip-path:clip-path: circle(0);: 使用元素裁切的
方式實(shí)現(xiàn)元素隱藏,會(huì)占位,不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件 -
transform: scale(0,0): 使用縮放,來(lái)實(shí)現(xiàn)元素的隱藏,會(huì)占位,但是不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件 -
filter: opacity(0): 使用元素濾鏡來(lái)改變?cè)氐耐该鞫? 會(huì)占位
5. 偽元素和偽類的區(qū)別和作用?
- 偽類:將某種狀態(tài)時(shí)添加到已有元素上,這個(gè)狀態(tài)是根據(jù)用戶的行為變化而變化為的。比如: hover,active, visited
- 偽元素:用于創(chuàng)建一些原本不在文檔樹(shù)中的元素或樣式, 比如:::after,::before。
- 區(qū)別:
- 偽類操作的對(duì)象是文檔樹(shù)種已有的元素或樣式
- 偽元素則是創(chuàng)建一個(gè)文檔樹(shù)以外的元素或樣式
- : 表示偽類
- :: 表示偽元素
- 作用:
- 偽類:通過(guò)在元素選擇器上加入偽類改變?cè)氐臓顟B(tài)
- 偽元素:通過(guò)對(duì)元素的操作進(jìn)而改變?cè)?/li>
6. CSS3 有哪些新特性?
- 圓角:
border-radius: 8px; - 陰影:
text-shadown: 2px 2px #ff0000; box-shadown: 10px 10px 5px #888888; - 文字方向:
text-decoration - 漸變:
linear-gradient: 線性漸變 radial-gradient 徑向漸變 - 旋轉(zhuǎn):
transform - css選擇器:
偽類選擇器:first-child, 偽元素選擇器,否定選擇器(:not),屬性選擇器[title="one"] - 多列布局:
multi-column:- column: 規(guī)定列寬和列數(shù)
- column-count: 列的數(shù)量
- column-width: 列寬
- column-gap: 列間隙
- column-rule: 列之間的寬度,樣式和顏色
- column-span:
- column-fill: 列填充:auto: 根據(jù)內(nèi)容填充。balance: 每列平均
7. 對(duì)媒體查詢的理解?
- 使用
@media查詢,可針對(duì)不同的媒體類型定義不同的樣式,@media 可針對(duì)不同的屏幕尺寸設(shè)置不同的樣式,特別是設(shè)置響應(yīng)式的頁(yè)面,
@media 非常有用。當(dāng)重置瀏覽器大小的過(guò)程中,頁(yè)面會(huì)根據(jù)瀏覽器的寬度和高度重新渲染頁(yè)面。
8. 對(duì) BFC 的理解,如何創(chuàng)建 BFC?
-
定義:
- Box: CSS 布局的對(duì)象和基本單位,一個(gè)頁(yè)面由很多個(gè) box 組成,這個(gè) Box 就是我們常說(shuō)的盒模型
- Formatting context: 塊級(jí)格式化上下文,頁(yè)面中的一個(gè)渲染區(qū)域,有一套渲染規(guī)則,它決定了其子元素如何定位,以及其他元素的關(guān)系和相互作用。
理解:BFC(Block Formatting Context, BFC) 塊級(jí)格式化上下文,頁(yè)面布局盒模型的一種 CSS 渲染模式,是一個(gè)獨(dú)立的容器,在這個(gè)容器中里面的元素和外部的元素互不影響。
-
創(chuàng)建 BFC 的條件:
- 根元素:html,body
- 浮動(dòng):float 除 none 以外的值
- 定位:position 為絕對(duì)定位(absoluate) 和 固定定位(fixed)
- dispaly 屬性:表格布局(grid: table-cell,table-caption) 和 flex(flex-items,flow-root) 布局
- multi column(多列布局): column
- overflow: 值為 hidden, auto, scroll
-
BFC 的特點(diǎn):
- 垂直方向上,自上而下排列,和文檔流的排列方式一致
- 在 BFC 中上下兩個(gè)相鄰的兩個(gè)容器的 margin 會(huì)重疊
- 計(jì)算 BFC 的高度時(shí),需要計(jì)算浮動(dòng)元素的高度
- BFC 區(qū)域不會(huì)與浮動(dòng)的容器發(fā)生重疊
- BFC 是獨(dú)立的容器,容器內(nèi)部的元素不會(huì)影響外部元素
- 每個(gè)元素的 margin-left 值和容器的 border-left 相接觸
-
BFC 的作用:
- 解決 margin 重疊問(wèn)題:由于 BFC 是一個(gè)獨(dú)立的區(qū)域,內(nèi)部的元素和外部的元素互不影響,將兩個(gè)元素變?yōu)閮蓚€(gè) BFC,就解決了 margin 重疊的問(wèn)題。
- 解決高度塌陷問(wèn)題:在對(duì)子元素設(shè)置浮動(dòng)后,父元素會(huì)發(fā)生高度塌陷,也就是父元素的高度變?yōu)?0。解決這個(gè)問(wèn)題,只需要把父元素變成一個(gè) BFC。常用的辦法是給父元素設(shè)置
overflow:hidden。 - 創(chuàng)建自適應(yīng)兩欄布局:可以用來(lái)創(chuàng)建自適應(yīng)兩欄布局:左邊的寬度固定,右邊的寬度自適應(yīng)。
9. 如何設(shè)置小于 12px 的字體?
- 使用 webkit 內(nèi)核的:
-webkit-text-size-adjust: none;。chrome 27 版本后不可用了。 - 使用 css3 的 transform 屬性:
transform: scale(0.5); - 內(nèi)容固定不變的情況下,將文字內(nèi)容做成圖片,使用圖片來(lái)解決
10. 單行/多行文本溢出?
/* 多行文本溢出 */
display: -webkit-box; /*作為彈性伸縮盒子模型顯示。 */
-webkit-box-orient:vertical; /*設(shè)置伸縮盒子的子元素排列方式:從上到下垂直排列 */
-webkit-line-clamp:3; /*顯示的行數(shù) */
overflow: hidden; /*溢出隱藏 */
text-overflow: ellipsis; /*溢出用省略號(hào)顯示 */
/* 單行文本溢出 */
white-space: nowrap; /*規(guī)定段落中的文本不進(jìn)行換行 */
overflow: hidden; /*溢出隱藏 */
text-overflow: ellipsis; /*溢出用省略號(hào)顯示 */
11. 實(shí)現(xiàn)一個(gè)三角形?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="div4"></div>
</body>
</html>
<style>
div{
width: 0px;
height: 0px;
border: 50px solid transparent;
}
.div1{
border-top-color: red;
}
.div2{
border-bottom-color: red;
}
.div3{
border-left-color: red;
}
.div4{
border-right-color: red;
}
</style>
12. 實(shí)現(xiàn)一個(gè)扇形?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="div1"></div>
</body>
</html>
<style>
.div1{
width: 0;
height: 0;
border-radius: 100px;
border: 100px solid transparent;
border-top-color: red;
}
</style>
13. 畫(huà)一條0.5px的線?
- 使用 transform 的 scale 來(lái)完成
width: 250px;
height: 1px;
background-color: gray;
transform: scaleY(0.5);
14. 常見(jiàn)的圖片格式以及使用場(chǎng)景?
- bmp: 無(wú)損的,此圖片格式不會(huì)對(duì)數(shù)據(jù)進(jìn)行壓縮,所以 bmp 格式的圖片通常都是較大文件
- git: 無(wú)損的,特點(diǎn)是文件小,適用場(chǎng)景:對(duì)色彩要求不高且文件體積較小
- jpeg,jpg: 有損的,有損壓縮會(huì)導(dǎo)致圖片模糊,文件類型比 gif 較大
- png-8:無(wú)損的,png-8 比 gif 文件還小
- png-24: 無(wú)損的,優(yōu)點(diǎn)在于壓縮了圖片數(shù)據(jù)
- svg: 無(wú)損矢量圖,放大不會(huì)失真,適用場(chǎng)景:繪制 LOGO, Icon
- webp: 同時(shí)支持有損和無(wú)損,同質(zhì)量的圖片,webp 擁有更小的文件體積,更好地提升用戶體驗(yàn),
- 在無(wú)損壓縮情況下:相同質(zhì)量的 webp 圖片,要比 png 小 26%
- 在有損壓縮情況下,具有相同精度的 webp 圖片,文件大小要比 jpeg 小 25%~34%
- webp 還支持圖片透明度,一個(gè)無(wú)損壓縮的 webp 圖片,想要支持透明度,只需要 22% 的格外文件大小。
15. CSS 優(yōu)化和提高性能的方法有哪些?
- 加載性能
- css 壓縮
- 減少使用屬性簡(jiǎn)寫(xiě)方式
- 減少使用 @import,建議使用 link,
- 選擇器性能
- 減少選擇器嵌套層級(jí)
- 使用關(guān)鍵的選擇器,不要逐層進(jìn)行選擇
- 渲染性能
- 慎重使用浮動(dòng)和定位
- 盡量減少重繪和回流的發(fā)生
- 刪除空規(guī)則,也就是預(yù)留樣式->{}
- 屬性值為浮點(diǎn)值時(shí),省略前面的 0
- 不要使用 @import 前綴引用樣式,會(huì)影響 css 加載速度
- 避免選擇器嵌套過(guò)深
- 不濫用 web 字體
- 可維護(hù)性,健壯性
- 抽離公共樣式
- 樣式與內(nèi)容分離
16. ::before 和 :after 的雙冒號(hào)和單冒號(hào)有什么區(qū)別?
-
單冒號(hào)(:)表示偽類,雙冒號(hào)(::)表示偽元素 - 在 CSS2.1 中,偽元素都是使用
單冒號(hào)來(lái)表示偽元素的,但在 CSS3 規(guī)范中,偽元素的語(yǔ)法被修改為使用雙冒號(hào)
17. CSS 預(yù)處理器/后處理器是什么?為什么要使用他們?
- 預(yù)處理器:
less, sass, styuls,它們?cè)黾恿?css 代碼的復(fù)用性,例如:變量,循環(huán),方法等 - 后處理器:
postcss,最常做的是給 css 代碼添加瀏覽器前綴,實(shí)現(xiàn)跨瀏覽器兼容性的問(wèn)題、 - 為什么要使用他們?
- 結(jié)構(gòu)清晰,便于擴(kuò)展
- 屏蔽瀏覽器私有語(yǔ)法的差異
- 使用多重繼承
- 提到 css 代碼的兼容性
18. z-index 會(huì)在什么情況下會(huì)失效?
- 作用及含義:設(shè)置元素的堆疊順序,值越大就越在上層
- 檢查以下情況:
- 該元素是否設(shè)置了定位
- 該元素的父級(jí)是否已經(jīng)設(shè)置了z-index(檢查需比較的元素是否同在一個(gè)層疊上下文)
- z-index 屬性會(huì)在下列情況中會(huì)失效:
- 在設(shè)置 z-index 的元素上必須含有 position 屬性為非 static 屬性值(relative,absolute,fixed)。
- 同一個(gè)父級(jí)元素下的元素層疊效果是受父級(jí)影響的,就是說(shuō)如果你的父級(jí)z-index很小,那你子級(jí)設(shè)置再大也沒(méi)有用
19. 常見(jiàn)的 css 布局單位?
- 常用布局單位:
像素px,百分比%,em,rem,vw/vh- 像素px: 頁(yè)面布局基礎(chǔ),分為css 像素和物理像素
- css 像素:web 開(kāi)發(fā)者提供,css 中的一個(gè)抽象單位
- 物理像素:與設(shè)備的硬件密度相關(guān),任何設(shè)備的物理像素都是固定的
- 百分比%: 實(shí)現(xiàn)響應(yīng)式效果
- em和rem: 相對(duì)于 px 更具靈活性,它們都是相對(duì)長(zhǎng)度單位,區(qū)別為,em 相對(duì)于父元素,rem相對(duì)于子元素
- em:文本相對(duì)長(zhǎng)度單位,瀏覽器默認(rèn)的字體尺寸為 16px;
- rem: css3 新增的一個(gè)相對(duì)單位,是相對(duì)于根元素 html元素 的 font-size 的倍數(shù),
- vw/vh: 視圖窗口單位,vw 寬度,vh 高度,還有 vmin 和 vmax 兩個(gè)相關(guān)單位
- vmin: vw 和 vh 的較小值
- vmax: vw 和 vh 的較大值
- 像素px: 頁(yè)面布局基礎(chǔ),分為css 像素和物理像素
20. px,em, rem 的區(qū)別以及使用場(chǎng)景?
- 區(qū)別:
- px: 固定像素,無(wú)法跟著頁(yè)面大小而改變
- em: em 和 rem 相對(duì)長(zhǎng)度單位,長(zhǎng)度不是固定的,會(huì)跟著頁(yè)面大小而改變,更適用于響應(yīng)式布局
- em 相對(duì)于父元素來(lái)設(shè)置字體大小,而 rem 是相對(duì)于根元素來(lái)改變的
- 使用場(chǎng)景:
- 適配少部分的移動(dòng)設(shè)備,且對(duì)分辨率對(duì)頁(yè)面影響大小的可使用 px
- 適配各種移動(dòng)設(shè)備,使用 rem
21. 兩欄布局的實(shí)現(xiàn)
- 左邊固定,右邊自適應(yīng)
- 利用浮動(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;
}
- 利用絕對(duì)定位,將父級(jí)元素設(shè)置為相對(duì)定位。左邊元素設(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;
}
- 利用絕對(duì)定位,將父級(jí)元素設(shè)置為相對(duì)定位。左邊元素寬度設(shè)置為 200px,右邊元素設(shè)置為絕對(duì)定位,左邊定位為 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;
}
22. 三欄布局的實(shí)現(xiàn)
左右兩遍固定。中間自適應(yīng)
利用絕對(duì)定位,左右兩欄設(shè)置為絕對(duì)定位,中間設(shè)置對(duì)應(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è)置對(duì)應(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ù)邊距來(lái)實(shí)現(xiàn)。父級(jí)元素設(shè)置左右的 padding,三列均設(shè)置向左浮動(dòng),中間一列放在最前面,寬度設(shè)置為父級(jí)元素的寬度,因此后面兩列都被擠到了下一行,通過(guò)設(shè)置 margin 負(fù)值將其移動(dòng)到上一行,再利用相對(duì)定位,定位到兩邊。
.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;
}
- 雙飛翼布局,雙飛翼布局相對(duì)于圣杯布局來(lái)說(shuō),左右位置的保留是通過(guò)中間列的 margin 值來(lái)實(shí)現(xiàn)的,而不是通過(guò)父元素的 padding 來(lái)實(shí)現(xiàn)的。本質(zhì)上來(lái)說(shuō),也是通過(guò)浮動(dòng)和外邊距負(fù)值來(lái)實(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;
}
23. 水平垂直居中的方式?
- flex 布局
.parent {
display: flex;
justify-content:center;
align-items:center;
}
- 絕對(duì)定位 + margin
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 自身 height 的一半 */
margin-left: -50px; /* 自身 width 的一半 */
}
- 絕對(duì)定位
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
- 絕對(duì)定位 + transform
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
24. 響應(yīng)式設(shè)計(jì)的概念及基本原理?
- 響應(yīng)式設(shè)計(jì):也就是一個(gè)網(wǎng)站能兼容多個(gè)終端,而不是每個(gè)終端做一個(gè)適配
- 原理:通過(guò)媒體查詢
@media查詢檢測(cè)不同的設(shè)備屏幕尺寸做處理 - 關(guān)于兼容:頁(yè)面頭部必須要有 meta 聲明的 viewport
25. position 的屬性有哪些,區(qū)別是什么?
absolute: 絕對(duì)定位的元素的位置相對(duì)于最近的已定位父元素,如果元素沒(méi)有已定位的父元素,那么它的位置相對(duì)于<html>
relative: 相對(duì)定位元素的定位是相對(duì)其正常位置
fixed: 元素的位置相對(duì)于瀏覽器窗口是固定位置。即使窗口是滾動(dòng)的它也不會(huì)移動(dòng):
static: HTML 元素的默認(rèn)值,即沒(méi)有定位,遵循正常的文檔流對(duì)象。靜態(tài)定位的元素不會(huì)受到 top, bottom, left, right影響。
inherit: 規(guī)定從父元素繼承 position 屬性的
sticky: 基于用戶的滾動(dòng)位置來(lái)定位
-
前面三者的定位方式如下:
-
relative:元素的定位永遠(yuǎn)是相對(duì)于元素自身位置的,和其他元素沒(méi)關(guān)系,也不會(huì)影響其他元素。
[圖片上傳失敗...(image-b8556c-1680407876023)]
fixed:元素的定位是相對(duì)于 window (或者 iframe)邊界的,和其他元素沒(méi)有關(guān)系。但是它具有破壞性,會(huì)導(dǎo)致其他元素位置的變化。
[圖片上傳失敗...(image-8fa51c-1680407876023)]
absolute:元素的定位相對(duì)于前兩者要復(fù)雜許多。如果為 absolute 設(shè)置了 top、left,瀏覽器會(huì)根據(jù)什么去確定它的縱向和橫向的偏移量呢?答案是瀏覽器會(huì)遞歸查找該元素的所有父元素,如果找到一個(gè)設(shè)置了position:relative/absolute/fixed的元素,就以該元素為基準(zhǔn)定位,如果沒(méi)找到,就以瀏覽器邊界定位。如下兩個(gè)圖所示:
[圖片上傳失敗...(image-c3dc7f-1680407876023)]
[圖片上傳失敗...(image-7e4900-1680407876023)]
-
relative:元素的定位永遠(yuǎn)是相對(duì)于元素自身位置的,和其他元素沒(méi)關(guān)系,也不會(huì)影響其他元素。
26. absolute 與 fixed 的共同點(diǎn)與不同點(diǎn)?
- 共同點(diǎn):
- 改變行內(nèi)元素的呈現(xiàn)方式,將 display 改為 inline-block
- 使元素脫離普通文檔流,不再占據(jù)文檔物理空間
- 覆蓋非定位文檔元素
- 不同點(diǎn):
- absolute 與 fixed 的根元素不同,absolute 的根元素可設(shè)置,fixed 的根元素是html
- 在有滾動(dòng)的頁(yè)面中,absolute 會(huì)跟隨父元素進(jìn)行滾動(dòng),而 fixed 固定在某個(gè)位置
27. 如何解決 1px 問(wèn)題?
- 1px 問(wèn)題的本質(zhì):在一些
Retina屏幕上,移動(dòng)端頁(yè)面的 1px 會(huì)變得很粗,所呈現(xiàn)出來(lái)不止是 1px 的效果,原因就是 CSS 中的 1px 不能和移動(dòng)端的 1px 劃等號(hào),他們之間是有一個(gè)比例關(guān)系。
window.devicePixelRatio = 設(shè)備的物理像素 / CSS像素。
- 解決方法:
- 直接寫(xiě) 0.5px: 通過(guò) js 拿到 window.devicePixelRatio 的值, 然后進(jìn)行判斷處理(如果是 1,則直接返回,否則 1 / window.devicePixelRatio),然后動(dòng)態(tài)的設(shè)置 CSS 屬性中的值,以此來(lái)達(dá)到 1px 的效果。
- 缺點(diǎn):兼容性不行, andriod 直接不兼容,ios 需要 8.0 以上的版本
<div id="container" data-device={{window.devicePixelRatio}}></div>
- 通過(guò)偽元素
#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;
}
- 缺點(diǎn):代碼較多,但兼容性好
- viewport 縮放來(lái)解決
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
- 這里針對(duì)像素比為 2 的頁(yè)面,把整個(gè)頁(yè)面縮放為了原來(lái)的 1/2 大小。這樣,本來(lái)占用 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)簽對(duì)應(yīng)的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
- 缺點(diǎn):整個(gè)頁(yè)面都會(huì)被縮放
28. 如何判斷元素進(jìn)入可視區(qū)域?
- offsetTop、scrollTop
- getBoundingClientRect
- Intersection Observer
`window.innerHeight` 是瀏覽器可視區(qū)的高度;
`document.body.scrollTop || document.documentElement.scrollTop` 是瀏覽器滾動(dòng)的過(guò)的距離;
`imgs.offsetTop` 是元素頂部距離文檔頂部的高度(包括滾動(dòng)條的距離);
內(nèi)容達(dá)到顯示區(qū)域的:`img.offsetTop < window.innerHeight + document.body.scrollTop;`
- 方式一:offsetTop、scrollTop
// 公式
el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
// 代碼實(shí)現(xiàn)
function isInViewPortOfOne (el) {
// viewPortHeight 兼容所有瀏覽器寫(xiě)法
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const offsetTop = el.offsetTop
const scrollTop = document.documentElement.scrollTop
const top = offsetTop - scrollTop
return top <= viewPortHeight
}
- 方式二:getBoundingClientRect
- 返回值是一個(gè) DOMRect對(duì)象,擁有l(wèi)eft, top, right, bottom, x, y, width, 和 height屬性
const target = document.querySelector('.target');
const clientRect = target.getBoundingClientRect();
console.log(clientRect);
// {
// bottom: 556.21875,
// height: 393.59375,
// left: 333,
// right: 1017,
// top: 162.625,
// width: 684
// }
// A:
// 如果一個(gè)元素在視窗之內(nèi)的話,那么它一定滿足下面四個(gè)條件:
// top 大于等于 0
// left 大于等于 0
// bottom 小于等于視窗高度
// right 小于等于視窗寬度
// 代碼實(shí)現(xiàn)
function isInViewPort(element) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
const {
top,
right,
bottom,
left,
} = element.getBoundingClientRect();
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
);
}
- 方式三:Intersection Observer
- Intersection Observer 即重疊觀察者,從這個(gè)命名就可以看出它用于判斷兩個(gè)元素是否重疊,因?yàn)椴挥眠M(jìn)行事件的監(jiān)聽(tīng),性能方面相比getBoundingClientRect會(huì)好很多
- 使用步驟主要分為兩步:創(chuàng)建觀察者和傳入被觀察者
// 第一步:創(chuàng)建觀察者
const options = {
// 表示重疊面積占被觀察者的比例,從 0 - 1 取值,
// 1 表示完全被包含
threshold: 1.0,
root:document.querySelector('#scrollArea') // 必須是目標(biāo)元素的父級(jí)元素
};
const callback = (entries, observer) => { ....}
const observer = new IntersectionObserver(callback, options);
// 通過(guò)new IntersectionObserver創(chuàng)建了觀察者 observer,傳入的參數(shù) callback 在重疊比例超過(guò) threshold 時(shí)會(huì)被執(zhí)行`
// 上段代碼中被省略的 callback
const callback = function(entries, observer) {
entries.forEach(entry => {
entry.time; // 觸發(fā)的時(shí)間
entry.rootBounds; // 根元素的位置矩形,這種情況下為視窗位置
entry.boundingClientRect; // 被觀察者的位置舉行
entry.intersectionRect; // 重疊區(qū)域的位置矩形
entry.intersectionRatio; // 重疊區(qū)域占被觀察者面積的比例(被觀察者不是矩形時(shí)也按照矩形計(jì)算)
entry.target; // 被觀察者
});
};
// 第二步:傳入被觀察者
const target = document.querySelector('.target');
observer.observe(target);
- 實(shí)現(xiàn)代碼:前兩種方法
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<title>Document</title>
<style>
.container {
display: flex;
flex-wrap: wrap;
}
.target {
margin: 5px;
width: 20px;
height: 20px;
background: red;
}
</style>
</head>
<body>
<div class="container"></div>
</body>
</html>
<script>
(() => {
const $container = $(".container");
function createTargets() {
const htmlString = new Array(10000).fill('<div class="target"></div>').join("")
$container.html(htmlString)
}
createTargets();
const $targets = $(".target");
function isInViewPort(el){
//方法1
// const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// const offsetTop = el.offsetTop;
// const scollTop = document.documentElement.scrollTop;
// return offsetTop-scollTop <= viewPortHeight
// 方法2
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
const viewPortWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
const {top,right,left,bottom} = el.getBoundingClientRect();
return top >= 0 && left >= 0 && bottom <= viewPortHeight && right <= viewPortWidth
}
//事件監(jiān)聽(tīng)
$(window).on("scroll",()=>{
console.log("scroll!!");
$targets.each((index,element)=>{
if(isInViewPort(element)){
$(element).css("background-color","blue")
}
})
})
})();
</script>
- 第三種方法
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"
integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.test {
width: 200px;
height: 1000px;
background: orange;
}
.box {
width: 150px;
height: 150px;
margin: 50px;
background: red;
}
#sta {
position: fixed;
left: 40%;
top: 40%;
width: 200px;
height: 100px;
background: greenyellow;
}
</style>
</head>
<body>
<div class="test">test</div>
<div class="box">box</div>
<div id="sta">初始化</div>
</body>
</html>
<script>
(() => {
var status_node=document.querySelector("#sta");
const box = document.querySelector('.box');
const intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
box.innerText = '進(jìn)入可視區(qū)域';
status_node.innerText = '進(jìn)入可視區(qū)域';
console.log('進(jìn)入可視區(qū)域');
}else{
box.innerText = '出去了';
status_node.innerText = '出去了';
}
})
});
intersectionObserver.observe(box);
})();
</script>
特殊字符描述:
- 問(wèn)題標(biāo)注
Q:(question) - 答案標(biāo)注
R:(result) - 注意事項(xiàng)標(biāo)準(zhǔn):
A:(attention matters) - 詳情描述標(biāo)注:
D:(detail info) - 總結(jié)標(biāo)注:
S:(summary) - 分析標(biāo)注:
Ana:(analysis) - 提示標(biāo)注:
T:(tips)