你所不知道的前端知识,html篇(更新中)

🚀 HTML 面试题目速查清单:从规范到引擎的"架构级答案"

你背得出标签、也写得出页面,只能算"会用"。面试官真正想确认的是:你能否把 规范(The Law)引擎(The Metal)工程收益(UX/性能/安全/可维护性) 串成闭环,并在复杂业务里做出可解释、可复用的决策。

这篇文章就是把你给的题集,重新整理成可讲、可追问、可落地的一整套答案模板。


1. 知识图谱预览(The Map)

1.1 重新分类(不是罗列,是建模)

A. 语义与结构(Semantic & Structure)
  • HTML5 语义化标签新增:结构化文档与可访问性树
  • 行内/块级/行内块:格式化上下文与默认 display
  • 空元素(Void Elements):解析器与内容模型边界
  • A11y 友好结构:Landmarks、标题层级、表单语义
  • <head><meta>:文档级协议与资源调度入口
B. 浏览器渲染协议(Rendering & Parsing)
  • 浏览器渲染流程:DOM/CSSOM/渲染树/布局/绘制/合成
  • 文档流与定位:Normal Flow、BFC、position/sticky
  • 重排(reflow)与重绘(repaint):同步点与性能预算
  • async/defer:解析器与执行时序
C. 离线与存储(Offline & Storage)
  • Cookie / LocalStorage / SessionStorage / IndexedDB:边界与选型
  • Cookie 安全属性:HttpOnly/Secure/SameSite 的威胁模型
  • Service Worker:离线、缓存、消息、后台同步
  • AppCache vs Service Worker:从"魔法"到"可编排协议"
D. 性能与安全(Performance & Security)
  • HTML 加载性能:关键路径、优先级、资源提示
  • 响应式图片:srcset/sizes + loading/decoding + LCP
  • XSS 防护:编码/CSP/Trusted Types/依赖治理
  • CSP:从策略到落地(report-only、nonce、hash)
  • iframe 安全限制:sandbox、CSP、跨域通信校验
  • rel="noopener noreferrer":opener 链与反向控制
E. SEO 与社交协议(SEO & Social)
  • HTML SEO 方法:语义结构、链接、元信息、可索引性
  • Schema.org 结构化数据:机器可读的业务语义
  • Open Graph:社交卡片协议
F. 组件化与现代应用(Architecture & Modern Web)
  • Web Components:Custom Elements / Shadow DOM / Template
  • PWA:manifest、SW、离线壳、安装与更新策略
  • 微前端下的 HTML:隔离边界、样式冲突、路由与容器职责
  • 离线编辑结构:可恢复、可同步、可冲突合并
G. 图形/多媒体/交互(Media & Interaction)
  • Canvas vs SVG:渲染模型与交互模型
  • <audio>/<video>:可控播放、自动播放限制、字幕轨道
  • WebGL 与 Canvas:Canvas 是承载面,WebGL 是渲染管线
  • Drag & Drop:事件模型与可访问性替代方案
  • Intersection Observer:可见性驱动的性能与体验治理
H. 兼容性/标准/调试监控(Standards & Quality)
  • HTML5 旧浏览器兼容:polyfill、渐进增强
  • 条件注释:历史遗产与现代替代
  • DOCTYPE:标准模式 vs 怪异模式
  • HTML vs XHTML:错误处理模型与工程影响
  • HTML Living Standard:标准发布与实现关系
  • A11y 检查:工具与人工检查闭环
  • Lighthouse:可量化指标与可回归的治理
  • LCP 与 DOM 体积监控:把性能变成"可观测资产"

1.2 一句话点睛

HTML 的价值不是"写标签",而是把页面变成 可被机器理解(SEO/A11y)可被引擎高效执行(渲染/调度)可被工程稳定治理(安全/性能/架构) 的产品协议层。


2. 模块化深挖(The Deep Dive)

A. 语义与结构(Semantic & Structure)

A1. HTML5 新增了哪些语义化标签?它们解决什么问题?

【面试官在问什么】

  • 不是问你"背标签表",而是确认你是否理解:语义标签的价值在 可访问性树(A11y)搜索理解(SEO)结构稳定性(可维护)

【三维解析】

  • 官方定义(The Law)
    • HTML Living Standard 将一批结构性元素(如 header/nav/main/article/section/aside/footer)作为表达文档结构的语义元素,用户代理与辅助技术可据此提供导航与语义映射。
    • MDN:语义元素让内容结构更易被开发者、浏览器、搜索引擎与辅助技术理解。
  • 白话逻辑(The Logic)
    • <div> 是"无名箱子";语义标签是"贴了用途标签的箱子"。箱子不变,信息密度变了。
  • 底层内幕(The Metal)
    • 语义元素会参与 landmark 的构建(例如 main/nav),屏幕阅读器可以一键跳转"主内容/导航/页脚"。
    • 结构信号还能减少 DOM 修补的歧义:团队协作时,"这个块是什么"不靠 class 命名猜,而靠语义直接表达。

【代码实战】

新手代码(全 div,语义只能靠 class 猜):

html 复制代码
<div class="top">
  <div class="menu">...</div>
</div>
<div class="content">...</div>
<div class="bottom">...</div>

架构师级(结构即契约):

html 复制代码
<header>
  <nav aria-label="主导航">...</nav>
</header>
<main>
  <article>...</article>
</main>
<footer>...</footer>

【避坑/优化】

  • section 不是"div+1":只有当它能构成文档结构的一节,并且通常带标题(显式或隐式)时才用。
  • 不要让 landmark 泛滥:一个页面通常一个 main,多个 nav 要用 aria-label 区分用途。

A2. 行内元素、块级元素、行内块元素有哪些?区别是什么?

【面试官在问什么】

  • 表面是分类,实际考的是:你是否理解 CSS display 参与的布局算法行盒(line box)、以及"为什么宽高/外边距表现不同"。

【三维解析】

  • 官方定义(The Law)
    • HTML 本身并不严格定义"块级/行内"的二元分类;工程里通常用"默认 display"描述:div/p 默认 block,span/a 默认 inline。
    • CSS 规范定义 display 决定元素参与的格式化上下文与布局行为(例如 block formatting context / inline formatting context)。
  • 白话逻辑(The Logic)
    • block 像"整行座位",inline 像"句子里的字",inline-block 像"句子里塞进一个小盒子"。
  • 底层内幕(The Metal)
    • inline 的布局受字体度量与 baseline 影响,width/height 通常不按你想的生效;inline-block 既在行内流里排队,又拥有块级盒模型,可控宽高与内外边距。
    • 很多"对不齐"的根源是 baseline 与 line-height,而不是你写错了 margin。

【代码实战】

新手代码(用 inline 元素强行设宽高):

