主题
第 01 章 · HTML 面试题集
Q1:什么是语义化 HTML?为什么要用语义化标签?
考察点:HTML5 语义化、SEO、无障碍
标准答案(适合背诵): 语义化 HTML 是指使用有明确含义的标签来描述内容结构(如 <header>、<nav>、<article>、<footer>),而不是一律用 <div> 和 <span>。它的好处有四点:
- SEO 友好:搜索引擎能更好理解页面结构,提升排名。
- 无障碍:屏幕阅读器能正确朗读出"这是导航、这是文章主体"。
- 可维护性:代码自带文档属性,团队协作时一眼能看懂。
- 样式默认值与行为:如
<button>自带键盘可达和点击事件,<div>模拟按钮要手动加。
通俗理解(生活类比): 就像快递盒子——你写"易碎品"和写"X-001"哪个更有用?语义化标签就是给浏览器和爬虫看的"易碎品"贴纸。
代码示例:
html
<!-- ❌ 全是 div -->
<div class="header">
<div class="title">站名</div>
<div class="nav"><div>首页</div></div>
</div>
<!-- ✅ 语义化 -->
<header>
<h1>站名</h1>
<nav><a href="/">首页</a></nav>
</header>加分回答(拉开差距):
- 语义化标签不影响样式,外观完全可以由 CSS 控制,所以"用语义化标签"和"页面好看"是两码事。
- HTML5 之前没有
<header>、<nav>这些标签,大家用<div class="header">凑数,HTML5 把这些"约定俗成的 class"扶正成了正式标签。 - 不要为了"语义化"硬塞标签,找不到合适的就用
<div>,不要错用比不用更糟。
追问:
<section>和<article>有什么区别?- 一个页面可以有多个
<header>吗? - 你能列出 HTML5 新增的 5 个语义化标签吗?
Q2:<section> 和 <article> 的区别是什么?
考察点:语义化标签的细微差别
标准答案:
<article>:独立、完整的内容单元,把它单独拿出去放到别的网站也能看懂。例如一篇博客文章、一条微博、一条评论。<section>:内容的主题分组,必须包含标题(h1~h6),通常是一个文档/文章内的章节。
判断口诀:"能不能单独发布"——能 → article,不能 → section。
通俗理解:
<article>像一本独立的书,能从图书馆借走单读。<section>像书里的一章,离开整本书就不完整了。
代码示例:
html
<article>
<h1>《前端入门》</h1>
<section>
<h2>第一章 HTML</h2>
<p>……</p>
</section>
<section>
<h2>第二章 CSS</h2>
<p>……</p>
</section>
</article>加分回答:
<article>内可以再嵌套<article>,例如博客的"评论"也是一个 article。- 都不合适时,请直接用
<div>,别强行套语义化。 <section>不能没有标题,否则用<div>即可。
追问:
- 一个页面可以有多个
<article>吗? <aside>和<section>又有什么区别?
Q3:行内元素和块级元素的区别?哪些是行内、哪些是块级?
考察点:HTML 元素分类、默认显示行为
标准答案:
| 维度 | 块级元素 | 行内元素 |
|---|---|---|
| 是否独占一行 | 是 | 否,可以并排 |
| 宽高 | 可设置 | 不可设置(跟随内容) |
| 内外边距 | 上下左右都生效 | 只有左右生效,上下无效(margin) |
| 包含关系 | 可包含块级和行内 | 只能包含行内(不能包块级) |
常见块级:div、p、h1~h6、ul、ol、li、header、footer、section、article、form、table
常见行内:span、a、strong、em、i、b、label
行内块(inline-block,可设宽高但不独占行):img、input、button
通俗理解: 块级像"整盒披萨",自己占一桌;行内像"瓜子",可以一排排着吃。
代码示例:
html
<div>我独占一行</div>
<div>我也独占一行</div>
<span>我和</span><span>它在一行</span>加分回答:
- 行内元素的"上下 margin 无效"是常见面试坑题。
- 用 CSS 的
display: block | inline | inline-block可以互相切换。 - HTML5 不再用"块/行"来分类,新分类是"流式内容、短语内容、嵌入内容、交互内容"等,但面试中通常还是问块/行。
追问:
<a>里能放<div>吗?(HTML5 中可以,HTML4 不行)display: inline-block和display: inline区别?
Q4:<img> 标签的 alt 属性有什么作用?
考察点:无障碍、SEO
标准答案: alt 是图片的替代文字,作用有三:
- 图片加载失败时,浏览器显示这段文字;
- 屏幕阅读器朗读这段文字给视障用户听;
- 搜索引擎通过 alt 索引图片内容(图片 SEO 的核心)。
通俗理解: 就像快递盒上贴的"内含一只猫的玩偶"——盒子破了你也知道里面是啥。
代码示例:
html
<!-- ✅ 描述性 alt -->
<img src="cat.jpg" alt="一只橘猫趴在窗台上" />
<!-- ✅ 装饰性图片:写空字符串,告诉屏幕阅读器"忽略" -->
<img src="divider.png" alt="" />
<!-- ❌ 不写 alt -->
<img src="cat.jpg" />加分回答:
title属性是鼠标悬停提示,不能替代 alt。- 如果图片是按钮(如
<a><img></a>),alt 应描述"点击后做什么",而不是图片长什么样。例如alt="返回首页"而不是alt="一个房子图标"。 - 装饰图片要写
alt="",不要省略 alt 属性,否则屏幕阅读器会朗读图片文件名(很难听)。
追问:
<picture>标签是什么?- 响应式图片用什么属性?(
srcset、sizes)
Q5:<a> 标签的 target="_blank" 有什么安全隐患?怎么解决?
考察点:Web 安全基础
标准答案: target="_blank" 在新标签页打开链接,但新页面的 window.opener 指向原页面,恶意网站可以通过 window.opener.location = "钓鱼网址" 把原页面跳转到钓鱼网站,用户切回去发现"被悄悄换页"。
解决方法:加上 rel="noopener noreferrer"。
通俗理解: 你介绍朋友 A 去 B 家做客,B 拿到了 A 的钥匙——就算 A 不在场,B 也能改 A 家的门牌号。noopener 就是"不给钥匙"。
代码示例:
html
<!-- ✅ 推荐 -->
<a href="https://other.com" target="_blank" rel="noopener noreferrer">
外部链接
</a>加分回答:
noopener:新页面拿不到window.opener,无法反向控制原页面。noreferrer:新页面的 HTTP 请求里不带Referer头,对方网站不知道你从哪来(隐私保护)。- 现代浏览器(Chrome 88+)已默认对
target="_blank"启用noopener,但显式写一行更稳。
追问:
target还能取哪些值?(_self、_parent、_top、自定义 frame 名)<a href="javascript:void(0)">是干嘛的?为什么不推荐?
Q6:表单中 GET 和 POST 提交的区别?
考察点:HTTP 基础与表单
标准答案:
| 维度 | GET | POST |
|---|---|---|
| 数据位置 | 拼接在 URL 后(?key=value) | 放在请求体(body) |
| 长度限制 | 受 URL 长度限制(约 2KB) | 几乎无限制 |
| 缓存 | 可被浏览器缓存 | 不缓存 |
| 安全性 | 参数暴露在 URL 和历史记录中 | 相对隐藏(但非真正"安全") |
| 幂等性 | 是(多次调用结果相同) | 否 |
| 适用场景 | 查询、搜索 | 提交、登录、上传 |
通俗理解:
- GET:在奶茶店门口大喊"我要一杯珍珠奶茶不加冰"——所有人都听到。
- POST:递一张点单小票给店员——别人看不到内容。
代码示例:
html
<form action="/search" method="GET">
<input name="q" /> <button>搜索</button>
</form>
<!-- 提交后:URL 变成 /search?q=xxx -->
<form action="/login" method="POST">
<input name="user" />
<input name="pwd" type="password" />
<button>登录</button>
</form>
<!-- 提交后:参数在请求体里,URL 不变 -->加分回答:
- POST 不是"安全",只是"不在 URL 里"。真正的安全要靠 HTTPS。
- POST 也可以加查询参数到 URL,body 里放主体数据。
- 浏览器会警告 POST 表单刷新页面("是否重新提交"),GET 不会,因为 GET 幂等。
- RESTful 接口里:GET 查、POST 增、PUT 改、DELETE 删。
追问:
- 表单文件上传用什么 method?(POST,且
enctype="multipart/form-data") - 跨域 POST 会触发什么?(预检请求 OPTIONS)
Q7:HTML5 新增了哪些重要特性?
考察点:HTML5 知识广度
标准答案: HTML5 是 2014 年正式发布的版本,相对 HTML4 的主要新增:
- 语义化标签:
<header>、<nav>、<main>、<article>、<section>、<aside>、<footer>、<figure>、<figcaption>。 - 多媒体标签:
<audio>、<video>,原生支持音视频,不再依赖 Flash。 - 表单增强:
type="email/url/date/color/range/number/tel"、required、pattern、autocomplete。 - 绘图能力:
<canvas>(基于像素的位图绘图)、<svg>(基于矢量的图形)。 - 本地存储:
localStorage、sessionStorage,比 cookie 容量大、不随请求发送。 - 新 API:地理位置(Geolocation)、拖拽(Drag & Drop)、Web Workers(多线程)、WebSocket(双向通信)、History API(前端路由)。
- 离线应用:Application Cache(已废弃,被 Service Worker 取代)。
通俗理解: HTML4 是"功能机",HTML5 是"智能机"——新增了相机(canvas)、录音(audio)、定位(Geolocation)等"硬件"。
代码示例:
html
<input type="email" required placeholder="请输入邮箱" />
<input type="date" />
<video src="movie.mp4" controls></video>
<canvas id="c" width="300" height="150"></canvas>加分回答:
<!DOCTYPE html>简化为一行(HTML4 是一长串 DTD)。- 标签大小写不敏感、属性值可省略引号(不推荐),HTML5 更宽容。
- HTML5 移除了一些表现层标签(
<font>、<center>),鼓励用 CSS 处理样式。
追问:
- canvas 和 svg 有什么区别?
- localStorage 和 cookie 有什么区别?
- Web Worker 解决了什么问题?
Q8:localStorage、sessionStorage、cookie 三者区别?
考察点:浏览器存储
标准答案:
| 维度 | cookie | localStorage | sessionStorage |
|---|---|---|---|
| 容量 | 4 KB | 5~10 MB | 5~10 MB |
| 生命周期 | 可设置过期时间 | 永久(除非手动删) | 标签页关闭即清除 |
| 是否随请求发送 | 是(每次 HTTP 请求都带) | 否 | 否 |
| 作用域 | 同源(含子域名可配) | 同源 | 同源 + 同标签页 |
| 主要用途 | 服务器认证(如 session id) | 长期客户端数据(主题、草稿) | 一次会话内的临时数据 |
通俗理解:
- cookie:你的会员卡(每次进店都要刷一下)。
- localStorage:你家的相册(永久保存在自己设备上)。
- sessionStorage:今天的购物车(关掉浏览器就没了)。
代码示例:
js
localStorage.setItem('theme', 'dark');
localStorage.getItem('theme'); // 'dark'
localStorage.removeItem('theme');
localStorage.clear();
sessionStorage.setItem('step', '2');
document.cookie = 'name=zhangsan; max-age=3600';加分回答:
- cookie 默认随所有请求(包括图片、CSS)发送,频繁使用浪费带宽。
HttpOnlycookie:JS 读不到,能防 XSS 偷取。Securecookie:只在 HTTPS 下发送。SameSite=Strict/Lax/None:防 CSRF 攻击。- 如果数据敏感且持久,用
IndexedDB(容量更大、支持索引和事务)。
追问:
- 怎么实现"记住我"功能?
- 跨域如何共享 localStorage?(不能直接共享,可用 postMessage + iframe 桥接)
- token 放 localStorage 还是 cookie?
Q9:<meta> 标签都有哪些常见用途?
考察点:HTML head、SEO、移动端适配
标准答案: <meta> 用于在 head 中声明页面的元信息,常见用法:
| meta 写法 | 作用 |
|---|---|
<meta charset="UTF-8"> | 字符编码(必写,避免乱码) |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | 移动端视口设置 |
<meta name="description" content="..."> | 页面描述(SEO) |
<meta name="keywords" content="..."> | 关键词(已不重要) |
<meta name="author" content="张三"> | 作者 |
<meta http-equiv="refresh" content="5;url=/login"> | 5 秒后跳转 |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | IE 用最新内核渲染 |
<meta name="robots" content="noindex,nofollow"> | 告诉爬虫不索引 |
<meta property="og:title" content="..."> | Open Graph,社交媒体分享卡片 |
通俗理解: <meta> 是网页的"身份证背面"——用户看不见,但浏览器、搜索引擎、微信分享都靠它了解你。
代码示例:
html
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="零基础前端学习笔记" />
<meta property="og:image" content="https://example.com/cover.jpg" />
</head>加分回答:
- viewport 的
user-scalable=no会禁用缩放,不推荐(影响视障用户)。 - Open Graph 是 Facebook 提出的协议,微信分享卡片也用它。
- 微信里还认
<meta name="apple-mobile-web-app-capable">等私有 meta。
追问:
- 为什么
<meta charset>必须放在 head 最前面? - 怎么禁止页面被 iframe 嵌入?(HTTP 响应头
X-Frame-Options,meta 不能完全做到)
Q10:<script> 标签的 defer 和 async 有什么区别?
考察点:脚本加载、性能优化
标准答案:
| 模式 | 下载 | 执行 | DOM 解析 |
|---|---|---|---|
默认 <script> | 同步阻塞 | 立即执行 | 暂停解析 |
<script defer> | 异步并行 | DOM 解析完后、DOMContentLoaded 前 | 不阻塞 |
<script async> | 异步并行 | 下载完立即执行(可能阻塞解析) | 不阻塞 |
执行时序图:
默认: [HTML 解析]──[暂停]──[下载]──[执行]──[继续解析]
defer: [HTML 解析────────────────────────] 完成后→[执行]
async: [HTML 解析──────[下载完中断──执行]──继续解析]通俗理解:
- 默认:边逛超市边买冰淇淋——必须停下来挑完才能走。
defer:让别人帮你买,你先逛完整个超市再去结账拿。async:让别人帮你买,到了就立刻送到你手上(哪怕你还在逛)。
代码示例:
html
<!-- 同步阻塞 -->
<script src="a.js"></script>
<!-- 推荐:所有 defer 按写的顺序执行 -->
<script defer src="b.js"></script>
<script defer src="c.js"></script>
<!-- 用于独立的、跟 DOM 无关的脚本(统计、广告) -->
<script async src="analytics.js"></script>加分回答:
defer多个脚本保持顺序执行;async谁先下完谁先执行,无序。defer/async只对外部脚本生效,行内<script>加了也忽略。- 现代项目可把
<script>放在</body>之前,效果类似 defer,且兼容老浏览器。 - ES Module(
<script type="module">)默认就是 defer 行为。
追问:
<script type="module">有什么特点?- 为什么很多模板把
<script>放在 body 末尾?