前端面試實錄CSS篇(最近一周)

前言

系列首發(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
    1. !important 例外紧唱,優(yōu)先級最高
    2. 內(nèi)聯(lián)樣式
    3. id 選擇器
    4. 類選擇器懈费,屬性選擇器,偽類選擇器
    5. 標簽選擇器伊滋,偽元素選擇器
    6. 子選擇器洋幻,后代選擇器郁轻,通配符選擇器
  • 選擇器權重

    • 參考 W3C: https://www.w3.org/TR/selectors/#specificity
    • 例子:./Demo/css_selector_and_priority.html

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

  • link: 鏈接外部資源的標簽鞋屈,此標簽決定了文檔與外部資源的關系,常用于鏈接樣式表(css)故觅,網(wǎng)頁站點圖標(favicon)厂庇。
    • 用法;<link rel="stylesheet,icon,image/png,shortlink,help,author,image/svg+xml" href="網(wǎng)絡路徑/相對路徑/絕對路徑"/>
    • 屬性:
      1. rel: 表示關系:realtionship,
      2. href: 網(wǎng)絡路徑/相對路徑/絕對路徑
      3. size: icon 的大小
      4. disabled: 僅對 rel = "stylesheet" 類型生效
  • 區(qū)別:
    1. 從屬差異:link 為 html 標簽输吏,可以加載 css, 也可以引入網(wǎng)站圖標(facaion), 定義 rel 鏈接屬性权旷,而 @import 是 css 提供,只能用于加載 css
    2. 加載差異:link 引用的 css,在頁面加載時同時加載。而 @import 在頁面加載完后才加載
    3. 兼容性:link 是 html 標簽拄氯,沒有兼容問題躲查。而 @ import 是 css2.1 提出的,IE5 以下的瀏覽器不支持译柏。
    4. 可操作性:link 可使用 js 來控制 DOM 去改變樣式镣煮,而 @import 不支持,因為 DOM 方法是基于文檔的鄙麦。
    5. 權重差異:
  • 在樣式中: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)]
  • 屬性:
    • 標準盒模型:box-sizing: content-box;
    • 怪異盒模型:box-sizing: border-box;

4. 隱藏元素的方法有哪些介衔?

  1. display: none;: 不會渲染該元素,不會占位骂因,也不會響應綁定的監(jiān)聽事件
  2. visibility: hidden;: 會渲染炎咖,但是不會顯示且會占位,也不會響應綁定的監(jiān)聽事件
  3. opacity: 0;: 將元素的透明度設置為 0, 以此來達到隱藏元素的效果寒波,會占位乘盼,能夠響應綁定的監(jiān)聽事件
  4. position: absolute;: 使用絕對定位將元素移除了可視區(qū)域外,不會占位影所,以此來實現(xiàn)元素的隱藏
  5. z-index:負值;: 使用其他元素將該元素隱藏,會占位
  6. clip:position:absolute; clip: rect(200px, 200px, 200px, 200px);/clip-path:clip-path: circle(0);: 使用元素裁切的
    方式實現(xiàn)元素隱藏蹦肴,會占位,不會響應綁定的監(jiān)聽事件
  7. transform: scale(0,0): 使用縮放猴娩,來實現(xiàn)元素的隱藏阴幌,會占位,但是不會響應綁定的監(jiān)聽事件
  8. 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 的條件:

    1. 根元素:html,body
    2. 浮動:float 除 none 以外的值
    3. 定位:position 為絕對定位(absoluate) 和 固定定位(fixed)
    4. dispaly 屬性:表格布局(grid: table-cell,table-caption) 和 flex(flex-items,flow-root) 布局
    5. multi column(多列布局): column
    6. overflow: 值為 hidden, auto, scroll
  • BFC 的特點:

    1. 垂直方向上,自上而下排列碧注,和文檔流的排列方式一致
    2. 在 BFC 中上下兩個相鄰的兩個容器的 margin 會重疊
    3. 計算 BFC 的高度時嚣伐,需要計算浮動元素的高度
    4. BFC 區(qū)域不會與浮動的容器發(fā)生重疊
    5. BFC 是獨立的容器,容器內(nèi)部的元素不會影響外部元素
    6. 每個元素的 margin-left 值和容器的 border-left 相接觸
  • BFC 的作用:

    1. 解決 margin 重疊問題:由于 BFC 是一個獨立的區(qū)域萍丐,內(nèi)部的元素和外部的元素互不影響轩端,將兩個元素變?yōu)閮蓚€ BFC,就解決了 margin 重疊的問題逝变。
    2. 解決高度塌陷問題:在對子元素設置浮動后基茵,父元素會發(fā)生高度塌陷,也就是父元素的高度變?yōu)?0壳影。解決這個問題拱层,只需要把父元素變成一個 BFC。常用的辦法是給父元素設置overflow:hidden宴咧。
    3. 創(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. 常見的圖片格式以及使用場景熏瞄?

  1. bmp: 無損的,此圖片格式不會對數(shù)據(jù)進行壓縮谬以,所以 bmp 格式的圖片通常都是較大文件
  2. git: 無損的强饮,特點是文件小,適用場景:對色彩要求不高且文件體積較小
  3. jpeg,jpg: 有損的为黎,有損壓縮會導致圖片模糊邮丰,文件類型比 gif 較大
  4. png-8:無損的,png-8 比 gif 文件還小
  5. png-24: 無損的铭乾,優(yōu)點在于壓縮了圖片數(shù)據(jù)
  6. svg: 無損矢量圖剪廉,放大不會失真,適用場景:繪制 LOGO, Icon
  7. webp: 同時支持有損和無損炕檩,同質(zhì)量的圖片斗蒋,webp 擁有更小的文件體積,更好地提升用戶體驗笛质,
  • 在無損壓縮情況下:相同質(zhì)量的 webp 圖片泉沾,要比 png 小 26%
  • 在有損壓縮情況下,具有相同精度的 webp 圖片妇押,文件大小要比 jpeg 小 25%~34%
  • webp 還支持圖片透明度跷究,一個無損壓縮的 webp 圖片,想要支持透明度敲霍,只需要 22% 的格外文件大小俊马。

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

  • 加載性能
    1. css 壓縮
    2. 減少使用屬性簡寫方式
    3. 減少使用 @import色冀,建議使用 link,
  • 選擇器性能
    1. 減少選擇器嵌套層級
    2. 使用關鍵的選擇器潭袱,不要逐層進行選擇
  • 渲染性能
    1. 慎重使用浮動和定位
    2. 盡量減少重繪和回流的發(fā)生
    3. 刪除空規(guī)則,也就是預留樣式->{}
    4. 屬性值為浮點值時,省略前面的 0
    5. 不要使用 @import 前綴引用樣式锋恬,會影響 css 加載速度
    6. 避免選擇器嵌套過深
    7. 不濫用 web 字體
  • 可維護性屯换,健壯性
    1. 抽離公共樣式
    2. 樣式與內(nèi)容分離

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

  1. 單冒號(:)表示偽類与学,雙冒號(::)表示偽元素
  2. 在 CSS2.1 中彤悔,偽元素都是使用 單冒號 來表示偽元素的,但在 CSS3 規(guī)范中索守,偽元素的語法被修改為使用 雙冒號

17. CSS 預處理器/后處理器是什么晕窑?為什么要使用他們?

  • 預處理器:less, sass, styuls卵佛,它們增加了 css 代碼的復用性杨赤,例如:變量敞斋,循環(huán),方法等
  • 后處理器:postcss疾牲,最常做的是給 css 代碼添加瀏覽器前綴植捎,實現(xiàn)跨瀏覽器兼容性的問題、
  • 為什么要使用他們阳柔?
    1. 結(jié)構清晰焰枢,便于擴展
    2. 屏蔽瀏覽器私有語法的差異
    3. 使用多重繼承
    4. 提到 css 代碼的兼容性

18. z-index 會在什么情況下會失效?

  • 作用及含義:設置元素的堆疊順序舌剂,值越大就越在上層
  • 檢查以下情況:
    1. 該元素是否設置了定位
    2. 該元素的父級是否已經(jīng)設置了z-index(檢查需比較的元素是否同在一個層疊上下文)
  • z-index 屬性會在下列情況中會失效:
    1. 在設置 z-index 的元素上必須含有 position 屬性為非 static 屬性值(relative,absolute,fixed)济锄。
    2. 同一個父級元素下的元素層疊效果是受父級影響的,就是說如果你的父級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 的較大值

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. 水平垂直居中的方式雕擂?

  1. flex 布局
.parent {
    display: flex;
    justify-content:center;
    align-items:center;
}
  1. 絕對定位 + margin
.parent {
    position: relative;
}

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;     /* 自身 height 的一半 */
    margin-left: -50px;    /* 自身 width 的一半 */
}
  1. 絕對定位
