Skip to content
📖预计阅读时长:0 分钟字数:0

前端大厂面试 —— HTML5 & CSS 高频面试题

本文整理了字节跳动、腾讯、阿里巴巴、美团等一线互联网大厂前端面试中高频出现的 HTML5 与 CSS 问题,涵盖基础概念、布局方案、性能优化、新特性等核心知识点。


一、HTML5 篇

1. HTML5 有哪些新特性?

高频指数:⭐⭐⭐⭐⭐

HTML5 的新特性主要包括以下几类:

  • 语义化标签<header><nav><main><article><section><aside><footer><figure><figcaption>
  • 多媒体支持<video><audio> 原生支持音视频播放
  • 图形绘制<canvas> 2D 绘图、内联 SVG 支持
  • 表单增强:新增 dateemailurlrangenumbersearchcolor 等 input 类型,以及 placeholderrequiredpatternautofocus 等属性
  • 本地存储localStoragesessionStorage 替代 Cookie 进行本地数据存储
  • 离线应用:Application Cache(已废弃)、Service Worker
  • WebSocket:支持全双工通信
  • Web Worker:多线程后台运算
  • 地理定位:Geolocation API
  • 拖放 API:原生 Drag and Drop
  • History APIpushStatereplaceState 实现无刷新跳转

2. 如何理解 HTML 语义化?

高频指数:⭐⭐⭐⭐⭐

什么是语义化: 根据内容的结构和含义,选择合适的标签来构建页面,让标签本身就能表达内容的意义。

为什么要语义化:

  1. 对开发者友好:代码结构清晰,增强可读性,便于团队协作和维护
  2. 对机器友好:搜索引擎爬虫能更好地理解页面结构,有利于 SEO
  3. 对用户友好:屏幕阅读器等辅助设备能正确解析内容,提升无障碍访问体验
  4. 样式丢失可读:即使没有 CSS,页面也能呈现良好的内容结构

常用语义化标签:

标签语义
<header>页眉/头部区域
<nav>导航链接区域
<main>页面主要内容(唯一)
<article>独立的文章内容
<section>文档中的章节
<aside>侧边栏/附属内容
<footer>页脚区域
<figure> / <figcaption>图片/图表及其标题
<mark>高亮文本
<time>时间/日期
<details> / <summary>折叠/展开内容

3. DOCTYPE 的作用是什么?

高频指数:⭐⭐⭐⭐

<!DOCTYPE html> 声明位于文档最前面,用于告诉浏览器以哪种标准来解析文档。

  • 标准模式(Standards Mode):浏览器按照 W3C 标准解析渲染页面
  • 怪异模式(Quirks Mode):浏览器模拟老旧浏览器的行为来渲染页面,向后兼容

如果不声明 DOCTYPE,浏览器会进入怪异模式,可能导致不同浏览器下渲染结果不一致。

HTML5 只需要简单地声明 <!DOCTYPE html> 即可。


4. 行内元素、块级元素、行内块元素有什么区别?

高频指数:⭐⭐⭐⭐⭐

特性块级元素行内元素行内块元素
独占一行✅ 是❌ 否❌ 否
设置宽高✅ 有效❌ 无效✅ 有效
默认宽度父容器 100%内容撑开内容撑开
margin/padding四个方向均有效水平方向有效,垂直方向不影响布局四个方向均有效
常见标签divph1-h6ulliformspanastrongemimginputimginputbuttonselecttextarea

转换方式:

css
display: block;        /* 转为块级 */
display: inline;       /* 转为行内 */
display: inline-block; /* 转为行内块 */

5. src 和 href 的区别?

高频指数:⭐⭐⭐

  • src(source):引入外部资源并替换当前元素。浏览器解析到 src 时会暂停其他资源的处理,直到该资源加载、编译、执行完毕(阻塞)。常用于 <script><img><iframe>
  • href(hypertext reference):建立当前文档与引用资源之间的链接关系。浏览器会并行下载资源,不会阻塞文档解析。常用于 <a><link>

这就是为什么建议把 <script> 放在 <body> 底部或使用 defer/async 属性。


6. script 标签中 defer 和 async 的区别?

高频指数:⭐⭐⭐⭐⭐

三种加载方式的对比:

html
<script src="script.js"></script>             <!-- 默认:阻塞解析 -->
<script src="script.js" async></script>       <!-- 异步加载,加载完立即执行 -->
<script src="script.js" defer></script>       <!-- 异步加载,DOMContentLoaded 前执行 -->
属性下载方式执行时机执行顺序适用场景
阻塞 HTML 解析下载完立即执行按书写顺序需要立即执行的脚本
async并行下载下载完立即执行(中断解析)不保证顺序独立脚本(如统计、广告)
defer并行下载HTML 解析完毕后、DOMContentLoaded 之前按书写顺序依赖 DOM 的脚本

7. 说说对 Web Worker 的理解?

高频指数:⭐⭐⭐

JavaScript 是单线程的,Web Worker 允许在后台线程中运行脚本,不会阻塞主线程的 UI 渲染。

特点:

  • 运行在独立线程中,不影响页面性能
  • 不能直接操作 DOM
  • 通过 postMessageonmessage 与主线程通信
  • 同源限制
javascript
// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ data: 'hello' });
worker.onmessage = (e) => {
  console.log('收到 Worker 返回的数据:', e.data);
};

// worker.js
self.onmessage = (e) => {
  const result = heavyCalculation(e.data);
  self.postMessage(result);
};

高频指数:⭐⭐⭐⭐⭐

特性CookielocalStoragesessionStorage
存储大小约 4KB约 5MB约 5MB
生命周期可设置过期时间永久存储,除非手动清除会话结束(标签页关闭)即清除
与服务器通信每次请求自动携带在 HTTP 头中不参与通信不参与通信
作用域同源 + 同路径同源同源 + 同标签页
API 易用性需手动解析字符串getItem/setItem 简洁同 localStorage
适用场景身份认证、用户偏好持久化数据(主题、Token)临时数据(表单草稿)

9. 什么是 Canvas?Canvas 和 SVG 的区别?

高频指数:⭐⭐⭐⭐

Canvas 是 HTML5 新增的绘图元素,通过 JavaScript 操作 Canvas API 在画布上绘制 2D 图形。

特性CanvasSVG
绘制方式通过 JavaScript 逐像素绘制使用 XML 描述 2D 图形
渲染方式位图(像素)矢量图
事件处理不支持为单独图形绑定事件每个元素都可绑定事件
缩放放大会失真任意缩放不失真
性能适合大量像素操作(游戏、数据可视化)适合少量图形、图标
DOM不生成 DOM 元素每个图形都是 DOM 元素
适用场景游戏、图像处理、实时图表图标、Logo、地图、可交互图形

10. 如何实现浏览器内多个标签页之间的通信?

高频指数:⭐⭐⭐⭐

  1. localStorage + storage 事件监听(最常用)
javascript
// 页面 A:写入数据
localStorage.setItem('message', JSON.stringify({ data: 'hello', timestamp: Date.now() }));

// 页面 B:监听变化
window.addEventListener('storage', (e) => {
  if (e.key === 'message') {
    console.log('收到消息:', JSON.parse(e.newValue));
  }
});
  1. BroadcastChannel API
javascript
const channel = new BroadcastChannel('my_channel');
channel.postMessage('hello');       // 发送
channel.onmessage = (e) => { ... } // 接收
  1. SharedWorker
  2. WebSocket(服务端中转)
  3. postMessage(需要有对目标窗口的引用)

11. HTML5 的离线存储怎么使用?原理是什么?

高频指数:⭐⭐⭐

HTML5 离线存储主要有两种方案:

方案一:Application Cache(已废弃,了解即可)

通过 manifest 文件声明需要缓存的资源,浏览器会自动缓存。

方案二:Service Worker(推荐)

Service Worker 是运行在浏览器后台的独立线程,可以拦截网络请求、管理缓存,实现离线访问。

javascript
// 注册 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

// sw.js
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('v1').then((cache) => {
      return cache.addAll(['/index.html', '/styles.css', '/app.js']);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    })
  );
});

12. 说说对 HTML5 拖放 API 的理解?

高频指数:⭐⭐⭐

拖放的核心流程和事件:

事件触发对象说明
dragstart被拖元素开始拖动时触发
drag被拖元素拖动过程中持续触发
dragend被拖元素拖动结束时触发
dragenter目标元素拖入目标区域时触发
dragover目标元素在目标区域内移动时持续触发
dragleave目标元素离开目标区域时触发
drop目标元素在目标区域释放时触发