html 复制代码
<a class="btn" href="/buy">购买</a>
<style>
  .btn { width: 160px; height: 44px; background: #111; color: #fff; }
</style>

架构师级(让 display 与目标一致):

html 复制代码
<a class="btn" href="/buy">购买</a>
<style>
  .btn { display: inline-block; width: 160px; height: 44px; line-height: 44px; text-align: center; background: #111; color: #fff; }
</style>

【避坑/优化】

  • 别背"行内不能嵌套块级"当规则:HTML 的内容模型更复杂,浏览器还会容错纠正。工程上要做的是:结构清晰、样式可控、可访问性不被破坏。

A3. 常见的空元素(Void Elements)有哪些?为什么它们"不能有内容"?

【面试官在问什么】

  • 这题用来筛出"只会写"与"理解解析器/内容模型"的人:你是否知道 void 元素在规范里就是 没有 end tag、没有内容模型

【三维解析】

  • 官方定义(The Law)
    • HTML 标准把 img/input/br/hr/meta/link/source/track/wbr/area/base/col/embed/param 等定义为 void elements:不得有内容,也没有结束标签。
  • 白话逻辑(The Logic)
    • void 元素是"原子指令",像换行 br、图片 img、输入框 input,它们本身就是一个完整动作。
  • 底层内幕(The Metal)
    • Tokenizer 与 Tree Builder 按内容模型建树:void 元素一旦开始标签被插入,就不会期待对应结束标签,也不会挂载子节点。你硬写 </img> 并不会"更规范",只是制造无意义 token,甚至触发容错路径。

【代码实战】

新手代码(写无意义 end tag):

html 复制代码
<img src="/a.png"></img>

架构师级(符合内容模型):

html 复制代码
<img src="/a.png" alt="示例图片">

【避坑/优化】

  • img 必须有 alt:这不是形式主义,是 SEO/A11y 的信息出口。
  • 在 JSX/TSX 里 <img /> 是语法要求(自闭合),不要把它理解成"HTML 里也必须写 /"。

A4. 如何设计无障碍(A11y)友好的 HTML 结构?

【面试官在问什么】

  • 这题不是"会不会加 aria-label",而是要你证明:你知道 AOM/无障碍树 是怎么来的,知道语义优先、ARIA 兜底的策略。

【三维解析】

  • 官方定义(The Law)
    • WAI-ARIA 与 HTML 映射定义了元素语义如何进入无障碍树;MDN 强调:优先使用原生语义元素,ARIA 用于补足语义,而不是替代。
  • 白话逻辑(The Logic)
    • 无障碍不是"给残障人士开小灶",而是让页面变成"可导航的信息空间":有路标(landmark)、有目录(标题层级)、有可达的操作(可聚焦、可读提示)。
  • 底层内幕(The Metal)
    • 浏览器会把 DOM + CSS 可见性(如 display:none)+ 语义映射综合成 Accessibility Tree。错误做法(例如用 div 模拟按钮)会导致:无障碍树缺少 role/状态/键盘行为,用户"看得见但用不了"。

【代码实战】

新手代码(div 当按钮,键盘与语义缺失):

html 复制代码
<div class="btn" onclick="buy()">购买</div>

架构师级(语义优先 + 键盘可达):

html 复制代码
<button type="button" class="btn" onclick="buy()">购买</button>

如果业务确实必须用非原生元素(极少数),至少补齐 role/键盘:

html 复制代码
<div role="button" tabindex="0" aria-label="购买" onkeydown="if(event.key==='Enter'||event.key===' ') buy()" onclick="buy()">
  购买
</div>

【避坑/优化】

  • ARIA 不是"装饰品":加了 aria 但没补键盘行为,是伪无障碍。
  • 表单错误提示要可感知:错误信息要和输入关联(aria-describedby),并在提交失败时把焦点带到第一个错误。

A5. <head> 标签有什么作用?可以包含哪些元素?

【面试官在问什么】

  • 在问"你把 head 当作什么":它是 文档级协议层,决定编码、视口、预加载、CSP、SEO 等"全局行为"。

【三维解析】

  • 官方定义(The Law)
    • HTML 标准把 head 定义为元数据容器,典型包含 meta/title/link/style/script/base 等。
    • MDN:head 中放置页面元信息与资源引用。
  • 白话逻辑(The Logic)
    • head 像"飞机的飞行计划":起飞前就要把航线(资源)、规则(策略)、参数(viewport/编码)写好。
  • 底层内幕(The Metal)
    • head 里的资源提示(preload、preconnect)会影响网络调度与优先级;CSP/meta 可能直接改变脚本是否允许执行。

【代码实战】

新手 head(缺关键元信息):

html 复制代码
<head>
  <title>站点</title>
</head>

架构师级 head(协议齐全):

html 复制代码
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="高性能、可访问的前端站点示例">
  <link rel="preload" href="/styles/app.css" as="style">
  <link rel="stylesheet" href="/styles/app.css">
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <title>站点</title>
</head>

【避坑/优化】

  • 视口 meta 写错会直接毁掉移动端体验。
  • CSP 用 meta 可用但能力有限,工程上更推荐用响应头配置与 report-only 灰度。

B. 浏览器渲染协议(Rendering & Parsing)

B1. 浏览器渲染 HTML 的完整流程是什么?

【面试官在问什么】

  • 你能否说清 CRP(关键渲染路径),以及"为什么 CSS/JS 能卡住首屏"。

【三维解析】

  • 官方定义(The Law)
    • MDN:渲染通常经历 DOM/CSSOM → Render Tree → Layout → Paint → Composite。
  • 白话逻辑(The Logic)
    • DOM 是骨架,CSSOM 是皮肤,布局是量尺寸,绘制是上色,合成是分层拼接。
  • 底层内幕(The Metal)
    • JS 会阻塞解析(同步脚本)并占用主线程;CSS 会阻塞首次绘制(需要完整样式才能算布局与画)。
    • 引擎会尽量把"可合成动画"交给合成线程(依实现),但布局与样式计算依然高度依赖主线程。

Mermaid:CRP 概念图

flowchart TD H[HTML] --> D[DOM] C[CSS] --> O[CSSOM] D --> R[Render Tree] O --> R R --> L[Layout] L --> P[Paint] P --> S[Composite] J[JS] -->|可能阻塞| D J -->|读写样式/布局| L

【代码实战】

新手代码(同步脚本卡解析):

html 复制代码
<head>
  <script src="/bundle.js"></script>
</head>
<body>
  <main>...</main>
</body>

架构师级(让解析与下载并行,稳定执行):

html 复制代码
<head>
  <script defer src="/bundle.js"></script>
</head>
<body>
  <main>...</main>
</body>

【避坑/优化】

  • 别只背"CSS 放 head":真正要做的是"关键路径预算",以 LCP 元素为中心裁剪资源。

B2. <script>asyncdefer 有什么区别?

【面试官在问什么】

  • 考你对 执行时序 的控制能力:能否避免"偶现初始化失败"。

【三维解析】

  • 官方定义(The Law)
    • HTML 标准:defer 下载并行、解析完成后按顺序执行;async 下载并行、下载完成立即执行(会中断解析),且不保证顺序。
  • 白话逻辑(The Logic)
    • defer 是"等房子盖完再装家具";async 是"家具到就装,装的时候工人停工"。
  • 底层内幕(The Metal)
    • async 的风险是不可预测:执行时间受网络/缓存影响,导致依赖 DOM 或依赖其他脚本的逻辑出现"只在弱网爆"的偶现问题。

【代码实战】

新手代码(DOM 依赖却 async):

html 复制代码
<script async src="/init-dom.js"></script>
<div id="root"></div>

架构师级(DOM 依赖用 defer):

html 复制代码
<div id="root"></div>
<script defer src="/init-dom.js"></script>

【避坑/优化】

  • 埋点也别无脑 async:它可能抢主线程窗口。更成熟做法是延后、分批、或使用 navigator.sendBeacon 等策略(视业务与兼容)。

B3. 什么是文档流?CSS 定位方式有哪些?

【面试官在问什么】

  • 面试官在确认你能否用"规则"解释布局:什么在 normal flow,谁脱离文档流,谁创建新的格式化上下文。

【三维解析】

  • 官方定义(The Law)
    • CSS 规范定义 normal flow(普通流)与 positioning scheme(static/relative/absolute/fixed/sticky)以及浮动(float)的排版规则。
  • 白话逻辑(The Logic)
    • 普通流像排队,绝对定位像"插队到指定座位",fixed 像"贴在屏幕玻璃上",sticky 像"先排队,滚到门口就钉住"。
  • 底层内幕(The Metal)
    • position: absolute 以最近的定位祖先为包含块(containing block),这决定了你"漂到哪里"。
    • sticky 的工作方式依赖滚动容器与阈值,一旦祖先元素产生新的滚动上下文或 overflow 裁剪,就会让 sticky "失效"。

【代码实战】

新手代码(absolute 找不到参照系,漂移不可控):

html 复制代码
<div class="card">
  <span class="badge">NEW</span>
</div>
<style>
  .badge { position: absolute; top: 0; right: 0; }
</style>

架构师级(显式提供 containing block):

html 复制代码
<div class="card">
  <span class="badge">NEW</span>
</div>
<style>
  .card { position: relative; }
  .badge { position: absolute; top: 0; right: 0; }
</style>

【避坑/优化】

  • 布局问题先问"参照系是谁""是否脱离普通流",比盲调 margin 更快。

B4. 什么是重绘(repaint)和重排(reflow)?怎么避坑?

【面试官在问什么】

  • 考你是否理解"性能不是玄学":哪些操作会触发布局,哪些能只合成,如何减少同步点。

【三维解析】

  • 官方定义(The Law)
    • 行业里常用重排/重绘术语描述布局与绘制阶段的开销(规范不会用 reflow 这个词做唯一标准,但概念对应 layout/paint)。
  • 白话逻辑(The Logic)
    • 重排是"重新量尺寸摆家具",重绘是"家具不动重新刷漆"。
  • 底层内幕(The Metal)
    • 最致命的是"强制同步布局":你先写样式(dirty),再立刻读取布局属性(如 offsetHeight),引擎为给你正确值被迫立刻 layout。

【代码实战】

新手代码(写-读交替,触发强制同步布局):

js 复制代码
const el = document.querySelector(".box")
for (let i = 0; i < 1000; i++) {
  el.style.width = i + "px"
  el.offsetHeight
}

架构师级(批量写入,避免写-读交错):

js 复制代码
const el = document.querySelector(".box")
let width = 0
for (let i = 0; i < 1000; i++) width = i
el.style.width = width + "px"

【避坑/优化】

  • 动画优先用 transform/opacity(更容易走合成路径),少用 top/left/width/height。
  • DOM 体积与层级过深会放大样式计算与布局成本,性能治理要把 DOM 当"资产"管理。

C. 性能优化(Performance)

C1. 如何优化 HTML 的加载性能?

【面试官在问什么】

  • 不是"背几条技巧",而是:你是否能围绕 LCP/TTI/INP 把优化串成可验证的方案。

【三维解析】

  • 官方定义(The Law)
    • Web 性能指标由 Web Vitals 等体系定义(如 LCP/INP/CLS)。HTML/资源加载策略影响关键路径与指标表现。
  • 白话逻辑(The Logic)
    • 首屏优化本质是:让"用户最在意的那块内容"更早到、更早算完、更早画出来。
  • 底层内幕(The Metal)
    • 你在优化的是"调度":网络优先级、主线程时间片、渲染同步点。
    • 关键策略通常包括:减少关键资源字节、减少关键资源数量、降低主线程启动负载、推迟非关键工作。

【代码实战】

新手代码(首屏塞满阻塞项):

html 复制代码
<head>
  <link rel="stylesheet" href="/styles/all.css">
  <script src="/bundle.js"></script>
</head>

架构师级(关键路径瘦身与时序控制):

html 复制代码
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="preload" href="/styles/app.css" as="style">
  <link rel="stylesheet" href="/styles/app.css">
  <script defer src="/bundle.js"></script>
</head>

【避坑/优化】

  • 不要把 preload 当万能:预加载错了资源就是在抢关键资源的带宽与连接。

C2. 如何实现响应式图片?srcset/sizes 怎么写才算"工程正确"?

【面试官在问什么】

  • 这题考的是:你是否理解浏览器的资源选择算法,以及你能否把它变成"可预测、可度量"的工程行为。

【三维解析】

  • 官方定义(The Law)
    • HTML 标准定义 srcset 候选集与 sizes 布局宽度声明,浏览器结合 DPR(Device Pixel Ratio) 与媒体条件选择资源。
  • 白话逻辑(The Logic)
    • 你告诉浏览器"不同尺码的衣服",再告诉它"这个场合我大概穿多大",它就会选刚刚好的。
  • 底层内幕(The Metal)
    • sizes 写错会让浏览器在请求阶段就做错决策:要么糊(下小图放大),要么浪费(下大图解码慢、占带宽)。

【代码实战】

新手代码(缺 sizes,选择不可控):

html 复制代码
<img
  src="/img/hero-800.jpg"
  srcset="/img/hero-800.jpg 800w, /img/hero-1600.jpg 1600w, /img/hero-2400.jpg 2400w"
  alt="主视觉"
>

架构师级(声明布局宽度,让选择可预测):

html 复制代码
<img
  src="/img/hero-800.jpg"
  srcset="/img/hero-800.jpg 800w, /img/hero-1600.jpg 1600w, /img/hero-2400.jpg 2400w"
  sizes="(max-width: 600px) 92vw, (max-width: 1200px) 70vw, 900px"
  alt="主视觉"
  decoding="async"
>

【避坑/优化】

  • 首屏 LCP 图别盲目 loading="lazy":会推迟请求,直接伤 LCP。非首屏图再启用懒加载。

C3. <img>loading 属性有什么作用?何时用 lazy,何时别用?

【面试官在问什么】

  • 考你是否理解"懒加载是优化也是风险":它改变请求时机,从而改变 LCP/CLS/首屏体验。

【三维解析】

  • 官方定义(The Law)
    • MDN:loading="lazy" 允许浏览器推迟加载非视口附近图片;eager 立即加载;默认由 UA 决策。
  • 白话逻辑(The Logic)
    • lazy 像"走近再拿货",省流量但可能让你"到了门口才发现没货",影响体验。
  • 底层内幕(The Metal)
    • 延迟请求会把网络与解码推迟到更晚的主线程窗口;如果这个元素是 LCP 候选,就会直接把指标拉差。

【代码实战】

新手代码(首屏大图也 lazy):

html 复制代码
<img src="/img/hero.jpg" loading="lazy" alt="主视觉">

架构师级(首屏 eager,非首屏 lazy):

html 复制代码
<img src="/img/hero.jpg" alt="主视觉">
<img src="/img/list-1.jpg" loading="lazy" alt="列表图 1">

【避坑/优化】

  • 懒加载要和占位尺寸配套(width/height 或 CSS aspect-ratio),否则滚动加载会造成 CLS。

D. 表单与输入(Forms & Input)

D1. HTML5 表单新增了哪些输入类型和属性?它们有什么"真实工程价值"?

【面试官在问什么】

  • 考你是否知道:很多输入类型不是"花活",是 移动端键盘优化浏览器原生校验 的入口。

【三维解析】

  • 官方定义(The Law)
    • HTML 标准定义了 email/url/number/date/time/search/tel 等类型,以及 required/min/max/pattern/autocomplete 等属性。
  • 白话逻辑(The Logic)
    • 你选对 input type,等于"让系统键盘帮你做一半交互设计"。
  • 底层内幕(The Metal)
    • 原生校验会参与提交流程与可访问性提示;但不同浏览器 UI 不一致,所以工程上常用"原生能力 + 自定义一致性"的组合策略。

【代码实战】

新手代码(一切 text,手机键盘体验差):

html 复制代码
<input type="text" name="email">

架构师级(类型与约束到位):

html 复制代码
<input type="email" name="email" autocomplete="email" required>

【避坑/优化】

  • pattern 不要写得比业务规则还严格,否则会制造"合法输入被拒绝"的体验灾难。

D2. <label> 标签的作用是什么?为什么它是 A11y 与可用性的关键点?

【面试官在问什么】

  • 在考你是否理解:label 不是"可选装饰",是输入语义、可点击区域与无障碍朗读的基础。

【三维解析】

  • 官方定义(The Law)
    • HTML 标准定义 label 与表单控件的关联(for 指向控件 id 或包裹控件)。
  • 白话逻辑(The Logic)
    • label 是"按钮的外壳":点文字也能选中,用户手指不需要精准点小圆点。
  • 底层内幕(The Metal)
    • 无障碍树会把 label 作为控件的可访问名称来源之一,缺 label 会导致读屏"只读出 edit text",用户不知道要填什么。

【代码实战】

新手代码(无关联,点击文字不生效):

html 复制代码
<span>同意协议</span>
<input type="checkbox">

架构师级(扩大可点击区域 + 可访问名称):

html 复制代码
<input id="agree" type="checkbox">
<label for="agree">同意协议</label>

【避坑/优化】

  • 表单错误信息别只用颜色表达,要有文本,并通过 aria-describedby 关联到输入。

D3. 表单提交 GET/POST 有什么区别?以及"面试官真正关心的是什么"?

【面试官在问什么】

  • 不是背"GET 有长度限制",而是:你是否理解语义、缓存、幂等性与隐私泄露面。

【三维解析】

  • 官方定义(The Law)
    • HTTP 语义层面:GET 用于获取资源,POST 用于提交处理;缓存与幂等性是关键差异之一。
  • 白话逻辑(The Logic)
    • GET 像"查询",POST 像"办理业务"。查询结果可缓存,办理业务要谨慎重复。
  • 底层内幕(The Metal)
    • GET 的参数出现在 URL:会进入历史记录、日志、Referer 传播链;敏感信息用 GET 是在给攻击者写"线索"。

【代码实战】

新手代码(把敏感信息放查询串):

html 复制代码
<form action="/login" method="get">
  <input name="password" type="password">
</form>

架构师级(语义与隐私正确):

html 复制代码
<form action="/login" method="post">
  <input name="password" type="password" autocomplete="current-password">
</form>

【避坑/优化】

  • 真正安全不在 method,而在 HTTPS、服务端校验、CSRF 防护与会话策略。

D4. 如何实现表单验证?原生验证与自定义验证如何取舍?

【面试官在问什么】

  • 你是否能把"体验一致性"与"原生能力"折中成可维护方案。

【三维解析】

  • 官方定义(The Law)
    • HTML 约束验证模型(constraint validation)提供 required/pattern/min/max 等,并通过 checkValidity/reportValidity 参与提交流程。
  • 白话逻辑(The Logic)
    • 原生验证像"系统自带的门禁",自定义验证像"你自己定的安检规则"。系统门禁免费但 UI 不统一,自定义统一但要付维护成本。
  • 底层内幕(The Metal)
    • 原生验证会自动阻止提交并聚焦第一个错误字段;工程上常见做法是:用原生约束做底线,用自定义 UI 做一致呈现与国际化文案。

【代码实战】

html 复制代码
<form id="f">
  <label for="email">邮箱</label>
  <input id="email" type="email" required>
  <button type="submit">提交</button>
</form>
<script>
  document.getElementById("f").addEventListener("submit", (e) => {
    const ok = e.target.checkValidity()
    if (!ok) e.preventDefault()
  })
</script>

【避坑/优化】

  • 自定义验证要处理键盘与读屏提示,否则你做的是"把可访问性退化掉的重造轮子"。

E. 多媒体与图形(Media & Graphics)

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

【面试官在问什么】

  • 考你是否理解两种渲染模型的成本结构:DOM/事件/可编辑性 vs 像素重绘/可控性

【三维解析】

  • 官方定义(The Law)
    • Canvas:脚本驱动的位图绘制;SVG:基于 XML/DOM 的矢量图形描述。
  • 白话逻辑(The Logic)
    • Canvas 像"画在纸上",SVG 像"留着图纸"。一个改像素,一个改对象。
  • 底层内幕(The Metal)
    • SVG 元素多会带来 DOM 与样式计算压力;Canvas 元素少但交互拾取与重绘需要你自己承担。

【代码实战】

Canvas 做 DPR 适配(避免发虚):

js 复制代码
const canvas = document.getElementById("c")
const dpr = window.devicePixelRatio || 1
const w = 300, h = 150
canvas.style.width = w + "px"
canvas.style.height = h + "px"
canvas.width = Math.floor(w * dpr)
canvas.height = Math.floor(h * dpr)
const ctx = canvas.getContext("2d")
ctx.scale(dpr, dpr)

【避坑/优化】

  • SVG 做动效要控制节点数量;Canvas 做交互要控制消息/拾取成本。

E2. <audio><video> 的基本用法?现代浏览器的自动播放限制怎么处理?

【面试官在问什么】

  • 考你是否了解现代浏览器对用户体验的约束:自动播放策略、静音、手势触发、字幕与可访问性。

【三维解析】

  • 官方定义(The Law)
    • HTML Media 元素支持 controls/autoplay/muted/playsinline,字幕轨道通过 track 提供。
  • 白话逻辑(The Logic)
    • 浏览器不让你随便"吵用户",所以自动播放通常要静音或有用户手势。
  • 底层内幕(The Metal)
    • 自动播放策略依 UA 与站点信任度变化;工程上要把"播放"设计为用户手势触发,并提供字幕/文本替代。

【代码实战】

html 复制代码
<video controls playsinline preload="metadata" width="640">
  <source src="/movie.mp4" type="video/mp4">
  <track kind="captions" src="/movie.zh.vtt" srclang="zh" label="中文字幕" default>
</video>

【避坑/优化】

  • preload="auto" 会增加流量;默认 metadata 更稳,除非你明确要首屏即播。

E3. WebGL 和 Canvas 有什么关系?

【面试官在问什么】

  • 看你有没有"底层视角":Canvas 是承载容器,WebGL 是 GPU 渲染 API;选型要看渲染管线与性能目标。

【三维解析】

  • 官方定义(The Law)
    • WebGL 在 <canvas> 上下文中提供基于 OpenGL ES 的 3D 渲染接口。
  • 白话逻辑(The Logic)
    • Canvas 是"画布",WebGL 是"高性能绘画机器",两者是容器与引擎的关系。
  • 底层内幕(The Metal)
    • WebGL 把大量工作交给 GPU,但也带来资源管理(纹理、缓冲)与上下文丢失处理等工程复杂度。

【代码实战】

js 复制代码
const gl = document.getElementById("c").getContext("webgl")
if (!gl) throw new Error("WebGL 不可用")

【避坑/优化】

  • WebGL 不是"更快"的代名词:小规模简单图形用 SVG/Canvas 可能更省。

F. 存储与缓存(Storage & Cache)

F1. Cookie、LocalStorage、SessionStorage、IndexedDB 的区别?怎么选型?

【面试官在问什么】

  • 看你是不是会做架构选择:同步/异步、容量、生命周期、隐私分区与安全面。

【三维解析】

  • 官方定义(The Law)
    • Cookie 自动随请求发送(受属性约束);Web Storage 是同步键值;IndexedDB 是异步事务数据库。
  • 白话逻辑(The Logic)
    • Cookie 是"每次请求都夹带的纸条";localStorage 是"你家门口的小柜子";IndexedDB 是"仓库"。
  • 底层内幕(The Metal)
    • localStorage 同步会卡主线程;IndexedDB 异步更适合大对象与高频写入;Cookie 的成本体现在网络与安全面(每次请求头都带)。

【代码实战】

localStorage(小且低频):

js 复制代码
localStorage.setItem("theme", "dark")

IndexedDB(大且高频,事务化):

js 复制代码
const req = indexedDB.open("db", 1)
req.onupgradeneeded = () => req.result.createObjectStore("kv")
req.onsuccess = () => {
  const db = req.result
  const tx = db.transaction("kv", "readwrite")
  tx.objectStore("kv").put("v", "k")
}

【避坑/优化】

  • 身份凭证别放 localStorage:XSS 一旦发生就是"全站通行证泄露"。更稳的基线通常是 HttpOnly Cookie + CSRF 防护。

【面试官在问什么】

  • 看你能否把威胁模型讲清楚:XSS/CSRF/会话劫持,以及属性的边界。

【三维解析】

  • 官方定义(The Law)
    • MDN:HttpOnly 禁止 JS 读取;Secure 仅 HTTPS 发送;SameSite 限制跨站点发送以缓解 CSRF。
  • 白话逻辑(The Logic)
    • HttpOnly 防"偷看",Secure 防"路上偷听",SameSite 防"隔壁借用你的身份"。
  • 底层内幕(The Metal)
    • CSRF 的根源是浏览器自动附带身份;SameSite 改的是"何时自动带上"。

【代码实战】

http 复制代码
Set-Cookie: session=abc; Path=/; HttpOnly; Secure; SameSite=Lax

【避坑/优化】

  • SameSite=None 必须配 Secure,否则现代浏览器可能拒绝。
  • HttpOnly 不能防止 XSS 直接发起敏感操作,XSS 的防线在编码、CSP 与权限校验闭环。

F3. Service Worker 是什么?有什么作用?

【面试官在问什么】

  • 考你对"离线与缓存"是否真的懂:SW 是可编排的网络代理层,不是"缓存开关"。

【三维解析】

  • 官方定义(The Law)
    • Service Worker 是运行在后台的脚本,拦截网络请求(fetch),处理缓存、推送、后台同步等,受 HTTPS 与作用域限制。
  • 白话逻辑(The Logic)
    • SW 像"站点的网络门卫":每个请求先过它,它决定走网络还是走仓库。
  • 底层内幕(The Metal)
    • SW 的更新是"新旧并存"的:新 SW 安装后要等旧页面释放控制权才能接管,这决定了你的发布策略不能只靠"刷新就生效"。

Mermaid:SW 生命周期(概念图)

stateDiagram-v2 [*] --> Installing Installing --> Installed Installed --> Activating Activating --> Activated Activated --> Redundant

【代码实战】

js 复制代码
if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("/sw.js")
}

【避坑/优化】

  • 缓存策略要可回滚:缓存错资源比不缓存更灾难(白屏、版本错乱)。
  • SW 作用域与路径要设计好,否则会出现"某些页面不受控"的灰色区域。

F4. Application Cache 和 Service Worker 有什么区别?为什么 AppCache 被淘汰?

【面试官在问什么】

  • 这题本质是问"你理解协议演进吗":AppCache 是不可控的魔法,SW 是可编排的系统。

【三维解析】

  • 官方定义(The Law)
    • AppCache 已废弃;Service Worker 成为离线与缓存的推荐机制。
  • 白话逻辑(The Logic)
    • AppCache 像"自动备份但你控制不了什么时候备份、备什么";SW 像"你写脚本明确告诉它怎么缓存、怎么更新"。
  • 底层内幕(The Metal)
    • AppCache 的更新与回退机制容易让版本错乱;SW 则允许你把缓存策略设计为可观测、可灰度、可回滚的工程流程。

【代码实战】

SW 缓存策略的关键点是"策略明确",例如 cache-first/network-first(这里只示意结构):

js 复制代码
self.addEventListener("fetch", (event) => {
  event.respondWith(fetch(event.request))
})

【避坑/优化】

  • 不要把 SW 当"离线万能药":离线编辑还需要冲突合并、队列重放、版本迁移等完整系统设计。

G. 安全相关(Security)

G1. rel="noopener noreferrer" 有什么作用?

【面试官在问什么】

  • 考你是否理解 window.opener 的反向控制风险与隐私泄露链。

【三维解析】

  • 官方定义(The Law)
    • MDN:noopener 阻止新页面访问 opener;noreferrer 抑制 Referer。
  • 白话逻辑(The Logic)
    • 不加的话,你打开的新页面可能反过来控制你,把你导航到钓鱼站。
  • 底层内幕(The Metal)
    • 切断 opener 关系会减少页面间的耦合,降低安全面,也常带来更好的隔离收益(具体进程策略依实现)。

【代码实战】

html 复制代码
<a href="https://example.com" target="_blank" rel="noopener noreferrer">外部链接</a>

【避坑/优化】

  • 这是安全基线,不是"锦上添花"。默认加,除非你能解释清楚为什么不加。

G2. 如何防止 XSS 攻击?

【面试官在问什么】

  • 看你有没有体系:XSS 防护不靠一句"过滤",而是输入、输出、执行三层闭环。

【三维解析】

  • 官方定义(The Law)
    • W3C/WHATWG 与 MDN 提供了 CSP 等机制;OWASP 给出 XSS 防护最佳实践:输出编码、CSP、减少危险 API、依赖治理。
  • 白话逻辑(The Logic)
    • XSS 就是"把别人的代码塞进你的页面,让它以你的身份执行"。所以防护重点是:别让它进来、别让它执行、执行了也别有权限。
  • 底层内幕(The Metal)
    • 最危险的不是"用户输入",而是"把不可信字符串拼进可执行上下文":innerHTMLdocument.writesetTimeout(string)、内联事件属性等。

【代码实战】

新手代码(把字符串当 HTML 执行):

js 复制代码
container.innerHTML = userInput

架构师级(使用 textContent,必要时做可信模板渲染):

js 复制代码
container.textContent = userInput

【避坑/优化】

  • "过滤黑名单"几乎必败:编码与上下文相关,黑名单永远跟不上绕过。
  • 真正的工程闭环:输出编码 + CSP + 依赖治理(审计第三方脚本)+ 权限最小化(令牌策略、接口鉴权)。

G3. CSP(内容安全策略)是什么?怎么落地才不把业务搞挂?

【面试官在问什么】

  • 考你能否把 CSP 从"概念"落到"工程策略":report-only 灰度、nonce/hash、第三方脚本治理。

【三维解析】

  • 官方定义(The Law)
    • CSP 是一组策略指令,约束资源加载与脚本执行来源,可显著缓解 XSS。
  • 白话逻辑(The Logic)
    • CSP 是"白名单门禁":只允许你信任的脚本/资源进入。
  • 底层内幕(The Metal)
    • CSP 的落地成本来自历史遗留:内联脚本、内联事件、第三方脚本。成熟落地路径是:先 report-only 收集违例,再分阶段收敛来源,最后强制执行。

【代码实战】

report-only 灰度示意(以 meta 表达,工程更推荐响应头):

html 复制代码
<meta http-equiv="Content-Security-Policy-Report-Only" content="default-src 'self'; script-src 'self'; report-to csp-endpoint">

【避坑/优化】

  • CSP 不是"一次性开关",是治理工程:需要资产盘点(脚本来源)、监控(违例上报)、灰度(report-only)与回滚方案。

G4. iframe 有哪些安全限制?怎么做隔离?

【面试官在问什么】

  • 看你是否理解:iframe 是隔离工具,但默认并不安全。安全来自明确的 sandbox、CSP、通信校验与最小权限。

【三维解析】

  • 官方定义(The Law)
    • iframe 创建独立 browsing context;sandbox 可限制脚本、表单、同源等能力;同源策略约束跨域访问。
  • 白话逻辑(The Logic)
    • iframe 像"在客厅里盖一间小屋",隔离更清晰,但你得规定它能不能开窗、能不能用电。
  • 底层内幕(The Metal)
    • 跨域通信只能走 postMessage,安全关键是校验 origin,否则就是把后门写在代码里。

【代码实战】

html 复制代码
<iframe
  src="https://third-party.example.com/widget"
  sandbox="allow-scripts allow-forms"
  referrerpolicy="no-referrer"
></iframe>

安全通信示意:

js 复制代码
window.addEventListener("message", (e) => {
  if (e.origin !== "https://third-party.example.com") return
  handle(e.data)
})

【避坑/优化】

  • sandbox 给太多权限等于没隔离;给太少会导致功能异常。做法是"最小权限起步",逐项加到能用为止。

H. SEO 优化(SEO & Social)

H1. HTML 中有哪些方法可以优化 SEO?

【面试官在问什么】

  • 不是"加几个 meta",而是:你是否理解 SEO 的输入信号来自 结构、可索引性、可理解性,以及 SSR/CSR 的取舍。

【三维解析】

  • 官方定义(The Law)
    • 搜索引擎实现不同,但普遍依赖:文档结构、链接关系、元信息与可抓取性(robots/canonical 等)。
  • 白话逻辑(The Logic)
    • SEO 就是"让机器读懂你":标题像章节名,链接像引用关系,结构化数据像你主动给的名片。
  • 底层内幕(The Metal)
    • 爬虫的 JS 执行能力有限且成本高;关键内容若只在客户端渲染,可能出现抓取延迟或理解偏差。工程上常用 SSR/预渲染提升稳定性。

【代码实战】

html 复制代码
<h1>产品定价</h1>
<nav aria-label="面包屑">
  <a href="/">首页</a> / <a href="/pricing">定价</a>
</nav>
<link rel="canonical" href="https://example.com/pricing">

【避坑/优化】

  • SEO 不是"关键词堆砌":结构清晰、内容可读、性能好(尤其 LCP)往往更有长期收益。

H2. <meta> 标签有哪些常用属性?哪些是"真有用"的?

【面试官在问什么】

  • 看你是否知道 meta 的边界:哪些影响浏览器行为,哪些影响 SEO/分享,哪些只是历史遗留。

【三维解析】

  • 官方定义(The Law)
    • 常见:charsetviewportdescriptionrobotshttp-equiv(策略类)。
  • 白话逻辑(The Logic)
    • meta 是"全局说明书":给浏览器、爬虫、分享平台各写一份摘要。
  • 底层内幕(The Metal)
    • charset 影响解析;viewport 影响布局视口;robots 影响索引策略;CSP meta 影响脚本执行。

【代码实战】

html 复制代码
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="高性能、可访问的定价页">
<meta name="robots" content="index,follow">

【避坑/优化】

  • description 不是"越长越好",它是摘要候选;内容要准确、可读、匹配落地页意图。

H3. 结构化数据(Schema.org)的作用是什么?

【面试官在问什么】

  • 考你是否能把"业务语义"显式提供给机器,提升富结果展示与理解准确性。

【三维解析】

  • 官方定义(The Law)
    • Schema.org 提供通用实体类型(Product/Article/BreadcrumbList 等),常用 JSON-LD 形式嵌入页面。
  • 白话逻辑(The Logic)
    • 结构化数据是你给搜索引擎递的"名片":我是谁、卖什么、价格多少、评分如何。
  • 底层内幕(The Metal)
    • 机器理解最怕歧义;结构化数据把歧义压缩成字段,让搜索系统更可靠抽取信息。

【代码实战】

html 复制代码
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "ACME Pro",
  "offers": { "@type": "Offer", "priceCurrency": "CNY", "price": "99" }
}
</script>

