前言
系列首發(fā)于公眾號『前端進階圈』 靴迫,更多精彩內(nèi)容敬請關注公眾號最新消息。
最近一周面試實錄CSS篇
1. CSS 選擇器以及優(yōu)先級?
-
CSS 選擇器
選擇器 格式 優(yōu)先級權重 id 選擇器 #id 100 類選擇器 .classname 10 屬性選擇器 [title]/[title="one"] 10 偽類選擇器 div:hover 10 標簽選擇器 div 1 偽元素選擇器 input::after 1 子選擇器 ul>li 0 后代選擇器 li a 0 通配符選擇器 * 0 -
CSS 選擇器優(yōu)先級
- 參考 MDN:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity
- !important 例外紧唱,優(yōu)先級最高
- 內(nèi)聯(lián)樣式
- id 選擇器
- 類選擇器懈费,屬性選擇器,偽類選擇器
- 標簽選擇器伊滋,偽元素選擇器
- 子選擇器洋幻,后代選擇器郁轻,通配符選擇器
- 參考 MDN:
-
選擇器權重
- 參考 W3C:
https://www.w3.org/TR/selectors/#specificity
- 例子:
./Demo/css_selector_and_priority.html
- 參考 W3C:
2. link 和 @import 的區(qū)別?
-
link
: 鏈接外部資源的標簽鞋屈,此標簽決定了文檔與外部資源的關系,常用于鏈接樣式表(css)故觅,網(wǎng)頁站點圖標(favicon)厂庇。- 用法;
<link rel="stylesheet,icon,image/png,shortlink,help,author,image/svg+xml" href="網(wǎng)絡路徑/相對路徑/絕對路徑"/>
- 屬性:
- rel: 表示關系:realtionship,
- href: 網(wǎng)絡路徑/相對路徑/絕對路徑
- size: icon 的大小
- disabled: 僅對 rel = "stylesheet" 類型生效
- 用法;
- 區(qū)別:
- 從屬差異:link 為 html 標簽输吏,可以加載 css, 也可以引入網(wǎng)站圖標(facaion), 定義 rel 鏈接屬性权旷,而 @import 是 css 提供,只能用于加載 css
- 加載差異:link 引用的 css,在頁面加載時同時加載。而 @import 在頁面加載完后才加載
- 兼容性:link 是 html 標簽拄氯,沒有兼容問題躲查。而 @ import 是 css2.1 提出的,IE5 以下的瀏覽器不支持译柏。
- 可操作性:link 可使用 js 來控制 DOM 去改變樣式镣煮,而 @import 不支持,因為 DOM 方法是基于文檔的鄙麦。
- 權重差異:
- 在樣式中:link 樣式的權重高于 @import 的權重嗎典唇,例如:
/* @import "03.css"; */
body,
html {
background-color: aquamarine;
}
/* @import "03.css"; */
- 在頁面中:不存在權重問題,誰在最低下就使用誰的樣式
<!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. 對盒模型的理解胯府?
- 組成:由四部分組成:margin, padding, border, content
- 分類:標準盒模型 和 怪異盒模型(IE 盒模型)
- 兩者區(qū)別:在于 width 和 height 所包含的范圍不同
- 標準盒模型:width 和 height 的范圍只包含了 content
[圖片上傳失敗...(image-c74a86-1680407876023)] - 怪異盒模型:width 和 height 的范圍只包含了 border, padding, content
[圖片上傳失敗...(image-4736d0-1680407876023)]
- 標準盒模型:width 和 height 的范圍只包含了 content
- 兩者區(qū)別:在于 width 和 height 所包含的范圍不同
- 屬性:
- 標準盒模型:
box-sizing: content-box;
- 怪異盒模型:
box-sizing: border-box;
- 標準盒模型:
4. 隱藏元素的方法有哪些介衔?
-
display: none;
: 不會渲染該元素,不會占位骂因,也不會響應綁定的監(jiān)聽事件 -
visibility: hidden;
: 會渲染炎咖,但是不會顯示且會占位,也不會響應綁定的監(jiān)聽事件 -
opacity: 0;
: 將元素的透明度設置為 0, 以此來達到隱藏元素的效果寒波,會占位乘盼,能夠響應綁定的監(jiān)聽事件 -
position: absolute;
: 使用絕對定位將元素移除了可視區(qū)域外,不會占位影所,以此來實現(xiàn)元素的隱藏 -
z-index:負值;
: 使用其他元素將該元素隱藏,會占位 -
clip:position:absolute; clip: rect(200px, 200px, 200px, 200px);/clip-path:clip-path: circle(0);
: 使用元素裁切的
方式實現(xiàn)元素隱藏蹦肴,會占位,不會響應綁定的監(jiān)聽事件 -
transform: scale(0,0)
: 使用縮放猴娩,來實現(xiàn)元素的隱藏阴幌,會占位,但是不會響應綁定的監(jiān)聽事件 -
filter: opacity(0)
: 使用元素濾鏡來改變元素的透明度, 會占位
5. 偽元素和偽類的區(qū)別和作用卷中?
- 偽類:將某種狀態(tài)時添加到已有元素上矛双,這個狀態(tài)是根據(jù)用戶的行為變化而變化為的。比如: hover蟆豫,active, visited
- 偽元素:用于創(chuàng)建一些原本不在文檔樹中的元素或樣式, 比如:::after,::before议忽。
- 區(qū)別:
- 偽類操作的對象是文檔樹種已有的元素或樣式
- 偽元素則是創(chuàng)建一個文檔樹以外的元素或樣式
- : 表示偽類
- :: 表示偽元素
- 作用:
- 偽類:通過在元素選擇器上加入偽類改變元素的狀態(tài)
- 偽元素:通過對元素的操作進而改變元素
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. 對媒體查詢的理解速址?
- 使用
@media
查詢,可針對不同的媒體類型定義不同的樣式由驹,@media 可針對不同的屏幕尺寸設置不同的樣式芍锚,特別是設置響應式的頁面,
@media 非常有用。當重置瀏覽器大小的過程中并炮,頁面會根據(jù)瀏覽器的寬度和高度重新渲染頁面默刚。
8. 對 BFC 的理解,如何創(chuàng)建 BFC逃魄?
-
定義:
- Box: CSS 布局的對象和基本單位泽铛,一個頁面由很多個 box 組成离赫,這個 Box 就是我們常說的盒模型
- Formatting context: 塊級格式化上下文,頁面中的一個渲染區(qū)域,有一套渲染規(guī)則晾虑,它決定了其子元素如何定位挥唠,以及其他元素的關系和相互作用够掠。
理解:BFC(Block Formatting Context, BFC) 塊級格式化上下文忠聚,頁面布局盒模型的一種 CSS 渲染模式,是一個獨立的容器柳弄,在這個容器中里面的元素和外部的元素互不影響舶胀。
-
創(chuàng)建 BFC 的條件:
- 根元素:html,body
- 浮動:float 除 none 以外的值
- 定位:position 為絕對定位(absoluate) 和 固定定位(fixed)
- dispaly 屬性:表格布局(grid: table-cell,table-caption) 和 flex(flex-items,flow-root) 布局
- multi column(多列布局): column
- overflow: 值為 hidden, auto, scroll
-
BFC 的特點:
- 垂直方向上,自上而下排列碧注,和文檔流的排列方式一致
- 在 BFC 中上下兩個相鄰的兩個容器的 margin 會重疊
- 計算 BFC 的高度時嚣伐,需要計算浮動元素的高度
- BFC 區(qū)域不會與浮動的容器發(fā)生重疊
- BFC 是獨立的容器,容器內(nèi)部的元素不會影響外部元素
- 每個元素的 margin-left 值和容器的 border-left 相接觸
-
BFC 的作用:
- 解決 margin 重疊問題:由于 BFC 是一個獨立的區(qū)域萍丐,內(nèi)部的元素和外部的元素互不影響轩端,將兩個元素變?yōu)閮蓚€ BFC,就解決了 margin 重疊的問題逝变。
- 解決高度塌陷問題:在對子元素設置浮動后基茵,父元素會發(fā)生高度塌陷,也就是父元素的高度變?yōu)?0壳影。解決這個問題拱层,只需要把父元素變成一個 BFC。常用的辦法是給父元素設置
overflow:hidden
宴咧。 - 創(chuàng)建自適應兩欄布局:可以用來創(chuàng)建自適應兩欄布局:左邊的寬度固定根灯,右邊的寬度自適應。
9. 如何設置小于 12px 的字體掺栅?
- 使用 webkit 內(nèi)核的:
-webkit-text-size-adjust: none;
烙肺。chrome 27 版本后不可用了。 - 使用 css3 的 transform 屬性:
transform: scale(0.5);
- 內(nèi)容固定不變的情況下氧卧,將文字內(nèi)容做成圖片桃笙,使用圖片來解決
10. 單行/多行文本溢出?
/* 多行文本溢出 */
display: -webkit-box; /*作為彈性伸縮盒子模型顯示假抄。 */
-webkit-box-orient:vertical; /*設置伸縮盒子的子元素排列方式:從上到下垂直排列 */
-webkit-line-clamp:3; /*顯示的行數(shù) */
overflow: hidden; /*溢出隱藏 */
text-overflow: ellipsis; /*溢出用省略號顯示 */
/* 單行文本溢出 */
white-space: nowrap; /*規(guī)定段落中的文本不進行換行 */
overflow: hidden; /*溢出隱藏 */
text-overflow: ellipsis; /*溢出用省略號顯示 */
11. 實現(xiàn)一個三角形怎栽?
<!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. 實現(xiàn)一個扇形?
<!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. 畫一條0.5px的線宿饱?
- 使用 transform 的 scale 來完成
width: 250px;
height: 1px;
background-color: gray;
transform: scaleY(0.5);
14. 常見的圖片格式以及使用場景熏瞄?
- bmp: 無損的,此圖片格式不會對數(shù)據(jù)進行壓縮谬以,所以 bmp 格式的圖片通常都是較大文件
- git: 無損的强饮,特點是文件小,適用場景:對色彩要求不高且文件體積較小
- jpeg,jpg: 有損的为黎,有損壓縮會導致圖片模糊邮丰,文件類型比 gif 較大
- png-8:無損的,png-8 比 gif 文件還小
- png-24: 無損的铭乾,優(yōu)點在于壓縮了圖片數(shù)據(jù)
- svg: 無損矢量圖剪廉,放大不會失真,適用場景:繪制 LOGO, Icon
- webp: 同時支持有損和無損炕檩,同質(zhì)量的圖片斗蒋,webp 擁有更小的文件體積,更好地提升用戶體驗笛质,
- 在無損壓縮情況下:相同質(zhì)量的 webp 圖片泉沾,要比 png 小 26%
- 在有損壓縮情況下,具有相同精度的 webp 圖片妇押,文件大小要比 jpeg 小 25%~34%
- webp 還支持圖片透明度跷究,一個無損壓縮的 webp 圖片,想要支持透明度敲霍,只需要 22% 的格外文件大小俊马。
15. CSS 優(yōu)化和提高性能的方法有哪些?
- 加載性能
- css 壓縮
- 減少使用屬性簡寫方式
- 減少使用 @import色冀,建議使用 link,
- 選擇器性能
- 減少選擇器嵌套層級
- 使用關鍵的選擇器潭袱,不要逐層進行選擇
- 渲染性能
- 慎重使用浮動和定位
- 盡量減少重繪和回流的發(fā)生
- 刪除空規(guī)則,也就是預留樣式->{}
- 屬性值為浮點值時,省略前面的 0
- 不要使用 @import 前綴引用樣式锋恬,會影響 css 加載速度
- 避免選擇器嵌套過深
- 不濫用 web 字體
- 可維護性屯换,健壯性
- 抽離公共樣式
- 樣式與內(nèi)容分離
16. ::before 和 :after 的雙冒號和單冒號有什么區(qū)別?
-
單冒號(:)
表示偽類与学,雙冒號(::)
表示偽元素 - 在 CSS2.1 中彤悔,偽元素都是使用
單冒號
來表示偽元素的,但在 CSS3 規(guī)范中索守,偽元素的語法被修改為使用雙冒號
17. CSS 預處理器/后處理器是什么晕窑?為什么要使用他們?
- 預處理器:
less, sass, styuls
卵佛,它們增加了 css 代碼的復用性杨赤,例如:變量敞斋,循環(huán),方法等 - 后處理器:
postcss
疾牲,最常做的是給 css 代碼添加瀏覽器前綴植捎,實現(xiàn)跨瀏覽器兼容性的問題、 - 為什么要使用他們阳柔?
- 結(jié)構清晰焰枢,便于擴展
- 屏蔽瀏覽器私有語法的差異
- 使用多重繼承
- 提到 css 代碼的兼容性
18. z-index 會在什么情況下會失效?
- 作用及含義:設置元素的堆疊順序舌剂,值越大就越在上層
- 檢查以下情況:
- 該元素是否設置了定位
- 該元素的父級是否已經(jīng)設置了z-index(檢查需比較的元素是否同在一個層疊上下文)
- z-index 屬性會在下列情況中會失效:
- 在設置 z-index 的元素上必須含有 position 屬性為非 static 屬性值(relative,absolute,fixed)济锄。
- 同一個父級元素下的元素層疊效果是受父級影響的,就是說如果你的父級z-index很小霍转,那你子級設置再大也沒有用
19. 常見的 css 布局單位荐绝?
- 常用布局單位:
像素px,百分比%,em,rem,vw/vh
- 像素px: 頁面布局基礎,分為css 像素和物理像素
- css 像素:web 開發(fā)者提供避消,css 中的一個抽象單位
- 物理像素:與設備的硬件密度相關很泊,任何設備的物理像素都是固定的
- 百分比%: 實現(xiàn)響應式效果
- em和rem: 相對于 px 更具靈活性,它們都是相對長度單位沾谓,區(qū)別為委造,em 相對于父元素,rem相對于子元素
- em:文本相對長度單位均驶,瀏覽器默認的字體尺寸為 16px;
- rem: css3 新增的一個相對單位昏兆,是相對于根元素 html元素 的 font-size 的倍數(shù),
- vw/vh: 視圖窗口單位妇穴,vw 寬度爬虱,vh 高度,還有 vmin 和 vmax 兩個相關單位
- vmin: vw 和 vh 的較小值
- vmax: vw 和 vh 的較大值
- 像素px: 頁面布局基礎,分為css 像素和物理像素
20. px腾它,em, rem 的區(qū)別以及使用場景跑筝?
- 區(qū)別:
- px: 固定像素,無法跟著頁面大小而改變
- em: em 和 rem 相對長度單位瞒滴,長度不是固定的曲梗,會跟著頁面大小而改變,更適用于響應式布局
- em 相對于父元素來設置字體大小妓忍,而 rem 是相對于根元素來改變的
- 使用場景:
- 適配少部分的移動設備虏两,且對分辨率對頁面影響大小的可使用 px
- 適配各種移動設備,使用 rem
21. 兩欄布局的實現(xiàn)
- 左邊固定世剖,右邊自適應
- 利用浮動定罢,將左邊元素寬度設置為 200px,并且設置向左浮動旁瘫。將右邊元素的 margin-left 設置為 200px祖凫,寬度設置為 auto(默認為 auto琼蚯,撐滿整個父元素)。
.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
background: gold;
}
- 利用浮動惠况,左側(cè)元素設置固定大小凌停,并左浮動,右側(cè)元素設置 overflow: hidden; 這樣右邊就觸發(fā)了 BFC售滤,BFC 的區(qū)域不會與浮動元素發(fā)生重疊,所以兩側(cè)就不會發(fā)生重疊台诗。
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
- 利用 flex 布局完箩,將左邊元素設置為固定寬度 200px,將右邊的元素設置為 flex:1拉队。
.outer {
display: flex;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
flex: 1;
background: gold;
}
- 利用絕對定位弊知,將父級元素設置為相對定位。左邊元素設置為 absolute 定位粱快,并且寬度設置為 200px秩彤。將右邊元素的 margin-left 的值設置為 200px。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
background: gold;
}
- 利用絕對定位事哭,將父級元素設置為相對定位漫雷。左邊元素寬度設置為 200px,右邊元素設置為絕對定位鳍咱,左邊定位為 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. 三欄布局的實現(xiàn)
左右兩遍固定谤辜。中間自適應
利用絕對定位蓄坏,左右兩欄設置為絕對定位,中間設置對應方向大小的 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 布局涡戳,左右兩欄設置固定大小,中間一欄設置為 flex:1脯倚。
.outer {
display: flex;
height: 100px;
}
.left {
width: 100px;
background: tomato;
}
.right {
width: 100px;
background: gold;
}
.center {
flex: 1;
background: lightgreen;
}
- 利用浮動渔彰,左右兩欄設置固定大小,并設置對應方向的浮動推正。中間一欄設置左右兩個方向的 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;
}
- 圣杯布局舔稀,利用浮動和負邊距來實現(xiàn)乳丰。父級元素設置左右的 padding,三列均設置向左浮動内贮,中間一列放在最前面产园,寬度設置為父級元素的寬度汞斧,因此后面兩列都被擠到了下一行,通過設置 margin 負值將其移動到上一行什燕,再利用相對定位粘勒,定位到兩邊。
.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 值來實現(xiàn)的,而不是通過父元素的 padding 來實現(xiàn)的技俐。本質(zhì)上來說乘陪,也是通過浮動和外邊距負值來實現(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;
}
- 絕對定位 + margin
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 自身 height 的一半 */
margin-left: -50px; /* 自身 width 的一半 */
}
- 絕對定位
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
- 絕對定位 + transform
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
24. 響應式設計的概念及基本原理啡邑?
- 響應式設計:也就是一個網(wǎng)站能兼容多個終端,而不是每個終端做一個適配
- 原理:通過媒體查詢
@media
查詢檢測不同的設備屏幕尺寸做處理 - 關于兼容:頁面頭部必須要有 meta 聲明的 viewport
25. position 的屬性有哪些井赌,區(qū)別是什么谤逼?
absolute: 絕對定位的元素的位置相對于最近的已定位父元素,如果元素沒有已定位的父元素仇穗,那么它的位置相對于<html>
relative: 相對定位元素的定位是相對其正常位置
fixed: 元素的位置相對于瀏覽器窗口是固定位置流部。即使窗口是滾動的它也不會移動:
static: HTML 元素的默認值,即沒有定位纹坐,遵循正常的文檔流對象贵涵。靜態(tài)定位的元素不會受到 top, bottom, left, right影響。
inherit: 規(guī)定從父元素繼承 position 屬性的
sticky: 基于用戶的滾動位置來定位
-
前面三者的定位方式如下:
-
relative:元素的定位永遠是相對于元素自身位置的恰画,和其他元素沒關系宾茂,也不會影響其他元素。
[圖片上傳失敗...(image-b8556c-1680407876023)]
fixed:元素的定位是相對于 window (或者 iframe)邊界的拴还,和其他元素沒有關系跨晴。但是它具有破壞性,會導致其他元素位置的變化片林。
[圖片上傳失敗...(image-8fa51c-1680407876023)]
absolute:元素的定位相對于前兩者要復雜許多端盆。如果為 absolute 設置了 top、left费封,瀏覽器會根據(jù)什么去確定它的縱向和橫向的偏移量呢焕妙?答案是瀏覽器會遞歸查找該元素的所有父元素,如果找到一個設置了position:relative/absolute/fixed
的元素弓摘,就以該元素為基準定位焚鹊,如果沒找到,就以瀏覽器邊界定位韧献。如下兩個圖所示:
[圖片上傳失敗...(image-c3dc7f-1680407876023)]
[圖片上傳失敗...(image-7e4900-1680407876023)]
-
relative:元素的定位永遠是相對于元素自身位置的恰画,和其他元素沒關系宾茂,也不會影響其他元素。
26. absolute 與 fixed 的共同點與不同點末患?
- 共同點:
- 改變行內(nèi)元素的呈現(xiàn)方式研叫,將 display 改為 inline-block
- 使元素脫離普通文檔流,不再占據(jù)文檔物理空間
- 覆蓋非定位文檔元素
- 不同點:
- absolute 與 fixed 的根元素不同璧针,absolute 的根元素可設置嚷炉,fixed 的根元素是html
- 在有滾動的頁面中,absolute 會跟隨父元素進行滾動探橱,而 fixed 固定在某個位置
27. 如何解決 1px 問題申屹?
- 1px 問題的本質(zhì):在一些
Retina
屏幕上,移動端頁面的 1px 會變得很粗隧膏,所呈現(xiàn)出來不止是 1px 的效果哗讥,原因就是 CSS 中的 1px 不能和移動端的 1px 劃等號,他們之間是有一個比例關系私植。
window.devicePixelRatio = 設備的物理像素 / CSS像素。
- 解決方法:
- 直接寫 0.5px: 通過 js 拿到 window.devicePixelRatio 的值, 然后進行判斷處理(如果是 1车酣,則直接返回曲稼,否則 1 / window.devicePixelRatio),然后動態(tài)的設置 CSS 屬性中的值,以此來達到 1px 的效果湖员。
- 缺點:兼容性不行, andriod 直接不兼容贫悄,ios 需要 8.0 以上的版本
<div id="container" data-device={{window.devicePixelRatio}}></div>
- 通過偽元素
#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 縮放來解決
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
- 這里針對像素比為 2 的頁面娘摔,把整個頁面縮放為了原來的 1/2 大小窄坦。這樣,本來占用 2 個物理像素的 1px 樣式凳寺,現(xiàn)在占用的就是標準的一個物理像素鸭津。根據(jù)像素比的不同,這個縮放比例可以被計算為不同的值肠缨,用 js 代碼實現(xiàn)如下:
const scale = 1 / window.devicePixelRatio;
// 這里 metaEl 指的是 meta 標簽對應的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
- 缺點:整個頁面都會被縮放
28. 如何判斷元素進入可視區(qū)域逆趋?
- offsetTop、scrollTop
- getBoundingClientRect
- Intersection Observer
`window.innerHeight` 是瀏覽器可視區(qū)的高度晒奕;
`document.body.scrollTop || document.documentElement.scrollTop` 是瀏覽器滾動的過的距離闻书;
`imgs.offsetTop` 是元素頂部距離文檔頂部的高度(包括滾動條的距離);
內(nèi)容達到顯示區(qū)域的:`img.offsetTop < window.innerHeight + document.body.scrollTop;`
- 方式一:offsetTop脑慧、scrollTop
// 公式
el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
// 代碼實現(xiàn)
function isInViewPortOfOne (el) {
// viewPortHeight 兼容所有瀏覽器寫法
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
- 返回值是一個 DOMRect對象魄眉,擁有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:
// 如果一個元素在視窗之內(nèi)的話,那么它一定滿足下面四個條件:
// top 大于等于 0
// left 大于等于 0
// bottom 小于等于視窗高度
// right 小于等于視窗寬度
// 代碼實現(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 即重疊觀察者闷袒,從這個命名就可以看出它用于判斷兩個元素是否重疊坑律,因為不用進行事件的監(jiān)聽,性能方面相比getBoundingClientRect會好很多
- 使用步驟主要分為兩步:創(chuàng)建觀察者和傳入被觀察者
// 第一步:創(chuàng)建觀察者
const options = {
// 表示重疊面積占被觀察者的比例囊骤,從 0 - 1 取值脾歇,
// 1 表示完全被包含
threshold: 1.0,
root:document.querySelector('#scrollArea') // 必須是目標元素的父級元素
};
const callback = (entries, observer) => { ....}
const observer = new IntersectionObserver(callback, options);
// 通過new IntersectionObserver創(chuàng)建了觀察者 observer蒋腮,傳入的參數(shù) callback 在重疊比例超過 threshold 時會被執(zhí)行`
// 上段代碼中被省略的 callback
const callback = function(entries, observer) {
entries.forEach(entry => {
entry.time; // 觸發(fā)的時間
entry.rootBounds; // 根元素的位置矩形,這種情況下為視窗位置
entry.boundingClientRect; // 被觀察者的位置舉行
entry.intersectionRect; // 重疊區(qū)域的位置矩形
entry.intersectionRatio; // 重疊區(qū)域占被觀察者面積的比例(被觀察者不是矩形時也按照矩形計算)
entry.target; // 被觀察者
});
};
// 第二步:傳入被觀察者
const target = document.querySelector('.target');
observer.observe(target);
- 實現(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)聽
$(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 = '進入可視區(qū)域';
status_node.innerText = '進入可視區(qū)域';
console.log('進入可視區(qū)域');
}else{
box.innerText = '出去了';
status_node.innerText = '出去了';
}
})
});
intersectionObserver.observe(box);
})();
</script>
特殊字符描述:
- 問題標注
Q:(question)
- 答案標注
R:(result)
- 注意事項標準:
A:(attention matters)
- 詳情描述標注:
D:(detail info)
- 總結(jié)標注:
S:(summary)
- 分析標注:
Ana:(analysis)
- 提示標注:
T:(tips)