关键点: 必须在 dragover 中调用 e.preventDefault() 才能触发 drop 事件。


二、CSS 篇

13. 说说 CSS 盒模型?

高频指数:⭐⭐⭐⭐⭐

每个 HTML 元素都可以看作一个矩形盒子,由四部分组成:content(内容)→ padding(内边距)→ border(边框)→ margin(外边距)

两种盒模型:

css
/* 标准盒模型(W3C):width/height 只包含 content */
box-sizing: content-box;  /* 默认值 */

/* IE 盒模型(怪异盒模型):width/height 包含 content + padding + border */
box-sizing: border-box;   /* 实际开发常用 */

实际开发中的最佳实践:

css
*, *::before, *::after {
  box-sizing: border-box;
}

14. CSS 选择器有哪些?优先级如何计算?

高频指数:⭐⭐⭐⭐⭐

常见选择器:

类别选择器示例
通用选择器**
元素选择器elementdiv
类选择器.class.container
ID 选择器#id#app
属性选择器[attr=value][type="text"]
后代选择器A Bdiv p
子选择器A > Bul > li
相邻兄弟选择器A + Bh1 + p
通用兄弟选择器A ~ Bh1 ~ p
伪类选择器:pseudo:hover:nth-child()
伪元素选择器::pseudo::before::after

优先级权重(从高到低):

  1. !important(最高,慎用)
  2. 内联样式(style=""):1,0,0,0
  3. ID 选择器:0,1,0,0
  4. 类/伪类/属性选择器:0,0,1,0
  5. 元素/伪元素选择器:0,0,0,1
  6. 通配符/继承:0,0,0,0

口诀: !important > 内联 > ID > 类 > 元素 > 继承/通配


15. CSS 中可继承与不可继承的属性有哪些?

高频指数:⭐⭐⭐

可继承属性:

  • 字体相关:font-familyfont-sizefont-weightfont-style
  • 文本相关:colortext-aligntext-indentline-heightletter-spacingword-spacing
  • 可见性:visibility
  • 光标:cursor
  • 列表:list-style

不可继承属性:

  • 盒模型:widthheightmarginpaddingborder
  • 背景:background
  • 定位:positiontopleftrightbottom
  • 布局:displayfloatclearoverflow
  • 弹性/网格:flexgrid 相关属性

16. 说说 BFC(块级格式化上下文)?

高频指数:⭐⭐⭐⭐⭐

BFC(Block Formatting Context) 是一个独立的渲染区域,内部元素的布局不会影响外部元素。

触发 BFC 的条件:

  • overflow 不为 visible(如 hiddenautoscroll
  • displayinline-blockflexinline-flexgridtable-cell
  • positionabsolutefixed
  • float 不为 none
  • 根元素 <html>

BFC 的应用场景:

  1. 解决 margin 重叠问题
html
<!-- 两个 BFC 之间的 margin 不会重叠 -->
<div style="overflow: hidden;">
  <p style="margin-bottom: 20px;">段落1</p>
</div>
<div style="overflow: hidden;">
  <p style="margin-top: 20px;">段落2</p>
</div>
  1. 清除浮动
css
.clearfix {
  overflow: hidden; /* 触发 BFC,包含浮动子元素 */
}
  1. 阻止元素被浮动元素覆盖(自适应两栏布局)
css
.left { float: left; width: 200px; }
.right { overflow: hidden; } /* 触发 BFC,不会与浮动元素重叠 */

17. 实现水平垂直居中的方式有哪些?

高频指数:⭐⭐⭐⭐⭐

方法一:Flex 布局(最推荐)

css
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

方法二:Grid 布局

css
.parent {
  display: grid;
  place-items: center;
}

方法三:绝对定位 + transform

css
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

方法四:绝对定位 + margin auto(已知宽高)

css
.child {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  margin: auto;
  width: 200px;
  height: 200px;
}

方法五:绝对定位 + 负 margin(已知宽高)

css
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 200px;
  margin-top: -100px;
  margin-left: -100px;
}

方法六:行内元素水平垂直居中

css
.parent {
  text-align: center;
  line-height: 200px; /* 等于容器高度 */
  height: 200px;
}

18. 如何实现两栏布局?三栏布局(圣杯/双飞翼)?

高频指数:⭐⭐⭐⭐⭐

两栏布局(左固定 + 右自适应)