.parent {
    position: relative;
}

.child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
  1. 絕對定位 + 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)]

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像素。
  • 解決方法:
  1. 直接寫 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>
  1. 通過偽元素
#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;
}
  • 缺點:代碼較多,但兼容性好
  1. 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ū)域逆趋?

  1. offsetTop、scrollTop
  2. getBoundingClientRect
  3. 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>

特殊字符描述:

  1. 問題標注 Q:(question)
  2. 答案標注 R:(result)
  3. 注意事項標準:A:(attention matters)
  4. 詳情描述標注:D:(detail info)
  5. 總結(jié)標注:S:(summary)
  6. 分析標注:Ana:(analysis)
  7. 提示標注:T:(tips)
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藕各,一起剝皮案震驚了整個濱河市池摧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌激况,老刑警劉巖作彤,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乌逐,居然都是意外死亡竭讳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門浙踢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绢慢,“玉大人,你說我怎么就攤上這事洛波∫扔撸” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵蹬挤,是天一觀的道長缚窿。 經(jīng)常有香客問我,道長焰扳,這世上最難降的妖魔是什么倦零? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮吨悍,結(jié)果婚禮上扫茅,老公的妹妹穿的比我還像新娘。我一直安慰自己育瓜,他們只是感情好诞帐,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爆雹,像睡著了一般停蕉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钙态,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天慧起,我揣著相機與錄音,去河邊找鬼册倒。 笑死蚓挤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灿意,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼估灿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缤剧?” 一聲冷哼從身側(cè)響起馅袁,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荒辕,沒想到半個月后汗销,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡抵窒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年弛针,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片李皇。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡削茁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掉房,到底是詐尸還是另有隱情茧跋,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布圃阳,位于F島的核電站厌衔,受9級特大地震影響璧帝,放射性物質(zhì)發(fā)生泄漏捍岳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一睬隶、第九天 我趴在偏房一處隱蔽的房頂上張望锣夹。 院中可真熱鬧,春花似錦苏潜、人聲如沸银萍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贴唇。三九已至,卻和暖如春飞袋,著一層夾襖步出監(jiān)牢的瞬間戳气,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工巧鸭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓶您,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像呀袱,于是被迫代替她去往敵國和親贸毕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容