【避坑/优化】

  • 字段必须真实一致:结构化数据与页面展示不一致会引发信任问题,甚至影响展示资格。

H4. 什么是 Open Graph 协议?为什么对增长很关键?

【面试官在问什么】

  • 这题看你是否懂"分享即增长":社交卡片是用户点击决策的一部分。

【三维解析】

  • 官方定义(The Law)
    • Open Graph 使用 og:title/og:description/og:image 等 meta 定义分享卡片内容。
  • 白话逻辑(The Logic)
    • 你发链接到群里,别人看到的不是你的页面,是卡片。卡片就是你的广告位。
  • 底层内幕(The Metal)
    • 大多分享平台不会执行你的 JS,只抓取静态 meta;因此 OG 信息需要服务端稳定输出。

【代码实战】

html 复制代码
<meta property="og:title" content="ACME Pro:更快的交付">
<meta property="og:description" content="从性能到安全,一次性把工程底座打牢。">
<meta property="og:image" content="https://example.com/og.png">

【避坑/优化】

  • og:image 尺寸与格式要符合平台要求,否则卡片会退化成纯文本,点击率会掉。

I. Web Components(组件化)

I1. Web Components 的三大核心是什么?

【面试官在问什么】

  • 不是背名词,而是:你是否理解"浏览器级组件边界"能解决什么(样式隔离/跨栈复用),不能解决什么(状态/路由/生态)。