Flex 方案:

css
.container { display: flex; }
.left { width: 200px; flex-shrink: 0; }
.right { flex: 1; }

浮动 + BFC 方案:

css
.left { float: left; width: 200px; }
.right { overflow: hidden; } /* 触发 BFC */

三栏布局(左右固定 + 中间自适应)

Flex 方案(最推荐):

css
.container { display: flex; }
.left { width: 200px; flex-shrink: 0; }
.center { flex: 1; }
.right { width: 200px; flex-shrink: 0; }

圣杯布局:

css
.container { padding: 0 200px; }
.center { float: left; width: 100%; }
.left {
  float: left; width: 200px;
  margin-left: -100%;
  position: relative; left: -200px;
}
.right {
  float: left; width: 200px;
  margin-left: -200px;
  position: relative; right: -200px;
}

双飞翼布局:

css
.center { float: left; width: 100%; }
.center-inner { margin: 0 200px; }
.left { float: left; width: 200px; margin-left: -100%; }
.right { float: left; width: 200px; margin-left: -200px; }

19. 说说 Flex 弹性布局?

高频指数:⭐⭐⭐⭐⭐

Flex 布局的核心概念是 主轴(main axis)交叉轴(cross axis)

容器属性(设置在父元素上):

属性说明常用值
flex-direction主轴方向rowcolumnrow-reversecolumn-reverse
flex-wrap是否换行nowrapwrapwrap-reverse
justify-content主轴对齐flex-startcenterspace-betweenspace-aroundspace-evenly
align-items交叉轴对齐flex-startcenterflex-endstretchbaseline
align-content多行交叉轴对齐justify-content
gap子项间距10px10px 20px

子项属性:

属性说明默认值
flex-grow放大比例0(不放大)
flex-shrink缩小比例1(自动缩小)
flex-basis初始主轴尺寸auto
align-self单独的交叉轴对齐auto
order排列顺序0

常用简写:

css
flex: 1;           /* flex: 1 1 0%   —— 等分剩余空间 */
flex: auto;        /* flex: 1 1 auto —— 按内容分配 */
flex: none;        /* flex: 0 0 auto —— 不伸缩 */
flex: 0 0 200px;   /* 固定 200px,不伸缩 */

20. 说说 Grid 网格布局?

高频指数:⭐⭐⭐⭐

Grid 是二维布局系统,可以同时控制行和列。

css
.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;   /* 三列:固定-自适应-固定 */
  grid-template-rows: 80px 1fr 60px;         /* 三行:头-内容-尾 */
  gap: 10px;                                  /* 网格间距 */
}

/* 子项跨行/列 */
.item {
  grid-column: 1 / 3;  /* 从第1条网格线到第3条 */
  grid-row: 1 / 2;
}

常用函数:

  • repeat(3, 1fr):重复三列等分
  • minmax(200px, 1fr):最小 200px,最大自适应
  • auto-fill / auto-fit:自动填充列数

Grid vs Flex:

维度FlexGrid
布局方向一维(行或列)二维(行和列同时)
适用场景组件内部布局、导航栏页面整体布局、复杂网格
控制方式基于内容流基于网格线精确控制

21. CSS 中的定位方式有哪些?

高频指数:⭐⭐⭐⭐⭐

定位方式说明是否脱离文档流定位基准
static默认值,正常文档流
relative相对定位否(保留原始空间)自身原始位置
absolute绝对定位最近的非 static 祖先元素
fixed固定定位浏览器视口
sticky粘性定位滚动容器,超过阈值后表现为 fixed

sticky 使用注意事项:

css
.sticky-header {
  position: sticky;
  top: 0;  /* 必须指定至少一个阈值 */
}
  • 父元素不能设置 overflow: hiddenoverflow: auto
  • 粘性定位的范围被限制在父容器的 content 区域内

22. 如何清除浮动?

高频指数:⭐⭐⭐⭐

浮动元素脱离文档流,会导致父元素高度塌陷。

方法一:clearfix 伪元素(最推荐)

css
.clearfix::after {
  content: '';
  display: block;
  clear: both;
}

方法二:触发 BFC

css
.parent {
  overflow: hidden;  /* 或 auto */
}

方法三:额外标签法

html
<div style="clear: both;"></div>

方法四:使用 Flex / Grid 替代浮动(现代方案)

