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

前言

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

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

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ì)路徑"/>
    • 屬性:
      1. rel: 表示關(guān)系:realtionship,
      2. href: 網(wǎng)絡(luò)路徑/相對(duì)路徑/絕對(duì)路徑
      3. size: icon 的大小
      4. disabled: 僅對(duì) rel = "stylesheet" 類型生效
  • 區(qū)別:
    1. 從屬差異:link 為 html 標(biāo)簽,可以加載 css, 也可以引入網(wǎng)站圖標(biāo)(facaion), 定義 rel 鏈接屬性,而 @import 是 css 提供,只能用于加載 css
    2. 加載差異:link 引用的 css,在頁(yè)面加載時(shí)同時(shí)加載。而 @import 在頁(yè)面加載完后才加載
    3. 兼容性:link 是 html 標(biāo)簽,沒(méi)有兼容問(wèn)題。而 @ import 是 css2.1 提出的,IE5 以下的瀏覽器不支持。
    4. 可操作性:link 可使用 js 來(lái)控制 DOM 去改變樣式,而 @import 不支持,因?yàn)?DOM 方法是基于文檔的。
    5. 權(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)盒模型:box-sizing: content-box;
    • 怪異盒模型:box-sizing: border-box;

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

  1. display: none;: 不會(huì)渲染該元素,不會(huì)占位,也不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件
  2. visibility: hidden;: 會(huì)渲染,但是不會(huì)顯示且會(huì)占位,也不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件
  3. opacity: 0;: 將元素的透明度設(shè)置為 0, 以此來(lái)達(dá)到隱藏元素的效果,會(huì)占位,能夠響應(yīng)綁定的監(jiān)聽(tīng)事件
  4. position: absolute;: 使用絕對(duì)定位將元素移除了可視區(qū)域外,不會(huì)占位,以此來(lái)實(shí)現(xiàn)元素的隱藏
  5. z-index:負(fù)值;: 使用其他元素將該元素隱藏,會(huì)占位
  6. 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)事件
  7. transform: scale(0,0): 使用縮放,來(lái)實(shí)現(xiàn)元素的隱藏,會(huì)占位,但是不會(huì)響應(yīng)綁定的監(jiān)聽(tīng)事件
  8. 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 的條件:

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

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

    1. 解決 margin 重疊問(wèn)題:由于 BFC 是一個(gè)獨(dú)立的區(qū)域,內(nèi)部的元素和外部的元素互不影響,將兩個(gè)元素變?yōu)閮蓚€(gè) BFC,就解決了 margin 重疊的問(wèn)題。
    2. 解決高度塌陷問(wèn)題:在對(duì)子元素設(shè)置浮動(dòng)后,父元素會(huì)發(fā)生高度塌陷,也就是父元素的高度變?yōu)?0。解決這個(gè)問(wèn)題,只需要把父元素變成一個(gè) BFC。常用的辦法是給父元素設(shè)置overflow:hidden。
    3. 創(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)景?

  1. bmp: 無(wú)損的,此圖片格式不會(huì)對(duì)數(shù)據(jù)進(jìn)行壓縮,所以 bmp 格式的圖片通常都是較大文件
  2. git: 無(wú)損的,特點(diǎn)是文件小,適用場(chǎng)景:對(duì)色彩要求不高且文件體積較小
  3. jpeg,jpg: 有損的,有損壓縮會(huì)導(dǎo)致圖片模糊,文件類型比 gif 較大
  4. png-8:無(wú)損的,png-8 比 gif 文件還小
  5. png-24: 無(wú)損的,優(yōu)點(diǎn)在于壓縮了圖片數(shù)據(jù)
  6. svg: 無(wú)損矢量圖,放大不會(huì)失真,適用場(chǎng)景:繪制 LOGO, Icon
  7. 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)化和提高性能的方法有哪些?

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

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

  1. 單冒號(hào)(:)表示偽類,雙冒號(hào)(::)表示偽元素
  2. 在 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)題、
  • 為什么要使用他們?
    1. 結(jié)構(gòu)清晰,便于擴(kuò)展
    2. 屏蔽瀏覽器私有語(yǔ)法的差異
    3. 使用多重繼承
    4. 提到 css 代碼的兼容性

18. z-index 會(huì)在什么情況下會(huì)失效?

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

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

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

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

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

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像素。
  • 解決方法:
  1. 直接寫(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>
  1. 通過(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):代碼較多,但兼容性好
  1. 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ū)域?

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

特殊字符描述:

  1. 問(wèn)題標(biāo)注 Q:(question)
  2. 答案標(biāo)注 R:(result)
  3. 注意事項(xiàng)標(biāo)準(zhǔn):A:(attention matters)
  4. 詳情描述標(biāo)注:D:(detail info)
  5. 總結(jié)標(biāo)注:S:(summary)
  6. 分析標(biāo)注:Ana:(analysis)
  7. 提示標(biāo)注:T:(tips)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. BFC機(jī)制 BFC(Block Formatting Context),塊級(jí)格式化上下文,是一個(gè)獨(dú)立的渲染區(qū)...
    寫(xiě)代碼的胖猴子閱讀 1,797評(píng)論 0 0
  • 1.實(shí)現(xiàn)不使用 border 畫(huà)出 1px 高的線,在不同瀏覽器的標(biāo)準(zhǔn)模式與兼容模式下都能保持一致的效果。 2.介...
    蒙面超人zrh閱讀 428評(píng)論 0 1
  • CSS 1、介紹一下標(biāo)準(zhǔn)的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有兩種,IE盒子模型、W3C...
    京程一燈閱讀 1,787評(píng)論 3 26
  • 介紹一下標(biāo)準(zhǔn)的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有兩種, IE 盒子模型、W3C 盒子模...
    無(wú)目的閱讀 407評(píng)論 0 1
  • HTML+CSS 1.講一下盒模型,普通盒模型和怪異盒模型有什么區(qū)別? 答:盒模型本質(zhì)就是一個(gè)盒子,包括邊距,邊框...
    Submarine_2ab7閱讀 441評(píng)論 0 0

友情鏈接更多精彩內(nèi)容