【三维解析】

  • 官方定义(The Law)
    • Custom Elements:自定义标签与生命周期。
    • Shadow DOM:样式与 DOM 封装边界。
    • HTML Templates:惰性模板定义(template/slot)。
  • 白话逻辑(The Logic)
    • 这是浏览器自带的"组件系统三件套":造标签、装盒子、塞模板。
  • 底层内幕(The Metal)
    • Shadow DOM 事件会 retarget,外部看到的 target 可能被重定向;埋点与事件委托要考虑这一点。

【代码实战】

js 复制代码
customElements.define("x-card", class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({ mode: "open" })
    this.shadowRoot.innerHTML = `<slot></slot>`
  }
})

【避坑/优化】

  • 组件隔离不是"拒绝定制":要给主题与可配置能力留出口(slot、CSS 自定义属性)。

I2. Shadow DOM 的作用是什么?它是"绝对隔离"吗?

【面试官在问什么】

  • 看你是否理解 Shadow DOM 的真实边界:样式作用域隔离,但主题与可访问性仍需设计。

【三维解析】

  • 官方定义(The Law)
    • Shadow DOM 为组件提供封装边界,外部 CSS 不会轻易影响内部(除非通过 CSS 自定义属性等机制)。
  • 白话逻辑(The Logic)
    • Shadow DOM 是"组件的私有房间",外人不能随便搬家具,但你可以留接口让它换窗帘。
  • 底层内幕(The Metal)
    • 封装会改变调试与选择器策略;事件与焦点管理更需要工程约束,否则很容易出现"可用但不好维护"的组件。