css
.parent {
  display: flex; /* 直接用 Flex 布局,不再需要 float */
}

23. CSS 中 display、visibility、opacity 隐藏元素的区别?

高频指数:⭐⭐⭐⭐⭐

属性display: nonevisibility: hiddenopacity: 0
是否占据空间❌ 不占据✅ 占据✅ 占据
是否触发事件❌ 不触发❌ 不触发✅ 可触发
是否影响子元素子元素一同消失子元素可通过 visibility: visible 单独显示子元素一同透明
是否触发重排✅ 触发❌ 仅重绘❌ 仅重绘
过渡动画❌ 不支持✅ 支持✅ 支持
无障碍屏幕阅读器忽略屏幕阅读器忽略屏幕阅读器可读

24. 说说对重绘(Repaint)和重排/回流(Reflow)的理解?

高频指数:⭐⭐⭐⭐⭐

重排(Reflow): 当元素的几何属性(位置、尺寸)发生变化时,浏览器需要重新计算元素的布局,然后重新渲染。

重绘(Repaint): 当元素的外观(颜色、背景、阴影等)发生变化,但不影响布局时,浏览器只需要重新绘制受影响的部分。

重排一定触发重绘,但重绘不一定触发重排。

触发重排的操作:

  • 修改元素尺寸(widthheightpaddingmarginborder
  • 修改元素位置(topleft
  • 修改 DOM 结构(增删节点)
  • 读取布局信息(offsetWidthclientHeightgetComputedStyle()
  • 窗口大小变化

性能优化建议:

  1. 批量修改样式,使用 class 切换而非逐个修改
  2. 使用 transform 代替 top/left 做动画(不触发重排)
  3. 使用 will-change 提示浏览器优化
  4. 将频繁重排的元素脱离文档流(position: absolute/fixed
  5. 读取布局属性时做缓存,避免反复读取
css
/* 优化前:触发重排 */
.box { top: 100px; left: 100px; }

/* 优化后:不触发重排,GPU 加速 */
.box { transform: translate(100px, 100px); }

25. CSS 如何实现响应式设计?

高频指数:⭐⭐⭐⭐⭐

核心手段:

  1. 媒体查询(Media Query)
css
/* 移动优先 */
.container { width: 100%; }

@media screen and (min-width: 768px) {
  .container { width: 750px; }
}

@media screen and (min-width: 1200px) {
  .container { width: 1170px; }
}
  1. 弹性布局(Flex / Grid)
  2. 相对单位%rememvwvhvminvmax
  3. 弹性图片max-width: 100%; height: auto;
  4. 视口设置<meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. CSS 容器查询(Container Query)—— 新特性
css
.card-container {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card { flex-direction: row; }
}

常见断点:

设备宽度
手机< 768px
平板768px - 1024px
桌面> 1024px
大屏> 1200px

26. CSS 中 em、rem、vw、vh 等单位的区别?

高频指数:⭐⭐⭐⭐

单位参考基准说明
px绝对单位像素
em父元素 font-size相对父元素,会层层叠加
rem根元素(html)font-size相对根元素,全局统一
%父元素对应属性宽度相对父元素宽度,字号相对父元素字号
vw视口宽度的 1%100vw = 视口宽度
vh视口高度的 1%100vh = 视口高度
vminvwvh 中的较小值适合保持比例
vmaxvwvh 中的较大值适合保持比例

最佳实践:<html> 上设置 font-size: 62.5%(即 10px),然后全局使用 rem 单位:

css
html { font-size: 62.5%; }   /* 1rem = 10px */
body { font-size: 1.6rem; }  /* 16px */
h1   { font-size: 2.4rem; }  /* 24px */

27. 说说伪类和伪元素的区别?

高频指数:⭐⭐⭐⭐

伪类(Pseudo-class): 用于选择元素的某种状态,以单冒号 : 表示。

css
a:hover { color: red; }          /* 鼠标悬停状态 */
li:first-child { ... }           /* 第一个子元素 */
input:focus { ... }              /* 获得焦点 */
li:nth-child(2n) { ... }        /* 偶数子元素 */

伪元素(Pseudo-element): 用于创建不在 DOM 中的虚拟元素,以双冒号 :: 表示。

css
p::before { content: '👉'; }    /* 在元素内容前插入 */
p::after  { content: ''; }      /* 在元素内容后插入 */
p::first-line { ... }           /* 第一行 */
p::first-letter { ... }         /* 首字母 */
input::placeholder { ... }      /* 占位符 */
::selection { ... }             /* 选中文本 */

核心区别:

  • 伪类选择的是已有元素的特定状态
  • 伪元素创建的是文档中本不存在的"虚拟"元素

28. CSS3 有哪些新特性?

高频指数:⭐⭐⭐⭐

类别新特性
选择器:nth-child():not()::placeholder、属性选择器增强
边框border-radiusbox-shadowborder-image
背景background-sizebackground-originbackground-clip、多重背景
渐变linear-gradientradial-gradientconic-gradient
文字text-shadowword-wraptext-overflow@font-face
2D/3D 变换transformtranslaterotatescaleskewperspective
过渡transition
动画@keyframesanimation
弹性布局display: flex
网格布局display: grid
多列布局column-countcolumn-gap
滤镜filterbackdrop-filter
自定义属性CSS 变量 --var-namevar()
媒体查询@media 增强
容器查询@container(较新)
混合模式mix-blend-modebackground-blend-mode

29. 如何用纯 CSS 实现三角形?

高频指数:⭐⭐⭐⭐

原理: 利用 border 的实现机制——当元素宽高为 0 时,四条边框以三角形形式拼接。

css
/* 向上的三角形 */
.triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid #333;
}

/* 向右的三角形 */
.triangle-right {
  width: 0;
  height: 0;
  border-top: 50px solid transparent;
  border-bottom: 50px solid transparent;
  border-left: 100px solid #333;
}

现代方案:使用 clip-path

css
.triangle {
  width: 100px;
  height: 100px;
  background: #333;
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

30. 如何实现 CSS 动画?transition 和 animation 的区别?

高频指数:⭐⭐⭐⭐

transition(过渡): 需要事件触发(如 hover),从状态 A 到状态 B 的变化。

css
.box {
  width: 100px;
  transition: width 0.3s ease-in-out;
}
.box:hover {
  width: 200px;
}

animation(动画): 可自动执行,支持多个关键帧,更灵活。

css
@keyframes slide {
  0%   { transform: translateX(0); }
  50%  { transform: translateX(200px); }
  100% { transform: translateX(0); }
}

.box {
  animation: slide 2s ease-in-out infinite;
}
特性transitionanimation
触发方式需要事件触发(hover等)可自动播放
关键帧只有起始和结束两个状态可定义多个关键帧
循环播放不支持支持 infinite
暂停控制不支持animation-play-state
JS 事件transitionendanimationstart/animationend/animationiteration

31. 说说 CSS 变量(自定义属性)?

高频指数:⭐⭐⭐

css
/* 定义变量 */
:root {
  --primary-color: #409eff;
  --font-size-base: 16px;
  --spacing: 8px;
}

/* 使用变量 */
.button {
  background-color: var(--primary-color);
  font-size: var(--font-size-base);
  padding: var(--spacing) calc(var(--spacing) * 2);
}

/* 带默认值 */
.text {
  color: var(--text-color, #333);
}

/* 通过 JS 动态修改 */
javascript
document.documentElement.style.setProperty('--primary-color', '#ff6700');

应用场景: 主题切换、暗黑模式、Design Token 管理。


32. 如何实现移动端 1px 边框?

高频指数:⭐⭐⭐⭐

在高倍屏(dpr >= 2)下,CSS 的 1px 会被渲染为物理像素的 2px 或 3px,看起来偏粗。

方案一:伪元素 + transform 缩放(最常用)

css
.border-1px {
  position: relative;
}
.border-1px::after {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 200%;
  height: 200%;
  border: 1px solid #ddd;
  transform: scale(0.5);
  transform-origin: left top;
  box-sizing: border-box;
  pointer-events: none;
  border-radius: inherit;
}

方案二:使用 box-shadow

css
.border-1px {
  box-shadow: 0 0 0 0.5px #ddd;
}

方案三:border-image + SVG

方案四:设置 viewport 的 initial-scale


33. CSS 性能优化有哪些方法?

高频指数:⭐⭐⭐⭐

  1. 选择器优化

    • 避免使用通配符 *
    • 避免深层嵌套(不超过 3 层)
    • 避免使用标签选择器限定类选择器(如 div.header
  2. 减少重绘重排

    • 使用 transform 代替 top/left
    • 使用 opacity 代替 visibility
    • 批量修改 DOM,使用文档碎片或离线 DOM
  3. 资源优化

    • 压缩 CSS 文件
    • 使用 CSS Sprites(精灵图)减少请求
    • 合理使用 @import(会阻塞加载,建议用 <link>
  4. 渲染优化

    • 使用 will-change 提示浏览器做 GPU 加速
    • 使用 contain 属性限制重排范围
    • 减少使用 box-shadowfilter 等耗性能属性
  5. 加载优化

    • 关键 CSS 内联(Critical CSS)
    • 非关键 CSS 异步加载
    • 利用 preload 预加载关键资源

34. 如何实现暗黑模式(Dark Mode)?

高频指数:⭐⭐⭐

方案一:CSS 变量 + 媒体查询

css
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #1a1a1a;
    --text-color: #e0e0e0;
  }
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

方案二:CSS 变量 + data 属性切换

css
[data-theme='dark'] {
  --bg-color: #1a1a1a;
  --text-color: #e0e0e0;
}
javascript
// 切换主题
document.documentElement.setAttribute('data-theme', 'dark');

35. 如何画一条 0.5px 的线?

高频指数:⭐⭐⭐

css
/* 方法一:transform 缩放 */
.line {
  height: 1px;
  background: #000;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

/* 方法二:使用 SVG */
.line {
  background: none;
  height: 1px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='1'%3E%3Cline x1='0' y1='0.5' x2='100%25' y2='0.5' stroke='%23000'/%3E%3C/svg%3E");
}

/* 方法三:使用渐变 */
.line {
  height: 1px;
  background: linear-gradient(to bottom, transparent 50%, #000 50%);
}

三、综合高频题

36. 什么是 CSS 层叠上下文(Stacking Context)?

高频指数:⭐⭐⭐⭐

层叠上下文是 HTML 元素的三维概念,决定了元素在 Z 轴上的显示顺序。

创建层叠上下文的条件:

  • positionrelative/absolute/fixedz-index 不为 auto
  • opacity 值小于 1
  • transform 值不为 none
  • filter 值不为 none
  • display: flex/grid 的子元素且 z-index 不为 auto
  • isolation: isolate
  • will-change 指定了任意属性

层叠顺序(从低到高):

  1. 背景和边框(层叠上下文的背景/边框)
  2. z-index 为负值的定位元素
  3. 块级元素(正常文档流中的)
  4. 浮动元素
  5. 行内/行内块元素
  6. z-index: 0 / auto 的定位元素
  7. z-index 为正值的定位元素

37. 如何实现文本溢出省略号?

高频指数:⭐⭐⭐⭐⭐

单行溢出省略:

css
.ellipsis {
  white-space: nowrap;       /* 不换行 */
  overflow: hidden;          /* 超出隐藏 */
  text-overflow: ellipsis;   /* 省略号 */
}

多行溢出省略(WebKit 方案):

css
.ellipsis-multi {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;     /* 最多显示 3 行 */
  overflow: hidden;
}

兼容性方案(利用伪元素):

css
.ellipsis-multi {
  position: relative;
  max-height: 4.5em;          /* line-height * 行数 */
  line-height: 1.5em;
  overflow: hidden;
}
.ellipsis-multi::after {
  content: '...';
  position: absolute;
  bottom: 0;
  right: 0;
  padding-left: 20px;
  background: linear-gradient(to right, transparent, #fff 50%);
}

38. margin 塌陷和 margin 合并是什么?如何解决?

高频指数:⭐⭐⭐⭐

margin 合并(Margin Collapsing): 两个垂直相邻的块级元素,上方的 margin-bottom 和下方的 margin-top 会合并为其中的较大值。

margin 塌陷: 父子元素之间,子元素的 margin-top 会"穿透"父元素,表现为父元素的 margin-top

解决方案:

css
/* 方法一:为父元素触发 BFC */
.parent { overflow: hidden; }

/* 方法二:为父元素添加 border 或 padding */
.parent { border-top: 1px solid transparent; }
.parent { padding-top: 1px; }

/* 方法三:使用 flex 布局 */
.parent { display: flex; flex-direction: column; }

39. 如何用 CSS 实现一个自适应的正方形?

高频指数:⭐⭐⭐

方法一:padding-bottom 百分比(经典方案)

css
.square {
  width: 50%;
  padding-bottom: 50%; /* padding 的百分比基于父元素的宽度 */
  height: 0;
  background: #333;
}

方法二:aspect-ratio(现代方案,推荐)

css
.square {
  width: 50%;
  aspect-ratio: 1 / 1;
  background: #333;
}

方法三:vw 单位

css
.square {
  width: 50vw;
  height: 50vw;
  background: #333;
}

40. 什么是 CSS 的 contain 属性?

高频指数:⭐⭐⭐

contain 属性用于声明元素和它的内容尽可能独立于文档树的其余部分,让浏览器可以对该元素的布局、样式、绘制、大小等进行局部优化。

css
.widget {
  contain: layout;   /* 该元素内部的布局变化不会影响外部 */
  contain: paint;    /* 该元素的子元素不会显示在其边界之外 */
  contain: size;     /* 该元素大小不受子元素影响 */
  contain: content;  /* 等价于 layout + paint */
  contain: strict;   /* 等价于 layout + paint + size */
}

应用场景: 大量列表项、卡片、Widget 等独立组件,使用 contain 可以显著减少重排范围,提升渲染性能。


四、场景题 & 编程题

41. 实现一个自适应的搜索框布局

题目描述: 左侧搜索框自适应宽度,右侧按钮固定宽度。

css
.search-bar {
  display: flex;
}
.search-input {
  flex: 1;
  height: 40px;
  border: 1px solid #ddd;
  border-radius: 4px 0 0 4px;
  padding: 0 12px;
  outline: none;
}
.search-btn {
  width: 80px;
  height: 40px;
  border: none;
  background: #409eff;
  color: #fff;
  border-radius: 0 4px 4px 0;
  cursor: pointer;
}

42. 实现一个加载动画(Spinner)

css
.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #409eff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

43. 实现一个 Tooltip 气泡提示

css
.tooltip {
  position: relative;
  display: inline-block;
  cursor: pointer;
}
.tooltip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 120%;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 12px;
  background: #333;
  color: #fff;
  border-radius: 4px;
  font-size: 14px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
.tooltip::before {
  content: '';
  position: absolute;
  bottom: calc(120% - 6px);
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #333;
  opacity: 0;
  transition: opacity 0.3s;
}
.tooltip:hover::after,
.tooltip:hover::before {
  opacity: 1;
}
html
<span class="tooltip" data-tip="这是一个提示">鼠标悬停我</span>

五、总结:面试知识图谱

HTML5 & CSS 面试知识图谱

├── HTML5
│   ├── 语义化标签与 SEO
│   ├── 新增表单类型与属性
│   ├── 多媒体(audio / video)
│   ├── Canvas & SVG
│   ├── 本地存储(localStorage / sessionStorage)
│   ├── 离线存储(Service Worker)
│   ├── Web Worker
│   ├── WebSocket
│   ├── 地理定位 & 拖放 API
│   └── History API

├── CSS 基础
│   ├── 盒模型(标准 / IE)
│   ├── 选择器与优先级
│   ├── 可继承与不可继承属性
│   ├── 伪类与伪元素
│   ├── CSS 单位(px / em / rem / vw / vh)
│   └── CSS 变量

├── CSS 布局
│   ├── 正常流 / 浮动 / 定位
│   ├── BFC
│   ├── Flex 弹性布局
│   ├── Grid 网格布局
│   ├── 两栏 / 三栏布局
│   ├── 水平垂直居中
│   └── 响应式设计 / 媒体查询

├── CSS 进阶
│   ├── 层叠上下文 & z-index
│   ├── 重绘与重排
│   ├── CSS 性能优化
│   ├── CSS3 动画 / 过渡
│   ├── 暗黑模式
│   ├── 1px 问题
│   └── contain 属性

└── 编码实战
    ├── 三角形 / 0.5px 线
    ├── 文本溢出省略
    ├── 加载动画
    ├── 自适应正方形
    └── Tooltip 气泡

面试建议:

  1. 面试中不仅要回答"是什么",还要能说出"为什么"和"怎么用"
  2. 布局类题目建议能手写 CSS 代码
  3. 性能优化类的问题要结合浏览器渲染原理来回答
  4. 对于 CSS3 新特性要关注兼容性和渐进增强策略
  5. 多关注新标准:容器查询、:has() 选择器、subgrid