【代码实战】

css 复制代码
x-card { --card-border: #ddd; }
js 复制代码
this.shadowRoot.innerHTML = `
  <style>:host{border:1px solid var(--card-border)}</style>
  <slot></slot>
`

【避坑/优化】

  • 不要用 Shadow DOM 来逃避设计系统:组件库真正难的是一致性与可演进性。

I3. Custom Elements 如何创建和使用?生命周期里最容易踩的坑是什么?

【面试官在问什么】

  • 考你是否会写"可回收"的组件:初始化、属性变更、卸载清理。

【三维解析】

  • 官方定义(The Law)
    • 生命周期:connectedCallback/disconnectedCallback/attributeChangedCallback
  • 白话逻辑(The Logic)
    • 组件像一个小应用:挂载时启动,卸载时必须关掉定时器、事件监听。
  • 底层内幕(The Metal)
    • 泄漏通常来自:全局事件、订阅、计时器、闭包引用。生命周期没清理就会在长列表里炸内存。

【代码实战】

js 复制代码
customElements.define("x-ticker", class extends HTMLElement {
  connectedCallback() {
    this._timer = setInterval(() => this.textContent = Date.now(), 1000)
  }
  disconnectedCallback() {
    clearInterval(this._timer)
  }
})

【避坑/优化】

  • attributeChangedCallback 里避免做昂贵工作;先做 diff,再更新。

J. 现代应用(PWA / 微前端 / 离线编辑)

J1. PWA 需要哪些 HTML 技术支持?

【面试官在问什么】

  • 在问你是否理解:PWA 不是"加个 manifest",而是一套"可安装 + 可离线 + 可更新 + 体验一致"的系统工程。

【三维解析】

  • 官方定义(The Law)
    • 典型要素:Web App Manifest、Service Worker、HTTPS、可离线、可安装。
  • 白话逻辑(The Logic)
    • PWA 是"像 App 一样用的网站":能装、能离线、能快、能稳。
  • 底层内幕(The Metal)
    • 最大挑战是更新策略:缓存与版本共存会导致"你以为上线了,用户还在旧壳里"。必须设计明确的版本与刷新策略。

【代码实战】

html 复制代码
<link rel="manifest" href="/manifest.webmanifest">

【避坑/优化】

  • 离线可用不等于离线正确:离线编辑需要队列、冲突合并与回放机制。

J2. 微前端架构下的 HTML 设计有什么挑战?

【面试官在问什么】

  • 考你是否懂"容器职责":隔离、路由、样式、资源、SEO、可观测性如何分层。

【三维解析】

  • 官方定义(The Law)
    • 微前端没有单一标准,但隔离通常依赖 iframe、Web Components、Shadow DOM、CSS 隔离与 JS 沙箱等工程方案。
  • 白话逻辑(The Logic)
    • 微前端像"商场":每个店铺装修不同,但消防通道、指示牌、支付系统要统一。
  • 底层内幕(The Metal)
    • 真实问题是"全局污染":CSS 重置、字体、事件、历史路由、资源前缀、同名 id。HTML 层要约束:容器提供清晰挂载点、子应用不得污染 head 的全局策略(或必须通过平台 API 申请)。

【代码实战】

html 复制代码
<main id="micro-app-root"></main>

【避坑/优化】

  • 微前端不是"把多个 SPA 拼起来":没有治理就会变成多倍体积、多倍启动、多倍故障面。

J3. 如何设计支持离线编辑的 HTML 结构?

【面试官在问什么】

  • 这题在考系统设计:离线编辑的关键不在"能输入",而在"可恢复、可同步、可冲突合并"。

【三维解析】

  • 官方定义(The Law)
    • 离线编辑通常结合 IndexedDB(本地持久化)+ Service Worker(离线壳与队列)+ 后端版本控制/冲突合并策略。
  • 白话逻辑(The Logic)
    • 离线编辑像"断网写文档":断网时先写草稿,联网后再同步,还要处理别人也改了的冲突。
  • 底层内幕(The Metal)
    • HTML 结构要支持:状态提示(离线/同步中/冲突)、可恢复入口(草稿列表)、可追溯版本(时间戳/修订号)。

【代码实战】

html 复制代码
<header>
  <h1>文档编辑</h1>
  <p role="status" aria-live="polite" id="sync-status">已同步</p>
</header>
<main>
  <label for="editor">内容</label>
  <textarea id="editor" rows="12"></textarea>
</main>

【避坑/优化】

  • 只做"本地存草稿"不等于离线编辑:没有队列与冲突策略,上线后只会制造数据丢失事故。

K. 综合应用(Rich Text / DnD / IO / Worker)

K1. 如何设计一个富文本编辑器的 HTML 结构?

【面试官在问什么】

  • 考你对"可编辑区域的边界"与"可访问性替代"的理解:contenteditable 的风险、工具栏语义、快捷键与状态同步。

【三维解析】

  • 官方定义(The Law)
    • HTML 提供 contenteditable,但富文本编辑的完整体验依赖更复杂的编辑模型与可访问性设计。
  • 白话逻辑(The Logic)
    • 富文本不是"能打字",而是"有结构、有状态、有一致行为"的编辑系统。
  • 底层内幕(The Metal)
    • contenteditable 的行为在不同浏览器有差异;工程级编辑器通常会在其之上建立自己的文档模型(AST/OT/CRDT),把 DOM 当渲染层而不是数据源。

【代码实战】

html 复制代码
<div role="toolbar" aria-label="编辑工具栏">
  <button type="button" aria-pressed="false">加粗</button>
  <button type="button" aria-pressed="false">斜体</button>
</div>
<div id="editor" contenteditable="true" role="textbox" aria-multiline="true" aria-label="富文本编辑区"></div>

【避坑/优化】

  • 把 DOM 当"唯一真相"会导致不可维护:复制粘贴、撤销重做、协同编辑都会把你拖进深水区。

K2. 如何实现拖放(Drag & Drop)功能?可访问性怎么补?

【面试官在问什么】

  • 不是问你会不会写 dragstart,而是:你是否理解 DnD 的可访问性与可替代交互。

【三维解析】

  • 官方定义(The Law)
    • HTML Drag and Drop API 提供 dragstart/dragover/drop 等事件与 dataTransfer
  • 白话逻辑(The Logic)
    • 拖放是"鼠标路径交互",键盘用户需要"移动/放置"的替代操作。
  • 底层内幕(The Metal)
    • 原生 DnD 在移动端与跨浏览器一致性并不完美;工程上常用 pointer 事件模拟拖拽,DnD API 用于特定场景(例如文件拖入)。

【代码实战】

html 复制代码
<ul>
  <li draggable="true">任务 A</li>
  <li draggable="true">任务 B</li>
</ul>

【避坑/优化】

  • 必须提供键盘替代:例如"上移/下移"按钮,或快捷键移动条目,否则是功能缺失。

K3. Web Workers 能操作 DOM 吗?为什么?

【面试官在问什么】

  • 这题在考线程模型:你是否理解主线程与 UI 线程绑定,Worker 的隔离边界与通信成本。

【三维解析】

  • 官方定义(The Law)
    • MDN:Worker 运行在独立线程,不能访问 window/document 等 DOM API;通过 postMessage 与主线程通信。
  • 白话逻辑(The Logic)
    • Worker 是"后台工人",DOM 是"舞台道具"。后台工人不能上台搬道具,只能把建议发给舞台经理(主线程)。
  • 底层内幕(The Metal)
    • postMessage 默认结构化克隆会复制数据;大数据频繁传递会把通信本身变成瓶颈,必要时用 Transferable(例如 ArrayBuffer)减少复制成本。

【代码实战】

js 复制代码
worker.postMessage({ type: "calculate", payload: [1, 2, 3] })

【避坑/优化】

  • Worker 适合 CPU 密集计算,不适合高频小消息往返的 UI 逻辑。

K4. Intersection Observer API 有什么作用?

【面试官在问什么】

  • 这题在考你是否懂"以可见性驱动的工程化":懒加载、曝光埋点、虚拟列表触发条件。

【三维解析】

  • 官方定义(The Law)
    • Intersection Observer 用于异步观察目标元素与视口(或容器)的交叉状态,避免频繁 scroll 监听带来的性能问题。
  • 白话逻辑(The Logic)
    • 它像一个"可见性雷达":元素快进入视口就通知你。
  • 底层内幕(The Metal)
    • 相比 scroll + getBoundingClientRect,IO 更接近引擎调度模型,减少同步布局风险与回调风暴。

【代码实战】

js 复制代码
const io = new IntersectionObserver((entries) => {
  for (const e of entries) {
    if (e.isIntersecting) e.target.classList.add("seen")
  }
})
document.querySelectorAll("[data-track]").forEach((el) => io.observe(el))

【避坑/优化】

  • 曝光埋点要防抖与去重,避免多次上报;观察结束要 unobserve 降低开销。

L. 兼容性与标准(Compatibility & Standards)

L1. 如何处理 HTML5 标签在旧浏览器的兼容问题?什么是 polyfill?

【面试官在问什么】

  • 考你是否知道"渐进增强"的正确姿势:功能检测、按需加载、可降级体验。

【三维解析】

  • 官方定义(The Law)
    • polyfill 用 JS 模拟缺失 API 行为;但对原生解析能力(例如新标签语义)并非都能完全复刻。
  • 白话逻辑(The Logic)
    • polyfill 像"给老车加装新配件",能补部分能力,但不是把老车变新车。
  • 底层内幕(The Metal)
    • 兼容策略要以"用户可完成任务"为目标:不支持的能力做降级,不要强行一致导致体积暴涨。

【代码实战】

js 复制代码
if (!("IntersectionObserver" in window)) {
  // 按需加载 polyfill(示意)
}

【避坑/优化】

  • 兼容不是"一刀切":要基于真实用户分布与性能预算做取舍。

L2. 条件注释是什么?现在还有用吗?

【面试官在问什么】

  • 这题用来测试你是否了解历史,以及能否给出"现代替代方案"。

【三维解析】

  • 官方定义(The Law)
    • 条件注释主要是旧 IE 的机制,现代浏览器不支持。
  • 白话逻辑(The Logic)
    • 它是"只给 IE 看的小纸条"。
  • 底层内幕(The Metal)
    • 现代做法是:特性检测(feature detection)+ 渐进增强,而不是浏览器嗅探。

【代码实战】

js 复制代码
const supports = "CSS" in window && CSS.supports && CSS.supports("position", "sticky")

【避坑/优化】

  • 只要你还在依赖 UA sniffing,迟早会被新 UA/壳浏览器打脸。

L3. DOCTYPE 的作用是什么?为什么会影响布局?

【面试官在问什么】

  • 在考"怪异模式"的认知:你是否知道 DOCTYPE 决定标准模式,避免浏览器用历史兼容的怪异渲染。

【三维解析】

  • 官方定义(The Law)
    • DOCTYPE 用于触发标准模式(Standards Mode),避免进入 Quirks Mode。
  • 白话逻辑(The Logic)
    • DOCTYPE 是"告诉浏览器按现代规则来",否则它可能按旧时代规则兼容你。
  • 底层内幕(The Metal)
    • Quirks Mode 下盒模型等规则可能不同,导致同一套 CSS 表现不一致,出现"只在某些环境错位"的噩梦。

【代码实战】

html 复制代码
<!doctype html>

【避坑/优化】

  • 没 DOCTYPE 的页面不要指望"修 CSS 就行",先把模式拉回标准模式再谈布局。

L4. HTML 和 XHTML 有什么区别?为什么工程上越来越少谈 XHTML?

【面试官在问什么】

  • 考你对错误处理模型的理解:XML 的"严苛失败"与 HTML 的"容错渲染"在工程上意味着什么。

【三维解析】

  • 官方定义(The Law)
    • XHTML 是 XML 序列化的 HTML:要求严格闭合与合法嵌套;HTML 解析器则具有明确的错误恢复机制。
  • 白话逻辑(The Logic)
    • XHTML 像"严格考试",错一个符号就零分;HTML 像"自动纠错",能救就救。
  • 底层内幕(The Metal)
    • 严格解析在 Web 现实里往往带来灾难性失败(整页不渲染),而 HTML 的容错更符合互联网的不确定性。

【代码实战】

HTML 容错让页面仍可显示,但结构可能被纠正,所以工程更需要校验与规范:

html 复制代码
<p><div>bad nesting</div></p>

【避坑/优化】

  • 依赖"浏览器会帮我修"不是工程能力:要用校验工具、Lint 与组件化约束把错误挡在上线前。

L5. HTML Living Standard 是什么?对工程有什么影响?

【面试官在问什么】

  • 考你是否理解标准与实现的关系:Web 是持续演进的,不是"HTML5 一次发布就结束"。

【三维解析】

  • 官方定义(The Law)
    • HTML Living Standard 是持续维护、持续更新的标准形态。
  • 白话逻辑(The Logic)
    • 标准不是一本"出完就封存的书",而是一条持续升级的"产品规格说明"。
  • 底层内幕(The Metal)
    • 工程策略要跟随实现成熟度:特性检测、渐进增强、灰度与回滚,都是和"持续演进"配套的工程能力。

【代码实战】

js 复制代码
if ("serviceWorker" in navigator) {
  // 渐进增强
}

【避坑/优化】

  • 不要把"规范支持"当作"线上可用":要看浏览器实现、生态与真实用户覆盖。

M. 架构设计(HTML 结构如何服务工程化)

M1. 如何设计一个支持主题切换的 HTML 结构?

【面试官在问什么】

  • 考你是否知道主题切换的本质是"状态驱动样式",HTML 要提供稳定的挂载点与无障碍一致性。

【三维解析】

  • 官方定义(The Law)
    • 主题通常通过 class/data-attribute + CSS 变量实现;偏好可结合 prefers-color-scheme
  • 白话逻辑(The Logic)
    • 主题切换像"换一套皮肤",结构不变,变量换。
  • 底层内幕(The Metal)
    • 主题切换要避免大面积重排,CSS 变量更利于局部更新;同时要处理持久化与初次渲染闪烁(FOUC)。

【代码实战】

html 复制代码
<html data-theme="dark">
css 复制代码
:root { --bg: #fff; --fg: #111; }
html[data-theme="dark"] { --bg: #111; --fg: #fff; }
body { background: var(--bg); color: var(--fg); }

【避坑/优化】

  • 初次渲染主题要与用户偏好一致,否则会出现闪烁;工程上常用早期注入或服务端渲染写入主题属性。

M2. 如何设计组件化的 HTML 结构?

【面试官在问什么】

  • 考你是否能把"组件边界"设计成可维护契约:结构、语义、可访问性、测试锚点。

【三维解析】

  • 官方定义(The Law)
    • 组件化是工程实践,但语义与 ARIA 规则依然需要满足 HTML/WAI-ARIA 约束。
  • 白话逻辑(The Logic)
    • 组件不是"复制粘贴",是"可组合的协议块"。
  • 底层内幕(The Metal)
    • 组件边界要避免污染全局(id 冲突、head 注入、全局样式),并提供稳定可测的选择器策略(例如 data-testid,但要克制使用)。

【代码实战】

html 复制代码
<article aria-label="商品卡片">
  <h2>ACME Pro</h2>
  <p>¥99</p>
  <button type="button">加入购物车</button>
</article>

【避坑/优化】

  • 可访问性必须作为组件契约的一部分,否则组件复用越多,系统性缺陷越大。

M3. 如何处理大量数据的表格渲染?如何实现虚拟滚动?

【面试官在问什么】

  • 考你是否理解 DOM 成本与渲染同步点:大表格不是"数据多",是"节点多 + 计算多 + 更新频繁"。

【三维解析】

  • 官方定义(The Law)
    • 虚拟滚动是工程优化策略:只渲染可视区域与缓冲区节点,减少 DOM 与布局压力。
  • 白话逻辑(The Logic)
    • 你不需要把仓库所有货都摆在柜台,只摆顾客看得到的那一排。
  • 底层内幕(The Metal)
    • 节点数量影响样式计算、布局、绘制;滚动时频繁更新会触发同步点。虚拟滚动核心是:稳定容器高度 + translate 偏移 + 只渲染窗口。

【代码实战】

HTML 结构示意(虚拟列表容器):

html 复制代码
<div class="viewport" style="height:400px; overflow:auto;">
  <div class="spacer" style="height:20000px; position:relative;">
    <div class="window" style="position:absolute; top:0; left:0; right:0;">
      <!-- 只渲染可视区行 -->
    </div>
  </div>
</div>

【避坑/优化】

  • 表格语义别随便丢:真正的 <table> 有可访问性与语义价值,虚拟化时要保证读屏与键盘导航的可用性(必要时提供替代视图)。

N. 调试与测试(Debug & QA)

N1. 如何检查页面的无障碍(A11y)问题?

【面试官在问什么】

  • 考你是否有"工具 + 人工"的闭环:自动化只能覆盖一部分,真实问题在交互与语义一致性。

【三维解析】

  • 官方定义(The Law)
    • WCAG 提供无障碍准则;常见工具(axe、Lighthouse、浏览器无障碍树)提供自动检查与提示。
  • 白话逻辑(The Logic)
    • 工具像体检报告,能查出指标异常;但"能不能走路"要你自己试。
  • 底层内幕(The Metal)
    • 关键检查清单:标题层级、landmark、可聚焦顺序、可访问名称、表单关联、动态内容通告(aria-live)。

【代码实战】

动态提示用 aria-live:

html 复制代码
<p id="status" role="status" aria-live="polite"></p>

【避坑/优化】

  • 只跑工具不做键盘走查=伪 A11y。至少要用 Tab 把核心流程走通。

N2. Lighthouse 可以检查哪些 HTML 相关问题?

【面试官在问什么】

  • 考你是否能把"检查结果"变成"可回归的工程动作":性能、可访问性、最佳实践、SEO。

【三维解析】

  • 官方定义(The Law)
    • Lighthouse 报告包含 Performance/A11y/Best Practices/SEO 等维度,很多问题直接指向 HTML 结构与资源策略。
  • 白话逻辑(The Logic)
    • Lighthouse 不是"打分游戏",是"把问题列表化、可回归化"的工具。
  • 底层内幕(The Metal)
    • 与 HTML 强相关的常见项:图片缺尺寸、无 alt、阻塞资源、无 meta description、缺可访问名称、对比度与可聚焦性等。

【代码实战】

给图片补尺寸减少 CLS:

html 复制代码
<img src="/img/a.jpg" width="800" height="600" alt="示例">

【避坑/优化】

  • 分数不是目标,指标与用户体验才是;要把优化与业务转化/留存挂钩。

N3. 如何测试不同屏幕尺寸的显示效果?

【面试官在问什么】

  • 考你是否有"响应式验证"流程:断点策略、字体缩放、触控命中区域、动态内容。

【三维解析】

  • 官方定义(The Law)
    • 响应式基于媒体查询与弹性布局;实际体验还受 DPR、字体设置与输入方式影响。
  • 白话逻辑(The Logic)
    • 不同屏幕不是"缩放",是"布局策略切换"。
  • 底层内幕(The Metal)
    • 真实事故常发生在:极窄屏、超宽屏、系统字体放大、长文本国际化、软键盘弹出导致视口变化。

【代码实战】

css 复制代码
@media (max-width: 600px) { .layout { padding: 12px; } }

【避坑/优化】

  • 只测 iPhone/Chrome 不够:要覆盖至少一个 Android WebView 场景与系统字体放大。

O. 性能监控(Observability)

O1. 哪些 HTML 因素会影响 LCP(最大内容绘制)?

【面试官在问什么】

  • 考你是否理解 LCP 是"资源 + 解码 + 主线程 + 渲染同步点"的合成结果,而不是单点优化。

【三维解析】

  • 官方定义(The Law)
    • LCP 关注最大内容元素的渲染完成时间,常见是大图或大文本块。
  • 白话逻辑(The Logic)
    • 用户等的就是"最重要那块内容什么时候出现",LCP 就在量这个。
  • 底层内幕(The Metal)
    • 影响 LCP 的 HTML 层因素:首屏图是否懒加载、图片候选选择是否正确、是否缺尺寸导致布局抖动、关键 CSS 是否阻塞、脚本是否抢占主线程。

【代码实战】

首屏图避免 lazy,并明确尺寸:

html 复制代码
<img src="/img/hero.jpg" width="1200" height="600" alt="主视觉">

【避坑/优化】

  • 把首屏大图放在轮播第一帧再 lazy,是最常见的"自杀式优化"。

O2. 如何监控 DOM 大小对性能的影响?

【面试官在问什么】

  • 考你是否能把"复杂度"变成指标:DOM 体积、深度、更新频率,并做治理。

【三维解析】

  • 官方定义(The Law)
    • 浏览器性能受 DOM 规模影响是事实:更多节点意味着更多样式计算、布局与绘制成本。
  • 白话逻辑(The Logic)
    • DOM 就是你的"渲染债务"。债务越大,利息越高。
  • 底层内幕(The Metal)
    • 大 DOM 常导致:样式计算慢、布局慢、内存占用高、交互响应差(INP 变差)。治理策略包括虚拟化、减少嵌套、避免隐藏但仍在 DOM 的大块内容。

【代码实战】

js 复制代码
const nodeCount = document.getElementsByTagName("*").length

【避坑/优化】

  • 不要只在 DevTools 里看一次:要做线上采样,把 DOM 体积与性能指标关联,才知道"哪里该动刀"。

3. 连点成面:高阶追问(The Counter-Attack)

3.1 追问:你说"语义化对 SEO 有用",怎么证明不是玄学?

  • 满分话术:我会把验证拆成结构信号与结果指标两层。结构层通过爬虫模拟/抓取日志确认抓取覆盖与主要内容抽取是否稳定;结果层观察自然流量、核心词排名、点击率变化,并排除页面改版的其他变量。语义化的本质是降低机器理解成本,效果应该能在"抽取稳定性与索引效率"上体现。

3.2 追问:为什么 async 的 bug 往往"只在弱网出现"?

  • 满分话术:因为 async 的执行时机取决于下载完成的瞬间,而下载完成受网络/缓存/连接复用影响,时序不稳定。依赖 DOM 或依赖脚本顺序的逻辑会随机提前执行,从而形成偶现。defer 的价值是把执行时序收敛为"解析完成后按顺序执行",把不确定性从系统里移除。

3.3 追问:你说"localStorage 会卡",你怎么向业务解释?

  • 满分话术:localStorage 是同步 API,高频写入会占用主线程,表现为输入延迟与掉帧。对业务来说就是"打字卡、按钮慢、转化跌"。我的策略是:小且低频才用 localStorage;高频与大对象用 IndexedDB,并把写入做成批处理与节流。

3.4 追问:CSP 会不会把业务搞挂?你怎么安全落地?

  • 满分话术:会,所以不能"一步到位"。正确落地是:先上 report-only 收集违例,盘点脚本资产;再逐步收敛来源,替换内联脚本为 nonce/hash;最后强制执行并保留回滚开关。CSP 是治理工程,不是配置项。

4. 总结与金句(The Summary)

4.1 三条底层哲学

  • HTML 是协议层,不是模板语言:它承载语义、策略与边界,决定了 SEO/A11y/安全/性能的上限。
  • 性能是同步点管理:减少关键路径阻塞,减少主线程争抢,让 LCP/INP 变成"可预测结果"。
  • 安全是默认值:noopener、CSP、HttpOnly、SameSite 不是可选项,是你作为负责人给团队定的底线。

4.2 面试官杀手锏清单(最难的 3 个点)

  • CRP + async/defer 时序:能把"解析器互锁、阻塞点、稳定策略"讲清楚的人非常少。
  • CSP/XSS 体系化防护:能讲闭环(编码+策略+治理+监控)直接拉开档位。
  • 离线体系(SW + 存储 + 更新/回滚):能把缓存变成可控系统,而不是赌运气。

5. 🎯 高频必考 TOP 10(背题不如背"答案骨架")

  1. HTML5 语义化标签及其意义:机器可理解(SEO/A11y)+ 团队契约(可维护)
  2. 浏览器渲染流程:DOM/CSSOM → 渲染树 → 布局 → 绘制 → 合成
  3. async 和 defer 的区别:时序稳定性 vs 不确定性
  4. 浏览器存储方案对比:同步/异步、容量、生命周期、安全面
  5. 重绘与重排:同步布局是性能杀手
  6. 无障碍(A11y)设计:语义优先、ARIA 兜底、键盘可达
  7. 响应式图片实现:srcset/sizes + 尺寸占位 + LCP 策略
  8. XSS 防护方法:输出编码 + CSP + 危险 API 治理
  9. SEO 优化技巧:结构、元信息、结构化数据、可索引性
  10. 性能优化方案:关键路径预算 + 可观测指标驱动
相关推荐
一 乐2 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
zzjyr2 小时前
Webpack 生命周期原理深度解析
前端
xiaohe06012 小时前
💘 霸道女总裁爱上前端开发的我
前端·游戏开发·trae
sophie旭2 小时前
内存泄露排查之我的微感受
前端·javascript·性能优化
k***1952 小时前
Spring 核心技术解析【纯干货版】- Ⅶ:Spring 切面编程模块 Spring-Instrument 模块精讲
前端·数据库·spring
努力学算法的蒟蒻2 小时前
day58(1.9)——leetcode面试经典150
算法·leetcode·面试
rgeshfgreh3 小时前
Spring事务传播机制深度解析
java·前端·数据库
Hilaku3 小时前
我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)
前端·javascript·github