对于HTML:HTML常见标签的解析—下

开篇介绍:

hello 大家,本篇博客我们就来对HTML常见标签进行一个小完结~

在上一篇解析中,我们聊了标题、段落、图片、链接等基础展示类标签 ------ 那些标签是网页的 "血肉",负责把内容展示给用户看。但你有没有想过:

  • 你每天上网填的登录框、注册页、购物车结算、问卷调研,是怎么把你的信息从浏览器传到服务器的?
  • 你看到的网页头部、导航栏、侧边栏、底部版权页,是怎么用 "有逻辑的结构" 而非 "乱套的盒子" 搭建的?
  • 你想给一段文字里的某个关键词标红、某个价格加粗、某个日期加灰色,是怎么精准控制到 "那几个字" 的?

答案就是:HTML 的核心高频标签------ 表单标签实现 "用户与网站的对话",无语义标签(div/span)实现 "网页的精细化布局",再配合 Emmet 快捷键提升效率,特殊字符解决 "字符冲突" 问题。

话不多说,咱们正式开启这场 HTML 核心标签的深度之旅!


第一章:表单标签 ------ 用户与网站的 "唯一对话窗口"

如果说网页是一个 "商店",那么展示类标签(h1/p/img)就是 "商店的橱窗和货架",负责展示商品;而表单标签就是 "商店的收银台和服务台"------ 用户在这里填写信息、提交需求,商店(后端)在这里接收信息、处理需求。

你可以把表单想象成你去银行办理业务时填的 "空白申请表单":

  • 你填的 "姓名、手机号、身份证号、家庭住址",就是表单控件(input/select/textarea)------ 这些是你要填的具体内容;
  • 这张纸框住所有填写项,还在右上角标注了 "填完后交给 3 号窗口",就是表单域(form 标签)------ 它划定了范围,指定了目标;
  • 你填完后按的 "提交""重新填写",就是按钮控件(submit/reset)------ 它触发了 "提交" 或 "清空" 的动作。

表单是前端和后端交互的唯一官方渠道------ 没有表单,用户就无法给网站传信息,网站也无法给用户提供个性化服务(比如登录、注册、下单、修改个人信息)。

1.1 表单的两大核心构成:表单域 + 表单控件

一个完整的、能工作的表单,绝对不是随便写几个输入框就行的,它必须分成两个不可分割、缺一不可的部分:

  1. 表单域(form 标签):包裹所有表单控件的 "大盒子",负责告诉浏览器 "哪些控件是一组的""填完的信息要传给谁""怎么传";
  2. 表单控件:用户实际输入 / 选择信息的 "小单元",比如文本框、密码框、单选框、复选框、下拉菜单、文本域、按钮等。

没有表单域的控件,就像 "无主的废纸"------ 你填了也白填,浏览器不知道要把这些信息交给谁,点击提交按钮也不会有任何反应;没有控件的表单域,就是 "一张空白的纸"------ 没有可收集的信息,完全没用。


1.2 表单域:form 标签 ------ 申请表单的 "总容器"

<form> 是所有表单控件的 "载体",也是前端和后端沟通的 "中间人",它是闭合标签 (必须有开始标签<form>和结束标签</form>,哪怕浏览器有时候会自动补全,你也必须手动写,这是规范)。

1.2.1 核心定义

你可以把 <form> 标签完完全全想象成银行给你的 "空白申请表单页":

  • 这张纸有明确的边界------ 所有要填的内容(姓名、手机号、身份证号)都必须写在这张纸的边界里面,写在外面的银行柜员不会看;
  • 这张纸的右上角会明确标注 **"填完后交给哪个窗口处理"**------ 比如 "开户窗口""挂失窗口""贷款窗口",这样你才知道要把填好的单子给谁;
  • 这张纸还会隐含告诉你 **"递单子的方式"**------ 比如 "直接念出来"(快,但不安全,适合简单查询),或者 "装在信封里密封递过去"(慢,但安全,适合提交重要信息)。

对应到 HTML 里:

  • 边界就是 <form> 和 </form> 之间的区域 ------ 所有表单控件必须放在这里面;
  • "交给哪个窗口" 就是 action 属性 ------ 后端接口的 URL;
  • "递单子的方式" 就是 method 属性 ------GET 或 POST。
1.2.2 关键作用(为什么必须有 form?)

很多新手会问:"我直接写几个 input 和按钮不行吗?为什么要多此一举套个 form?"答案是:没有 form,浏览器就不知道三件最重要的事,表单完全无法工作。

具体来说,form 有三个不可替代、至关重要的作用

作用 1:划定范围 ------ 明确哪些控件是 "一组"

你去银行办理业务,可能同时填了 "开户申请表" 和 "信用卡申请表"------ 这两张单子是分开的,你肯定不会把它们一起交给同一个窗口。

同样,一个网页上可能有多个表单(比如 "登录表单" 和 "注册表单" 分开,"搜索表单" 和 "订阅表单" 分开)------form 标签的第一个作用,就是明确划定范围:哪些输入框、按钮是 "登录表单" 的,哪些是 "注册表单" 的,不会混在一起提交。

反例(没有 form 的后果):如果你不套 form,把登录的用户名、密码和注册的用户名、密码写在一起,点击提交按钮时,浏览器会把所有输入框的内容都提交出去 ------ 后端会收到一堆混乱的数据,完全不知道你是要登录还是要注册,直接报错。

作用 2:指定提交目标 ------ 告诉浏览器 "填完的信息要发送到哪个服务器地址"

你填好的银行申请表单,必须交给指定的窗口 ------ 开户表单交给开户窗口,挂失表单交给挂失窗口,交错了窗口,柜员不会处理你的业务。

同样,你填好的表单数据,必须发送到指定的后端接口 URL------ 注册数据发送到注册接口,登录数据发送到登录接口,发错了地址,后端收不到或者处理不了。

form 标签的第二个作用,就是通过 action 属性,明确告诉浏览器 "填完的信息要发送到哪个 URL"。

反例(没有 form 的后果):如果你不套 form,不写 action,点击提交按钮时,浏览器根本不知道要把数据发到哪里 ------ 要么什么都不发生,要么直接报错 "404 Not Found"。

作用 3:指定提交方式 ------ 告诉浏览器 "怎么传数据"

你递银行申请表单,有两种方式:

  • 方式 1:直接站在窗口外面,大声念出你填的内容 ------ 快,方便,但是旁边的人都能听到,不安全,而且你不能念太长的内容(比如念一篇作文);
  • 方式 2:把表单装在信封里,密封好,递进去 ------ 慢一点,但是安全,旁边的人看不到,而且可以装很长的内容、甚至附件(比如身份证复印件)。

同样,浏览器提交表单数据,也有两种最常用的方式(HTTP 请求方法):

  • 方式 1:GET------ 像 "大声念出来",数据会拼在 URL 后面,可见,不安全,数据量有限制(大约 2KB);
  • 方式 2:POST------ 像 "装在信封里递",数据藏在请求体里,不可见,更安全,没有数据量限制。

form 标签的第三个作用,就是通过 method 属性,明确告诉浏览器 "用哪种方式传数据"。

反例(没有 form 的后果) :如果你不套 form,不写 method,浏览器默认用 GET 方式提交 ------ 如果你提交的是密码,密码会直接显示在 URL 里(比如 xxx.com?username=张三&pwd=123456),旁边的人、甚至历史记录里都能看到,极度不安全!

1.2.3 核心属性

form 的核心价值全靠属性体现,每个属性都对应 "信息传递" 的关键规则

一、action:信息传递的「目的地规则」
核心作用

决定 "填好的表单数据要送到哪个'后端窗口'处理"------ 就像银行里的 "指定投递窗口",没有它,数据就会 "寄丢"。

信息传递逻辑
  • 浏览器拿到 action 的值,就知道 "把数据打包后发送到这个网络地址";
  • 后端在这个地址上 "监听",收到数据后进行处理(如注册、登录、搜索)。
实战避坑
避坑点 错误示例 正确示例 后果
协议缺失 action="www.xxx.com/login" action="https://www.xxx.com/login" 浏览器不知道用 http 还是 https,可能直接报错 "无法连接"
路径写错 action="/api/regist"(少写了 'e') action="/api/register" 后端收不到数据,返回 "404 Not Found",白填了表单
本地开发忘启动后端 action="http://localhost:5000/api/register"(但后端没启动) 先启动后端,再提交表单 浏览器报错 "连接被拒绝",数据根本发不出去

二、method:信息传递的「方式规则」
核心作用

决定 "数据用什么方式送过去"------ 是 "大声念出来(公开)" 还是 "装在信封里(保密)",直接关系到数据安全和传递容量。

信息传递逻辑(GET vs POST 核心对比)
对比项 GET(公开念) POST(密封信)
数据位置 拼在 URL 后面(?username=张三&pwd=123456) 藏在 HTTP "请求体" 里(外面看不到)
安全性 不安全(密码、身份证号会留在 URL、浏览器历史、服务器日志里) 更安全(敏感数据不外露)
容量限制 约 2KB(太长的内容塞不下) 无限制(可以传大段文本、文件)
用途 查询数据(搜索、筛选、看详情) 提交 / 修改数据(注册、登录、下单、传文件)
错误

提交密码、身份证号用 GET :比如 https://xxx.com/login?username=张三&pwd=123456,旁边的人一眼就能看到密码,浏览器历史里也永久留存,极度危险!

正确做法 :所有涉及 "提交重要信息" 的场景,必须用 method="post"。


三、enctype:信息传递的「打包规则」
核心作用

告诉浏览器和后端:"数据是什么格式,该怎么拆包"------ 就像寄快递时选 "普通包裹" 还是 "大件 / 特殊物品包裹",打包错了后端就 "拆不开"。

信息传递逻辑
合法取值 打包方式 适用场景
application/x-www-form-urlencoded(默认) 打成 "键值对" 格式(username=张三&pwd=123456) 普通表单(只有文本、单选框、下拉菜单,没有文件上传)
multipart/form-data 分成 "多个部分" 打包,文件会转成二进制一起发 带文件上传的表单(上传头像、简历、照片)
错误

有文件上传却没改 enctype :比如表单里有 <input type="file">,但 enctype 还是默认值 ------ 文件会 "打包坏了",后端完全收不到文件,白传了!

正确做法 :只要表单里有文件选择框,必须写 enctype="multipart/form-data"。


四、target:信息传递的「反馈展示规则」
核心作用

决定 "后端处理完后,结果在哪里显示给用户看"------ 是 "在当前窗口看回执" 还是 "开个新窗口看回执",影响用户体验。

信息传递逻辑
合法取值 展示位置 适用场景
_self(默认) 当前窗口 注册、登录表单(提交后直接跳转到首页 / 个人中心,不用留着当前页)
_blank 新窗口 搜索表单(在新窗口看搜索结果,不影响当前搜索页;记得加 rel="noopener noreferrer" 防劫持)

五、autocomplete:信息传递的「前置辅助规则」
核心作用

决定 "浏览器要不要帮用户'自动填表单'"------ 就像银行柜台 "记住你的常用信息,下次直接帮你填好",提升用户体验,但敏感场景要关闭。

信息传递逻辑
合法取值 浏览器行为 适用场景
on(默认) 记住之前填过的内容,下次打开表单自动填充 普通注册、搜索表单(方便用户,不用重复填)
off 不记住,每次都要手动填 银行登录页、支付页面、敏感信息表单(防止别人用你的电脑时自动登录)

六、novalidate:信息传递的「前置校验规则」
核心作用

决定 "要不要让浏览器先'检查一遍表单'再提交"------ 就像银行柜台 "先帮你检查有没有漏填必填项,再递进去",新手一般不用关。

信息传递逻辑
  • 写了 novalidate:浏览器跳过自动检查(哪怕没填必填项、邮箱格式不对,也直接提交);
  • 不写(默认):浏览器先检查,有问题直接提示用户,不提交。
注意

如果你还没学 JavaScript 自定义验证,千万不要写这个属性------ 浏览器的自动检查能帮你避免很多低级错误(比如没填密码就提交)。


总结:属性是 form 的 "灵魂"

form 的核心价值,就在于通过这些属性把 "模糊的用户操作" 变成 "明确的信息传递规则":

  • action 定 "目的地",method 定 "方式",enctype 定 "格式"------ 解决 "数据怎么送";
  • target 定 "反馈位置",autocomplete 定 "辅助策略",novalidate 定 "校验策略"------ 解决 "用户体验怎么优化"。

理解了每个属性对应的 "信息传递规则",你就能精准控制表单的每一个环节,既保证数据安全,又提升用户体验。

1.2.4 基础语法(完整的 form 框架)
html 复制代码
<!-- 
  完整的form框架:
  1. action:后端接口地址(必写!)
  2. method:提交方式(必写!重要信息用post,查询用get)
  3. enctype:打包方式(有文件上传必写multipart/form-data,普通表单可省略)
  4. target:结果显示位置(可选,默认_self)
  5. autocomplete:自动填充(可选,默认_on)
  6. novalidate:关闭自动验证(可选,新手暂时不用)
-->
<form 
  action="http://localhost:5000/api/register" 
  method="post" 
  enctype="multipart/form-data"
  target="_self"
  autocomplete="on">
  <!-- 这里放所有表单控件:input/label/select/textarea/button -->
</form>
1.2.5 避坑指南(form 标签的 3 个致命错误,犯了表单就废了)
错误 1:嵌套 form 标签

一个页面可以有多个 form(比如登录表单和注册表单分开,搜索表单和订阅表单分开),但绝对不能嵌套 form 标签 ------ 也就是不能 <form><form></form></form>。

反例(错误写法):

html 复制代码
<!-- 绝对不能这么写!!!浏览器会解析出错,表单提交完全失效!!! -->
<form action="http://localhost:5000/api/register" method="post">
  <input type="text" name="username" placeholder="用户名">
  
  <!-- 错误!嵌套了form!!! -->
  <form action="http://localhost:5000/api/login" method="post">
    <input type="text" name="loginUsername" placeholder="登录用户名">
    <input type="submit" value="登录">
  </form>
  
  <input type="submit" value="注册">
</form>

正例(正确写法):

html 复制代码
<!-- 正确!两个form是并列的,不是嵌套的!!! -->
<form action="http://localhost:5000/api/register" method="post">
  <input type="text" name="username" placeholder="用户名">
  <input type="submit" value="注册">
</form>

<!-- 两个form分开,并列写!!! -->
<form action="http://localhost:5000/api/login" method="post">
  <input type="text" name="loginUsername" placeholder="登录用户名">
  <input type="submit" value="登录">
</form>
错误 2:submit 按钮放在 form 外

<input type="submit"> 或 <button type="submit"> 只有在 form 内才会触发 "提交数据" 的默认行为,放在外面就是普通按钮,点击后什么都不会发生(除非你用 JS 绑定了点击事件,新手暂时不用学 JS)。

反例(错误写法):

复制代码
<form action="http://localhost:5000/api/register" method="post">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="pwd" placeholder="密码">
</form>

<!-- 错误!submit按钮放在form外了!!!点击后什么都不会发生!!! -->
<input type="submit" value="注册">

正例(正确写法):

复制代码
<form action="http://localhost:5000/api/register" method="post">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="pwd" placeholder="密码">
  <!-- 正确!submit按钮放在form内!!! -->
  <input type="submit" value="注册">
</form>
错误 3:提交重要信息时用 GET

提交密码、身份证号、手机号、银行卡号等重要信息时,绝对不能用 GET!!!密码会直接显示在 URL 里,旁边的人能看到,浏览器历史记录里也能看到,极度不安全!!!

反例(错误写法):

复制代码
<!-- 绝对不能这么写!!!提交密码用GET,密码会显示在URL里!!! -->
<form action="http://localhost:5000/api/login" method="get">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="pwd" placeholder="密码">
  <input type="submit" value="登录">
</form>
<!-- 提交后URL会变成:http://localhost:5000/api/login?username=张三&pwd=123456 -->
<!-- 密码123456直接显示在URL里!!!极度不安全!!! -->

正例(正确写法):

复制代码
<!-- 正确!提交重要信息用POST!!!数据藏在请求体里,不显示在URL里!!! -->
<form action="http://localhost:5000/api/login" method="post">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="pwd" placeholder="密码">
  <input type="submit" value="登录">
</form>

1.3 表单控件:input 标签 ------ 申请表单的 "填写项"(变形金刚!)

<input> 是表单中最核心、最灵活、用得最多 的控件,没有之一!它是单标签 (只有开始标签 <input>,没有结束标签 </input>,哪怕你写了浏览器也会忽略,必须养成写单标签的习惯)。

你可以把 <input> 标签完完全全想象成 **"变形金刚"**------ 它通过修改 type 属性,可以变成完全不同的形态:文本框、密码框、单选框、复选框、按钮、文件选择框、邮箱框、电话框、数字框、日期框、隐藏框...... 一个标签满足 90% 的表单输入需求!

1.3.1 通用属性(所有 type 都能用,必学!每个都讲透)

不管 <input> 变成哪种形态,以下通用属性都是控制它的 "核心开关"

下面结合 "银行申请表单" 的生活化比喻,逐个解析通用属性:


通用属性总览

属性名 生活化比喻(银行场景) 核心作用
type 变形金刚的 "形态切换键" 决定 input 变成什么(文本框 / 密码框 / 单选框 / 按钮等)
name 填写项的 "官方名称" 后端识别数据的唯一标识,没有 name 后端收不到数据!
value 填写项的 "实际内容 / 默认值" 文本类:默认显示的内容;按钮类:按钮文字;单选 / 复选:提交给后端的值
required 银行单子上的 "* 必填" 标记 不填不让提交,浏览器自动验证
placeholder 填写项的 "灰色提示文字" 告诉用户 "该怎么填",只是提示,不会提交
disabled 填写项被 "封条贴住" 不能填、不能改、也不会提交
readonly 填写项 "只能看不能改" 不能改,但会提交给后端
checked 银行单子上 "默认勾好的选项" 只对单选框 / 复选框有效,默认选中
autofocus 一进银行 "先让你填这个" 页面加载后自动聚焦到这个输入框
autocomplete 银行 "记住你的信息,下次自动填" 控制浏览器是否自动填充
form 填写项 "属于哪张申请表" 让 input 不在 <form> 标签内也能关联表单

逐个属性深度解析

1. type:形态切换键(变形金刚的核心)

生活化比喻

就像变形金刚的 "形态切换按钮"------ 按一下变成 "文本框",再按一下变成 "密码框",再按变成 "单选框"...... 一个标签满足 90% 输入需求!

超详细说明

type 是 input 的灵魂属性,没有它 input 就是个 "空壳"。合法取值超丰富,新手先掌握这 8 个核心:

type 值 形态 银行场景类比
text(默认) 普通文本框 填 "姓名""地址"
password 密码框(输入内容显示为圆点) 填 "密码""验证码"
radio 单选框(只能选一个) 选 "性别:男 / 女"
checkbox 复选框(可以选多个) 选 "兴趣:读书 / 运动 / 旅游"
submit 提交按钮 银行单子的 "提交申请" 按钮
reset 重置按钮 银行单子的 "重新填写" 按钮
file 文件选择框 上传 "身份证照片""简历"
hidden 隐藏框(页面上看不见) 存 "系统自动生成的用户 ID",不用用户填
实战例子
复制代码
<!-- 普通文本框:填姓名 -->
<input type="text" name="username">

<!-- 密码框:填密码 -->
<input type="password" name="pwd">

<!-- 单选框:选性别(name 必须相同才能互斥!) -->
<input type="radio" name="gender" value="male" id="male">
<label for="male">男</label>
<input type="radio" name="gender" value="female" id="female">
<label for="female">女</label>

<!-- 复选框:选兴趣(name 相同,后端会收到数组) -->
<input type="checkbox" name="hobby" value="read" id="read">
<label for="read">读书</label>
<input type="checkbox" name="hobby" value="sport" id="sport">
<label for="sport">运动</label>

<!-- 提交按钮 -->
<input type="submit" value="提交申请">
必记 + 避坑
  • 单选框 name 不同 :比如两个性别单选框 name 一个叫 gender1 一个叫 gender2------ 结果两个都能选,不是互斥的!
  • 单选框 name 必须相同:只有 name 一样,浏览器才知道 "这几个是一组,只能选一个"。
  • 忘记写 type :默认是 text,想做密码框结果变成普通文本框,密码直接显示!

2. name:填写项的 "官方名称"(后端的 "眼睛")

生活化比喻

就像银行申请表单上的 "字段名"------ 比如 "姓名:____","姓名" 就是 name。银行柜员(后端)拿到单子,靠 "姓名" 这两个字知道 "这个空填的是用户名字"。

超详细说明
  • 核心价值 :name 是后端识别数据的唯一标识 ------ 没有 name,哪怕你填了内容,后端也 "看不见",收不到这个数据!
  • 命名规则 :用英文、数字、下划线,别用中文、空格、特殊字符(比如 user name 不行,user_name 可以)。
  • 单选 / 复选的 name :同一组的单选 / 复选 name 必须相同(比如性别单选框都叫 gender),后端才能收到 "这一组的选择结果"。
实战例子
复制代码
<!-- 正确:有 name,后端能收到 username 的值 -->
<input type="text" name="username" placeholder="请输入姓名">

<!-- 错误:没有 name,后端收不到数据! -->
<input type="text" placeholder="请输入姓名">

<!-- 正确:同一组单选框 name 相同 -->
<input type="radio" name="gender" value="male"> 男
<input type="radio" name="gender" value="female"> 女
错误

忘记写 name :这是新手最常犯的错!比如写了 <input type="text" placeholder="请输入姓名">,提交后后端问 "怎么没有用户名?"------ 因为你没给它 "官方名字",后端不知道这是啥!

所有要提交数据的 input 必须写 name(按钮、隐藏框除外,按钮的 name 一般不用,隐藏框必须写)。


3. value:填写项的 "实际内容"

生活化比喻

分两种情况:

  • 文本类(text/password):银行单子上 "预填的内容"------ 比如银行已经帮你印好的 "当前日期",你可以改;
  • 单选 / 复选 / 按钮 :银行单子上 "选项的实际值"------ 比如 "性别:男(value=male)",用户看到的是 "男",但提交给后端的是 male;
  • 按钮类(submit/reset):按钮上显示的文字 ------ 比如 "提交申请"。
超详细说明
input 类型 value 的作用 示例
text/password/email 等文本类 默认显示的内容(用户可以改) <input type="text" name="username" value="张三">(打开页面就显示 "张三")
radio/checkbox 提交给后端的实际值(必须写!) <input type="radio" name="gender" value="male">(用户选 "男",后端收到 gender=male)
submit/reset/button 按钮上显示的文字 <input type="submit" value="提交申请">(按钮上显示 "提交申请")
hidden(隐藏框) 隐藏的实际值(必须写!) <input type="hidden" name="user_id" value="12345">(页面看不见,后端收到 user_id=12345)
实战例子
复制代码
<!-- 文本框:默认显示"张三" -->
<input type="text" name="username" value="张三">

<!-- 单选框:用户看到"男",后端收到"male" -->
<input type="radio" name="gender" value="male" id="male">
<label for="male">男</label>

<!-- 提交按钮:按钮上显示"提交申请" -->
<input type="submit" value="提交申请">

<!-- 隐藏框:存用户ID,页面看不见,后端能收到 -->
<input type="hidden" name="user_id" value="1001">
必记 + 避坑
  • 单选 / 复选忘记写 value :比如 <input type="radio" name="gender"> 男------ 用户选了,后端收到的是 gender=on(默认值),不是 "男"!
  • 单选 / 复选必须写 value:明确告诉后端 "用户选的是什么"。
  • 把 placeholder 当 value 用 :比如 <input type="text" name="username" placeholder="张三">------placeholder 只是提示,不会提交!后端收不到 "张三"!

4. required:必填项标记(*)

生活化比喻

就像银行申请表单上的 "* 必填"------ 比如 "姓名:____ *",不填这个空,银行不让你提交单子!

超详细说明
  • 布尔属性 :直接写属性名即可,不用赋值(写 required 或 required="required" 都可以,新手直接写 required 更简单);
  • 作用 :浏览器自动验证 ------ 如果这个 input 是空的,点击提交按钮时,浏览器会弹出提示 "请填写此字段",不会提交表单;
  • 适用类型:几乎所有输入类 input(text/password/radio/email 等),按钮、隐藏框除外。
实战例子
复制代码
<!-- 姓名:必填,不填不让提交 -->
<input type="text" name="username" required>

<!-- 密码:必填 -->
<input type="password" name="pwd" required>

<!-- 性别:单选框,给其中一个加 required 即可(一组里选一个就行) -->
<input type="radio" name="gender" value="male" required id="male">
<label for="male">男</label>
<input type="radio" name="gender" value="female" id="female">
<label for="female">女</label>
必记 + 避坑
  • 给 required 赋值成 false :比如 <input type="text" name="username" required="false">------ 没用!布尔属性只要写了属性名就生效,不管值是什么!
  • 直接写 required 即可:不用赋值,简单清晰。
  • 只靠 required 验证:浏览器的验证可以被绕过(比如用户改 HTML 代码),后端必须再验证一次!

5. placeholder:灰色提示文字

生活化比喻

就像银行申请表单上的 "填写说明"------ 比如 "姓名:____(请输入真实姓名)",灰色的小字,告诉你 "该怎么填",但不是实际内容。

超详细说明
  • 作用:提升用户体验,告诉用户 "这个空该填什么";
  • 特点 :
    1. 只是视觉提示,不会提交给后端;
    2. 用户一输入内容,提示文字就会消失;
    3. 颜色是灰色的(浏览器默认样式,可通过 CSS 改)。
实战例子
复制代码
<!-- 文本框:提示"请输入真实姓名" -->
<input type="text" name="username" placeholder="请输入真实姓名">

<!-- 密码框:提示"请输入6-16位密码" -->
<input type="password" name="pwd" placeholder="请输入6-16位密码">

<!-- 邮箱框:提示"请输入常用邮箱" -->
<input type="email" name="email" placeholder="请输入常用邮箱">
必记 + 避坑
  • 把 placeholder 当默认值用 :比如 <input type="text" name="username" placeholder="张三">------ 用户没输入,提交后后端收不到 "张三"!
  • 默认值用 value,提示用 placeholder:分清楚,别搞混!
  • placeholder 写太长:比如写 "请输入您的真实姓名,必须是中文,不能有数字和特殊字符"------ 太长会被截断,用户看不全!
  • placeholder 简洁明了:一句话说清楚 "该填什么"。

6. disabled:被封条贴住的填写项

生活化比喻

就像银行申请表单上 "系统自动生成,请勿填写" 的空 ------ 被封条贴住了,你不能填、不能改,甚至连选都选不中,而且银行(后端)也不会收这个空的内容。

超详细说明
  • 布尔属性 :直接写 disabled 即可;
  • 特点 :
    1. 不能编辑、不能选中、不能点击;
    2. 样式会变灰(浏览器默认);
    3. 最重要:不会提交给后端!(哪怕有 value 也没用)。
实战例子
复制代码
<!-- 文本框:禁用,不能改,也不会提交 -->
<input type="text" name="user_id" value="1001" disabled>

<!-- 单选框:禁用,选不中 -->
<input type="radio" name="gender" value="male" disabled> 男

<!-- 提交按钮:禁用,点击没反应 -->
<input type="submit" value="提交申请" disabled>
必记 + 避坑
  • 想提交数据但用了 disabled :比如 <input type="text" name="user_id" value="1001" disabled>------ 后端收不到 user_id!
  • 想提交但不让改,用 readonly(看下面),别用 disabled!
  • 给 disabled 赋值成 false:和 required 一样,只要写了属性名就生效,不管值是什么!

7. readonly:只能看不能改的填写项

生活化比喻

就像银行申请表单上 "银行预填的你的姓名"------ 已经印好了,你不能改,但这是单子的一部分,银行(后端)会收这个内容。

超详细说明
  • 布尔属性 :直接写 readonly 即可;

  • 和 disabled 的核心区别 :

    对比项 disabled readonly
    能不能改 不能 不能
    能不能选中 不能 能(可以复制内容)
    会不会提交 不会 会!
    适用类型 几乎所有 仅文本类(text/password/email 等),单选 / 复选 / 按钮无效
实战例子
复制代码
<!-- 文本框:只读,不能改,但会提交 user_id=1001 -->
<input type="text" name="user_id" value="1001" readonly>

<!-- 姓名:只读,银行预填的,不能改 -->
<input type="text" name="username" value="张三" readonly>
必记 + 避坑
  • 给单选 / 复选用 readonly :没用!readonly 只对文本类 input 有效,单选 / 复选想 "默认选中且不能改",用 checked + disabled(但 disabled 不会提交,想提交的话用 hidden 存值)。
  • readonly 只用于文本类:别用错地方。
  • 搞混 disabled 和 readonly :记住 ------想提交用 readonly,不想提交用 disabled!

8. checked:默认选中的选项

生活化比喻

就像银行申请表单上 "默认勾好的'同意服务条款'"------ 你一拿到单子,这个选项已经勾好了,不用你手动勾。

超详细说明
  • 布尔属性 :直接写 checked 即可;
  • 仅对两种类型有效 :radio(单选框)和 checkbox(复选框);
  • 单选框 :同一组里只能有一个 checked(不然会冲突,最后一个生效);
  • 复选框 :可以有多个 checked(默认选中多个)。
实战例子
复制代码
<!-- 单选框:默认选中"男" -->
<input type="radio" name="gender" value="male" checked id="male">
<label for="male">男</label>
<input type="radio" name="gender" value="female" id="female">
<label for="female">女</label>

<!-- 复选框:默认选中"读书"和"运动" -->
<input type="checkbox" name="hobby" value="read" checked id="read">
<label for="read">读书</label>
<input type="checkbox" name="hobby" value="sport" checked id="sport">
<label for="sport">运动</label>
<input type="checkbox" name="hobby" value="travel" id="travel">
<label for="travel">旅游</label>

<!-- 同意条款:默认勾好 -->
<input type="checkbox" name="agree" value="yes" checked id="agree">
<label for="agree">我同意服务条款</label>
必记 + 避坑
  • 给文本框用 checked:没用!checked 只对单选 / 复选有效!
  • checked 仅用于 radio 和 checkbox。
  • 同一组单选框多个 checked:比如两个性别单选框都写了 checked------ 结果只有最后一个生效,前面的被覆盖!
  • 同一组单选框最多一个 checked。

9. autofocus:自动聚焦的填写项

生活化比喻

就像你一进银行,柜员直接把笔递到 "姓名" 那一行 ------ 你不用自己点,直接就能填。

超详细说明
  • 布尔属性 :直接写 autofocus 即可;
  • 作用 :页面加载完成后,自动把光标聚焦到这个 input,用户不用手动点击,直接就能输入;
  • 注意 :一个页面最好只有一个 autofocus------ 如果有多个,只有最后一个生效。
实战例子
复制代码
<!-- 登录页:自动聚焦到用户名输入框 -->
<input type="text" name="username" placeholder="请输入用户名" autofocus>

<!-- 搜索页:自动聚焦到搜索框 -->
<input type="text" name="wd" placeholder="请输入搜索关键词" autofocus>
必记 + 避坑
  • 一个页面多个 autofocus:比如登录页用户名和密码都写了 autofocus------ 结果只有密码框聚焦,用户名框没用!
  • 一个页面最多一个 autofocus。
  • 给隐藏框、按钮用 autofocus:没用!聚焦了也看不见 / 没用。

10. autocomplete:浏览器自动填充

生活化比喻

就像银行记住了你的账号,下次你再来填单子,银行直接帮你把账号填好 ------ 不用你手动输。

超详细说明
  • 作用:控制浏览器是否 "记住并自动填充" 这个 input 的内容;

  • 合法取值 (新手重点掌握这几个):

    值 作用 适用场景
    on(默认) 开启自动填充 普通表单(用户名、地址)
    off 关闭自动填充 敏感表单(银行登录、支付密码)
    username 自动填充用户名 登录页的用户名框
    current-password 自动填充当前密码 登录页的密码框
    new-password 自动填充新密码(建议强密码) 注册页 / 修改密码页的新密码框
实战例子
复制代码
<!-- 登录页:用户名自动填充,密码自动填充当前密码 -->
<input type="text" name="username" autocomplete="username">
<input type="password" name="pwd" autocomplete="current-password">

<!-- 银行登录页:关闭自动填充,安全 -->
<input type="text" name="bank_account" autocomplete="off">
<input type="password" name="bank_pwd" autocomplete="off">

<!-- 注册页:新密码建议强密码 -->
<input type="password" name="new_pwd" autocomplete="new-password">
必记 + 避坑
  • 银行 / 支付页面用 autocomplete="on":不安全!别人用你的电脑时,浏览器会自动填充你的账号密码!
  • 敏感页面用 autocomplete="off"。
  • 值写错 :比如 autocomplete="密码"------ 要用英文标准值,浏览器才认识!

11. form:指定属于哪个表单

生活化比喻

就像你填的 "附加信息表",虽然和 "主申请表" 分开,但银行知道 "这张附加表属于主申请表"------ 一起提交。

超详细说明
  • 作用 :让 input 不在 <form> 标签内,也能关联到某个表单;
  • 用法 :给 <form> 加 id,然后给 input 加 form="表单的id";
  • 适用场景:input 位置和表单离得远,或者布局需要分开写。
实战例子
复制代码
<!-- 表单:加 id="loginForm" -->
<form id="loginForm" action="/api/login" method="post">
  <input type="text" name="username" placeholder="请输入用户名">
</form>

<!-- 密码框:不在 form 内,但通过 form="loginForm" 关联 -->
<input type="password" name="pwd" placeholder="请输入密码" form="loginForm">

<!-- 提交按钮:不在 form 内,也能提交表单 -->
<input type="submit" value="登录" form="loginForm">
必记 + 避坑
  • form 的值写错 :比如 <form id="login">,但 input 写 form="loginForm"------ 关联不上!
  • form 的值必须和表单的 id 完全一致(区分大小写)。
  • 没必要时用 form :input 本来就在 form 内,不用多写 form 属性!

总结:通用属性是 input 的 "基本功"

input 的通用属性是所有形态的基础 ------ 不管变成文本框还是密码框,都要靠 name 让后端识别,靠 value 传值,靠 required 做必填验证。

1.3.2 不同 type 类型

type 属性是 input 的 "形态开关",不同 type 对应不同的输入场景,下面我逐个讲透,包括核心定义 、适用场景 、核心属性 、实战例子 、新手避坑 、最佳实践。

(1)type="text":普通文本框(最常用!)
  • 核心定义:用于输入普通文本(可见),是 input 的默认 type(不写 type 就是 text);
  • 适用场景:输入用户名、昵称、地址、搜索关键词、备注等普通文本;
  • 核心属性:name(必写)、placeholder(建议写)、maxlength/minlength(建议写)、id(配合 label)、disabled/readonly(按需)、required(按需);
  • 实战例子:
html 复制代码
<!-- 用户名输入框:name必写,placeholder提示,maxlength/minlength限制,required必填,配合label -->
<label for="username">用户名:</label>
<input 
  type="text" 
  id="username" 
  name="username" 
  placeholder="请输入用户名(2-20位)" 
  minlength="2" 
  maxlength="20" 
  required>
  • 避坑 :
    1. 忘记写 name!!!后端拿不到值!!!
    2. 用 value 代替 placeholder!!!value 是默认值,会被提交,placeholder 是提示文字,不会被提交!!!
  • 最佳实践 :
    1. 所有 text 输入框都写 placeholder,提升用户体验;
    2. 配合 maxlength/minlength 一起用,限制输入长度;
    3. 配合 label 一起用,点击文字输入框获得焦点。

(2)type="password":密码框
  • 核心定义:用于输入密码,输入内容会被隐藏(显示为●或 *,不同浏览器显示的符号可能不同),只是 "视觉隐藏",不是 "加密"------ 如果网站没有 HTTPS 加密,数据传输过程中仍可能被窃取;
  • 适用场景:输入密码、确认密码、支付密码等敏感信息;
  • 核心属性:name(必写)、placeholder(建议写)、maxlength/minlength(建议写)、id(配合 label)、disabled/readonly(按需)、required(按需);
  • 实战例子:
html 复制代码
<!-- 密码输入框:name必写,placeholder提示,maxlength/minlength限制,required必填,配合label -->
<label for="pwd">密码:</label>
<input 
  type="password" 
  id="pwd" 
  name="pwd" 
  placeholder="请输入6-18位密码" 
  minlength="6" 
  maxlength="18" 
  required>

<!-- 确认密码输入框 -->
<label for="repwd">确认密码:</label>
<input 
  type="password" 
  id="repwd" 
  name="repwd" 
  placeholder="请再次输入密码" 
  minlength="6" 
  maxlength="18" 
  required>
  • 避坑 :
    1. 忘记写 name!!!后端拿不到值!!!
    2. 提交密码时用 GET!!!密码会显示在 URL 里!!!极度不安全!!!
    3. 以为 password 是 "加密" 的!!!只是视觉隐藏,传输过程中仍需 HTTPS 加密!!!
  • 最佳实践 :
    1. 所有密码输入框都写 placeholder;
    2. 配合 maxlength/minlength 一起用;
    3. 配合 label 一起用;
    4. 提交密码时必须用 POST!!!
    5. 网站必须用 HTTPS 加密!!!

(3)type="radio":单选框(互斥选择!!!)
  • 核心定义:用于 "互斥选择" 场景 ------ 同一组单选框,只能选一个,选了一个就会自动取消另一个的选中状态;
  • 适用场景:选择性别、学历、支付方式、是否同意协议(二选一)等;
  • 核心规则 :
    1. 同一组单选框必须设置相同的 name!!!------ 只有 name 相同,浏览器才知道它们是 "一组的",才能实现互斥选择;
    2. 每个单选框必须设置 value!!!------ 否则后端拿到的是 "on"(无意义);
    3. 同一组单选框,最多只能有一个 checked!!!------ 如果写了多个,只有最后一个生效;
    4. 配合 label 一起用!!!------ 点击文字也能选中,提升用户体验;
  • 核心属性:name(必写,同一组相同)、value(必写)、checked(按需,默认选中)、id(配合 label)、disabled(按需)、required(按需,给其中一个写即可);
  • 实战例子:
html 复制代码
<!-- 性别选择:同一组name都是sex,互斥选择,每个都有value,默认选中男,配合label,required必填 -->
<label>性别:</label>
<input type="radio" id="male" name="sex" value="male" checked required>
<label for="male">男</label>
<input type="radio" id="female" name="sex" value="female">
<label for="female">女</label>
<input type="radio" id="other" name="sex" value="other">
<label for="other">其他</label>

<!-- 学历选择:同一组name都是education -->
<label>学历:</label>
<input type="radio" id="highschool" name="education" value="highschool">
<label for="highschool">高中</label>
<input type="radio" id="college" name="education" value="college">
<label for="college">大专</label>
<input type="radio" id="undergraduate" name="education" value="undergraduate" checked>
<label for="undergraduate">本科</label>
<input type="radio" id="master" name="education" value="master">
<label for="master">硕士</label>
  • 避坑 :
    1. 同一组单选框的 name 不同!!!能选多个,完全失去了单选框的意义!!!
    2. 没写 value!!!后端拿到的是 "on",完全不知道用户选了什么!!!
    3. 没配合 label!!!用户必须精准点击小圆圈,体验差!!!
  • 最佳实践 :
    1. 同一组单选框必须设置相同的 name!!!
    2. 每个单选框必须设置 value!!!
    3. 配合 label 一起用!!!
    4. 同一组单选框,最多只能有一个 checked!!!

(4)type="checkbox":复选框(多选!!!)
  • 核心定义:用于 "多选" 场景 ------ 同一组复选框,可以选多个、选一个、一个都不选;
  • 适用场景:选择爱好、选择商品规格、选择兴趣标签、同意多个协议等;
  • 核心规则 :
    1. 同一组复选框建议设置相同的 name!!!------name 相同,后端会把选中的值接收为 "数组"(比如 hobby: ' 吃饭 ',' 打游戏 '),方便处理;
    2. 每个复选框必须设置 value!!!------ 否则后端拿到的是 "on"(无意义);
    3. 同一组复选框,可以有多个 checked!!!------ 多个选项默认选中;
    4. 配合 label 一起用!!!------ 点击文字也能选中,提升用户体验;
  • 核心属性:name(建议写,同一组相同)、value(必写)、checked(按需,默认选中)、id(配合 label)、disabled(按需)、required(按需,必须选中至少一个);
  • 实战例子:
html 复制代码
<!-- 爱好选择:同一组name都是hobby,后端接收为数组,每个都有value,默认选中吃饭和打游戏,配合label -->
<label>爱好:</label>
<input type="checkbox" id="eat" name="hobby" value="eat" checked>
<label for="eat">吃饭</label>
<input type="checkbox" id="sleep" name="hobby" value="sleep">
<label for="sleep">睡觉</label>
<input type="checkbox" id="game" name="hobby" value="game" checked>
<label for="game">打游戏</label>
<input type="checkbox" id="read" name="hobby" value="read">
<label for="read">看书</label>

<!-- 协议勾选:必须选中,配合label,required必填 -->
<input type="checkbox" id="agree" name="agree" value="yes" required>
<label for="agree">我已阅读并同意《用户协议》和《隐私政策》</label>
  • 避坑 :
    1. 没写 value!!!后端拿到的是 "on",完全不知道用户选了什么!!!
    2. 没配合 label!!!用户必须精准点击小方框,体验差!!!
  • 最佳实践 :
    1. 同一组复选框建议设置相同的 name!!!
    2. 每个复选框必须设置 value!!!
    3. 配合 label 一起用!!!

(5)type="button":普通按钮
  • 核心定义:无默认行为的按钮 ------ 点击后什么都不会发生(除非你用 JS 绑定了点击事件),必须配合 JavaScript 使用;

  • 适用场景:点击弹出弹窗、点击清空某个输入框、点击切换内容等(需要配合 JS,新手暂时不用学 JS,先知道格式即可);

  • 核心属性:value(按钮上显示的文字,建议写)、id(配合 JS)、disabled(按需);

  • 实战例子:

  • 避坑 :

    1. 放在 form 内,以为会触发表单提交!!!type="button" 不会触发表单提交,只有 type="submit" 才会!!!
  • 最佳实践 :

    1. 建议写 value,否则按钮上显示默认的 "Button"(英文浏览器显示 "Button");
    2. 配合 JS 使用,新手暂时不用学 JS,先记住格式即可。

(6)type="submit":提交按钮(触发表单提交!!!)
  • 核心定义:触发表单提交的按钮 ------ 点击后,form 内所有带 name 的控件值会被传递到 action 指定的 URL;

  • 适用场景:提交注册表单、提交登录表单、提交搜索表单、提交订单等;

  • 核心规则 :

    1. 必须放在 form 内!!!------ 放在 form 外就是普通按钮,点击后什么都不会发生;
    2. 一个 form 内可以有多个 submit 按钮!!!------ 如果有多个,需要给每个 submit 写不同的 name 和 value,后端可以区分是哪个按钮提交的(新手很少用);
  • 核心属性:value(按钮上显示的文字,建议写)、name(按需,多个按钮时用)、disabled(按需);

  • 实战例子:

  • 避坑 :

    1. 放在 form 外!!!点击后什么都不会发生!!!
  • 最佳实践 :

    1. 必须放在 form 内!!!
    2. 建议写 value,否则按钮上显示默认的 "提交"(英文浏览器显示 "Submit Query")。

(7)type="reset":重置按钮(一键清空表单!!!)
  • 核心定义:一键清空 form 内所有控件的输入内容,恢复到初始状态 ------ 文本框 / 密码框的内容清空,单选框 / 复选框恢复到默认选中状态,下拉菜单恢复到默认选中选项;

  • 适用场景:清空注册表单、清空登录表单、清空搜索表单等;

  • 核心规则 :

    1. 必须放在 form 内!!!------ 放在 form 外就是普通按钮,点击后什么都不会发生;
    2. 会清空当前 form 内的所有控件!!!------ 不会影响其他 form;
  • 核心属性:value(按钮上显示的文字,建议写)、disabled(按需);

  • 实战例子:

  • 避坑 :

    1. 放在 form 外!!!点击后什么都不会发生!!!
    2. 以为只会清空某个输入框!!!会清空当前 form 内的所有控件!!!
  • 最佳实践 :

    1. 必须放在 form 内!!!
    2. 建议写 value,否则按钮上显示默认的 "重置"(英文浏览器显示 "Reset");
    3. 重要表单(比如注册表单)建议加 reset 按钮,提升用户体验。

(8)type="file":文件选择框(上传文件!!!)
  • 核心定义:用于让用户选择本地文件(如上传头像、身份证、简历、照片、视频);

  • 核心规则 :

    1. 必须配合 form 的 enctype="multipart/form-data"!!!------ 否则文件传不出去,后端打不开;
    2. 必须配合 form 的 method="post"!!!------GET 方式数据量有限制,传不了文件;
  • 适用场景:上传头像、上传身份证、上传简历、上传照片、上传视频等;

  • 核心属性 :

    • name(必写);
    • accept(指定可选择的文件类型,建议写,提升用户体验,防止用户上传错误类型的文件);
    • multiple(允许选择多个文件,按需,省略则只能选一个);
    • id(配合 label);
    • disabled(按需);
    • required(按需,必须选文件);
  • accept 属性的常用取值(新手必掌握!) :

    • image/*:只允许选择所有图片(jpg/png/gif 等);
    • image/jpeg,image/png:只允许选择 JPG 和 PNG 图片;
    • .pdf:只允许选择 PDF 文件;
    • .docx,.doc:只允许选择 Word 文件;
    • .xlsx,.xls:只允许选择 Excel 文件;
  • 实战例子:

    复制代码
    <!-- 上传简历:允许PDF和Word,可多选,配合label -->
    <label for="resume">上传简历:</label>
    <input type="file" id="resume" name="resume" accept=".pdf,.docx,.doc" multiple>
    
    <input type="submit" value="提交文件">
  • 避坑 :

    1. 没改 form 的 enctype!!!文件传不出去,后端打不开!!!
    2. 没改 form 的 method!!!用 GET 传不了文件!!!
    3. 没写 accept!!!用户可能上传错误类型的文件!!!
  • 最佳实践 :

    1. 必须配合 form 的 enctype="multipart/form-data" 和 method="post"!!!
    2. 建议写 accept,指定可选择的文件类型,提升用户体验,防止用户上传错误类型的文件!!!
    3. 配合 label 一起用!!!

其他常用 type(不算超纲,实际开发高频!!!)

除了上面的 8 个 type,这几个 type 在实际开发中也非常常用,能提升用户体验和开发效率,新手也必须掌握:

(9)type="email":邮箱输入框
  • 核心定义:专门用于输入邮箱,浏览器会自动验证格式(必须包含 @,且 @后面有内容);

  • 适用场景:输入邮箱地址;

  • 核心属性:name(必写)、placeholder(建议写)、id(配合 label)、disabled/readonly(按需)、required(按需);

  • 实战例子:


  • 新手避坑 :

    1. 浏览器的自动验证只是 "格式验证"(必须包含 @),不是 "真实性验证"(不能验证这个邮箱是否真的存在);
  • 最佳实践 :

    1. 输入邮箱时用 type="email",不要用 type="text";
    2. 浏览器会自动验证格式,体验更好;
    3. 移动端会弹出 "带 @的键盘",更友好。

(10)type="tel":电话输入框
  • 核心定义:专门用于输入电话号码,移动端会弹出 "数字键盘"(不是全键盘),更友好;

  • 适用场景:输入手机号、座机号;

  • 核心属性:name(必写)、placeholder(建议写)、maxlength(建议写,比如手机号 11 位)、id(配合 label)、disabled/readonly(按需)、required(按需);

  • 实战例子:


  • 最佳实践 :

    1. 输入手机号 / 座机号时用 type="tel",不要用 type="text";
    2. 移动端弹出数字键盘,用户体验更好;
    3. 配合 maxlength 一起用,限制输入长度。

(11)type="number":数字输入框
  • 核心定义:专门用于输入数字,只能输数字(不能输字母、汉字),带上下箭头(点击可以增加 / 减少数字),移动端弹出数字键盘;

  • 适用场景:输入年龄、数量、价格、身份证号(虽然身份证号有 X,但 X 很少,新手可以用 text);

  • 核心属性 :

    • name(必写);
    • placeholder(建议写);
    • min(最小值,建议写);
    • max(最大值,建议写);
    • step(步长,点击上下箭头时增加 / 减少的数值,默认 1,新手了解即可);
    • id(配合 label);
    • disabled/readonly(按需);
    • required(按需);
  • 实战例子:



  • 最佳实践 :

    1. 输入数字时用 type="number",不要用 type="text";
    2. 只能输数字,防止用户输入错误内容;
    3. 配合 min/max 一起用,限制输入范围;
    4. 移动端弹出数字键盘,用户体验更好。

(12)type="date":日期选择框
  • 核心定义:专门用于选择日期,浏览器会弹出 "日历控件"(不用自己写日历组件!!!省了很多事!!!);

  • 适用场景:选择出生日期、选择预约日期、选择订单日期等;

  • 核心属性:name(必写)、min(最小日期,建议写)、max(最大日期,建议写)、id(配合 label)、disabled/readonly(按需)、required(按需);

  • 实战例子:


  • 最佳实践 :

    1. 选择日期时用 type="date",不要用 type="text";
    2. 浏览器弹出日历控件,不用自己写,省了很多事!!!
    3. 配合 min/max 一起用,限制选择范围;
    4. 不同浏览器的日历控件样式可能不同,但功能一样。

(13)type="hidden":隐藏输入框
  • 核心定义 :隐藏的输入框 ------ 用户看不到,页面上不显示,但提交表单时,这个控件的值会被传递给后端!!!

  • 适用场景:传递后端需要但用户不需要看到的值,比如用户类型、页面来源、商品 ID、当前时间等;

  • 核心属性:name(必写)、value(必写!!!);

  • 实战例子:

  • 新手避坑 :

    1. 没写 value!!!后端拿不到值!!!
    2. 以为用户完全看不到!!!用户可以通过浏览器的 "开发者工具"(F12)看到隐藏输入框的 name 和 value,所以不要放敏感信息(比如密码)!!!
  • 最佳实践 :

    1. 必须写 name 和 value!!!
    2. 不要放敏感信息(比如密码)!!!
    3. 用于传递后端需要但用户不需要看到的值。

1.4 label 标签 ------ 提升表单体验的 "辅助神器"

前面我们讲完了 input 的所有核心类型,你在实际使用中一定遇到过这种糟心情况:想选性别 "男",必须精准点击那个直径不到 10px 的圆形单选框,点旁边的 "男" 字完全没反应;尤其是在手机上,手指粗,反复点好几次都选不中,体验极差!

<label>标签就是专门解决这个问题的 "体验优化神器"------ 它能让 "文字描述" 和 "表单控件" 实现深度绑定 ,点击文字就和点击控件本身的效果完全一致:点击 "男" 字就能选中对应的单选框,点击 "我同意协议" 就能勾选对应的复选框,点击 "用户名" 三个字就能让输入框自动获得焦点(光标跳进去),极大提升用户体验,尤其是移动端!

除此之外,它还有一个核心作用:提升无障碍访问性 ------ 屏幕阅读器(给视障用户使用的工具)会优先读取 label 里的文字,告诉用户这个控件是用来做什么的,是前端开发的强制最佳实践,所有表单控件都必须配合 label 使用!

1.4.1 核心作用
  1. 提升点击体验:扩大控件的可点击范围,点击文字就能操作控件,不用精准点击小圆圈 / 小方框;
  2. 提升无障碍访问性:屏幕阅读器会读取 label 的文字,告诉视障用户这个控件的用途,符合无障碍标准;
  3. 代码语义化:明确了 "文字" 和 "控件" 的对应关系,代码可读性更强,后期维护更方便。
1.4.2 两种绑定方式(全讲透,优缺点、适用场景全覆盖)

<label>是闭合标签 (必须有开始标签<label>和结束标签</label>),有两种完全合规的绑定方式,都能实现 "点击文字操作控件" 的效果,新手必须全部掌握。

方式 1:for + id 关联(官方推荐!)

这是 W3C 官方推荐的标准写法,也是实际开发中用得最多的写法,没有任何使用限制,结构清晰,可复用性强。

  • 核心规则(必须严格遵守!) :label 标签的for属性值,必须和对应控件的id属性值完全一致(包括大小写,HTML 里虽然不区分大小写,但建议统一小写,养成规范习惯),且这个 id 在整个 HTML 页面内必须是唯一的,不能和其他元素的 id 重复。
  • 原理 :浏览器通过for和id的匹配,建立了 label 和控件的一一对应关系,点击 label 时,浏览器会自动触发对应控件的点击 / 聚焦行为。
  • 优点 :
    1. 结构完全分离,label 和控件可以放在页面的不同位置(比如 label 在左边,控件在右边,甚至在不同的 div 里),布局不受限制;
    2. 代码可读性极强,一眼就能看出 label 和哪个控件绑定;
    3. 一个控件可以被多个 label 绑定(极少数场景会用到);
    4. 完全符合 W3C 标准,兼容性拉满,所有浏览器都支持。
  • 缺点:需要给控件写 id,多写一点点代码(完全可以忽略,带来的收益远大于这点代码量)。

实战例子:

复制代码
<!-- 1. 绑定单选框:点击"男"字就能选中单选框 -->
<label for="male">男</label>
<input type="radio" id="male" name="sex" value="male">

<!-- 2. 绑定复选框:点击"我同意协议"就能勾选复选框 -->
<input type="checkbox" id="agree" name="agree" value="yes" required>
<label for="agree">我已阅读并同意《用户协议》和《隐私政策》</label>

<!-- 3. 绑定文本输入框:点击"用户名"三个字,输入框自动获得焦点 -->
<label for="username">用户名:</label>
<input type="text" id="username" name="username" placeholder="请输入用户名">

<!-- 4. 绑定密码框:点击"密码"三个字,密码框自动获得焦点 -->
<label for="pwd">密码:</label>
<input type="password" id="pwd" name="pwd" placeholder="请输入密码">

<!-- 5. 绑定文件选择框:点击"上传头像"四个字,就能弹出文件选择窗口 -->
<label for="avatar">上传头像:</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
方式 2:嵌套关联(控件直接放在 label 内部,无需 for 和 id)

这是一种简化写法,直接把表单控件放在 label 标签的内部,无需写for和id,浏览器会自动把 label 和内部的控件绑定,实现点击文字操作控件的效果。

  • 核心规则 :把表单控件直接放在<label>和</label>之间,文字和控件可以任意排列(控件在前,文字在后;或者文字在前,控件在后,都可以)。
  • 原理:浏览器会自动识别 label 内部的表单控件,建立默认的绑定关系,点击 label 的任意区域(包括文字),都会触发内部控件的行为。
  • 优点 :
    1. 代码简洁,不用写 for 和 id,少写代码;
    2. 不用考虑 id 重复的问题,不会出现绑定错误;
    3. 兼容性拉满,所有浏览器都支持。
  • 缺点 :
    1. label 和控件必须放在一起,布局受限制,无法实现 "label 在左、控件在右,中间隔了其他元素" 的布局;
    2. 一个 label 里只能放一个主控件(放多个的话,只会绑定第一个);
    3. 代码可读性不如 for+id 的写法,复杂表单里很难一眼看出绑定关系。

实战例子:

复制代码
<!-- 1. 嵌套单选框:控件在前,文字在后 -->
<label>
  <input type="radio" name="sex" value="female"> 女
</label>

<!-- 2. 嵌套复选框:文字在前,控件在后 -->
<label>
  我已阅读并同意协议 <input type="checkbox" name="agree" value="yes">
</label>

<!-- 3. 嵌套文本输入框 -->
<label>
  用户名:<input type="text" name="username" placeholder="请输入用户名">
</label>
1.4.3 核心属性(只有 1 个核心属性,新手必记)
属性名 作用 合法取值 新手必记细节 & 避坑
for 建立 label 和控件的绑定关系,值必须等于对应控件的 id 字符串(必须和控件的 id 完全一致) 1. 只有方式 1(for+id)需要写这个属性,方式 2(嵌套)不需要;2. 值必须和控件的 id完全一致,包括大小写,少一个字母都不行,否则绑定失效;3. 对应的 id 在页面内必须唯一,否则会绑定到第一个匹配 id 的控件上;4. 一个 for 只能绑定一个控件,一个控件可以被多个 label 的 for 绑定。
disabled 禁用 label(极少用) 布尔属性,直接写属性名即可 禁用后,点击 label 不会触发控件的行为,几乎不用,直接禁用控件即可。
1.4.4 避坑指南
  1. for 和 id 的值不一致:比如 label 的 for="man",控件的 id="male",少了一个字母,绑定完全失效,点击文字没反应;
  2. id 重复:页面内有两个相同的 id,比如两个 input 的 id 都是 male,label 只会绑定第一个,第二个完全失效;
  3. 一个 label 里放多个控件:嵌套写法里,一个 label 里放了两个单选框,只会绑定第一个,第二个点击文字没反应;
  4. 只给文字加 label,不给控件加 id :写了<label for="male">男</label>,但 input 没写 id="male",绑定完全失效;
  5. 用 div/p 标签代替 label:很多新手用 div 包裹文字和控件,以为能实现点击效果,完全不行!只有 label 标签有这个原生绑定效果,div 没有!
1.4.5 最佳实践
  1. 所有表单控件必须配合 label 使用:不管是输入框、单选框、复选框、文件选择框,都必须加 label,这是前端开发的强制规范,提升用户体验和无障碍性;
  2. 优先使用 for+id 的写法:除了极简单的场景,都用 for+id 的标准写法,结构清晰,布局灵活,可读性强,后期维护方便;
  3. id 和 for 的值用有意义的英文 :不要用id="a1"、for="a1"这种无意义的名字,要用id="username"、for="username"这种有意义的名字,代码可读性更强;
  4. 不要在 label 里放块级元素:label 是行内元素,里面不要放 div、p、h1 等块级元素,会导致浏览器解析出错,布局混乱;
  5. 必填项的提示放在 label 里 :比如<label for="username">用户名:<span style="color: red;">*</span></label>,明确告诉用户这是必填项,体验更好。

1.5 下拉菜单:select & option 标签 ------ 有序选择的 "下拉列表"

当你的可选选项超过 3 个(比如年份、省份、城市、职业、商品分类),用单选框会占满整个页面,显得非常臃肿,用户体验极差;这时候<select> + <option> 组成的下拉菜单就是最佳解决方案 ------ 它默认只显示一行(当前选中的选项),点击后才会展开所有选项,极大节省页面空间,用户体验更流畅。

你可以把它想象成奶茶店的 "口味选择下拉框":默认只显示 "请选择口味",点击后展开 "原味、珍珠、芋泥、啵啵" 等所有选项,选完后自动收起,只显示你选的口味,不占多余空间。

1.5.1 核心标签构成(2 个必用标签 + 1 个可选标签,新手必记)
标签名 定义 类型 核心规则
<select> 下拉菜单的 "总容器" 闭合标签(必须有开始和结束标签) 所有选项必须放在<select>和</select>之间,不能放在外面;必须写 name 属性,否则选中的值无法提交给后端
<option> 下拉菜单的 "单个选项" 闭合标签(必须有开始和结束标签) 必须放在<select>内部,每个 option 对应一个可选选项;必须写 value 属性,否则后端拿到的是 option 标签里的文字
<optgroup> 下拉菜单的 "选项分组" 闭合标签(可选,新手了解即可) 用于给 option 分组,比如 "国内省份" 和 "国外国家" 分组,让选项更清晰,不会混乱
1.5.2 select 标签的核心属性
属性名 作用 合法取值 实战例子 & 新手必记细节
name 下拉菜单的 "身份证号",后端通过 name 获取选中的选项值 自定义有意义的英文字符串(比如 birthYear、province、city) 必写属性!!! 没有 name 的 select,提交表单时不会被传递给后端,后端拿不到值!例子:<select name="birthYear">
multiple 允许多选(按住 Ctrl/Command 键可以同时选多个选项) 布尔属性,直接写属性名即可,无需赋值 例子:<select name="hobby" multiple>⚠️ 新手注意:1. 加了 multiple 后,下拉菜单会变成列表样式,不会收起;2. 多选时,后端会收到一个数组,和复选框类似;3. 实际开发中用得极少,多选优先用复选框,用户体验更好。
size 设置下拉菜单默认显示的行数(默认 1 行) 正整数(比如 3、5、10) 例子:<select name="year" size="5">(默认显示 5 行选项)⚠️ 新手注意:size 和 multiple 一起用的时候,体验更好,单独用得极少。
disabled 禁用整个下拉菜单 ------ 菜单变灰,无法展开,无法选择,值不会被提交 布尔属性,直接写属性名即可 例子:<select name="province" disabled>⚠️ 新手注意:禁用整个 select 后,里面所有的 option 都会被禁用。
required 必填项 ------ 必须选一个选项,否则浏览器不让提交表单 布尔属性,直接写属性名即可 例子:<select name="province" required>⚠️ 新手注意:需要给第一个 option 设置value=""且disabled selected,否则用户不选也能提交。
1.5.3 option 标签的核心属性(全讲透,每个都有例子)
属性名 作用 合法取值 实战例子 & 新手必记细节
value 选项的 "实际值"------ 提交给后端的就是这个值 自定义有意义的字符串 / 数字 必写属性!!! 不写 value 的话,后端会拿到 option 标签里的文字(比如<option>北京市</option>,后端拿到 "北京市"),但实际开发中,后端一般需要的是编码(比如 110000),而不是中文文字,所以必须写 value!例子:<option value="110000">北京市</option>
selected 默认选中该选项 ------ 页面加载后,这个选项会默认显示在 select 框里 布尔属性,直接写属性名即可 例子:<option value="1995" selected>1995年</option>⚠️ 新手注意:1. 单选下拉菜单里,最多只能有一个 option 写 selected,写多个的话,只有最后一个生效;2. 多选下拉菜单里,可以给多个 option 写 selected,默认选中多个。
disabled 禁用单个选项 ------ 该选项变灰,无法选择 布尔属性,直接写属性名即可 例子:<option value="" disabled selected>--请选择省份--</option>⚠️ 新手必用技巧:给第一个 "请选择" 的 option 加 disabled 和 selected,用户无法选这个空选项,必须选一个有效选项,配合 required 使用,完美实现必填验证!
label 选项的 "简化显示名"(极少用) 自定义字符串 例子:<option value="110000" label="北京">北京市</option>,下拉菜单里会显示 "北京" 而不是 "北京市",几乎不用,直接写在 option 标签里更清晰。
1.5.4 optgroup 标签(选项分组,实用技巧)

当你的选项超过 10 个,比如全国 34 个省份,直接堆在一起会非常乱,用户很难找到想要的选项;这时候用<optgroup>给选项分组,比如 "华北地区""华东地区""华南地区",选项会自动折叠分组,非常清晰,用户体验拉满。

  • 核心属性 :label(分组的名称,必写!)、disabled(禁用整个分组,可选)。

实战例子:

html 复制代码
<!-- 省份选择下拉菜单:分组显示,必填,默认选中"请选择省份"且禁用 -->
<label for="province">所在省份:</label>
<select id="province" name="province" required>
  <!-- 第一个空选项:禁用+默认选中,配合required实现必填验证 -->
  <option value="" disabled selected>--请选择省份--</option>
  
  <!-- 华北地区分组 -->
  <optgroup label="华北地区">
    <option value="110000">北京市</option>
    <option value="120000">天津市</option>
    <option value="130000">河北省</option>
    <option value="140000">山西省</option>
  </optgroup>
  
  <!-- 华东地区分组 -->
  <optgroup label="华东地区">
    <option value="310000">上海市</option>
    <option value="320000">江苏省</option>
    <option value="330000">浙江省</option>
    <option value="340000">安徽省</option>
  </optgroup>
  
  <!-- 华南地区分组 -->
  <optgroup label="华南地区">
    <option value="440000">广东省</option>
    <option value="450000">广西壮族自治区</option>
    <option value="460000">海南省</option>
  </optgroup>
</select>
1.5.5 完整实战例子
html 复制代码
<!-- 出生年份选择下拉菜单:配合label,必填,默认选中1995年 -->
<label for="birthYear">出生年份:</label>
<select id="birthYear" name="birthYear" required>
  <option value="" disabled>--请选择年份--</option>
  <option value="1990">1990年</option>
  <option value="1991">1991年</option>
  <option value="1992">1992年</option>
  <option value="1993">1993年</option>
  <option value="1994">1994年</option>
  <option value="1995" selected>1995年</option>
  <option value="1996">1996年</option>
  <option value="1997">1997年</option>
  <option value="1998">1998年</option>
  <option value="1999">1999年</option>
  <option value="2000">2000年</option>
</select>
1.5.6 避坑指南
  1. select 没写 name:后端拿不到选中的值,白选了!!!
  2. option 没写 value:后端拿到的是中文文字,不符合后端的数据规范,必须写 value!!!
  3. required 配合空选项没加 disabled :比如<option value="" selected>--请选择--</option>,用户可以选这个空选项,required 完全失效,必须给空选项加 disabled!!!
  4. 单选下拉菜单里给多个 option 加 selected:只有最后一个生效,前面的都没用,单选只能有一个默认选中项!!!
1.5.7 最佳实践
  1. 所有 select 必须配合 label 使用:用 for+id 绑定,提升用户体验;
  2. select 必须写 name,option 必须写 value:这是后端能拿到数据的前提,必写!!!
  3. 必填下拉菜单必须加 "禁用的空选项" :<option value="" disabled selected>--请选择--</option>,配合 required 实现完美的必填验证;
  4. 选项超过 10 个必须用 optgroup 分组:让选项更清晰,用户更容易找到想要的选项,提升体验;
  5. 不要用 multiple 实现多选:多选优先用复选框,用户体验更好,multiple 的下拉菜单操作很反人类。

1.6 文本域:textarea 标签 ------ 大段文本输入的 "专属框"

前面我们讲的<input type="text">只能输入单行文本 ,最多显示几十个字,当你需要让用户输入大段文本(比如留言、备注、个人简介、商品评价、文章内容)时,单行文本框完全不够用,用户体验极差;这时候<textarea>标签就是专门为这个场景设计的 ------ 它是一个多行文本输入框,可以输入、显示多行大段文本,支持滚动条,完全满足大段文本的输入需求。

你可以把它想象成银行申请表单上的 "备注栏":有好几行的空白区域,让你写大段的补充说明,而不是只能写一行的小格子。

1.6.1 核心定义与基础语法

<textarea>是闭合标签(必须有开始标签<textarea>和结束标签</textarea>),这是它和 input 标签最大的区别之一!!!

  • 它的默认内容写在两个标签之间,而不是用 value 属性!!!
  • 它是专门用于输入多行大段文本的控件,支持换行、滚动条,可调整大小(默认)。

基础语法:

复制代码
<!-- 正确写法:默认内容写在标签之间,不是用value属性!!! -->
<textarea name="remark" rows="5" cols="50" placeholder="请输入留言内容">
这是默认内容(可选)
</textarea>

<!-- 错误写法:用value属性设置默认内容,完全无效!!! -->
<textarea name="remark" value="这是默认内容"></textarea>
1.6.2 核心属性
属性名 作用 合法取值 实战例子 & 新手必记细节
name 文本域的 "身份证号",后端通过 name 获取用户输入的内容 自定义有意义的英文字符串(比如 remark、intro、comment、content) 必写属性!!! 没有 name 的 textarea,提交表单时不会被传递给后端,后端拿不到值!例子:<textarea name="intro"></textarea>
rows 设置文本域默认显示的行数(默认约 2 行),决定了文本域的默认高度 正整数(比如 3、5、10、20) 例子:<textarea rows="5"></textarea>(默认显示 5 行,高度约 5 行文字)⚠️ 新手注意:rows 只是默认显示的行数,用户输入的内容超过行数时,会自动出现垂直滚动条,不会限制输入的总行数。
cols 设置文本域默认显示的列数(默认约 20 列),决定了文本域的默认宽度 正整数(比如 30、50、100) 例子:<textarea cols="50"></textarea>(默认显示 50 列,宽度约 50 个英文字符)⚠️ 新手注意:cols 只是默认显示的列数,实际开发中,我们一般用 CSS 的 width 属性设置宽度,比 cols 更灵活、更精准。
maxlength 限制用户输入的最大字符数(包括汉字、字母、数字、标点、换行符) 正整数(比如 100、500、2000) 例子:<textarea maxlength="500" placeholder="最多输入500字"></textarea>⚠️ 新手注意:1. 一个汉字、一个字母、一个数字、一个标点、一个换行符,都算一个字符;2. 超过 maxlength 后,用户无法再输入内容,浏览器会自动限制;3. 配合 required 使用,实现必填 + 字数限制的双重验证。
minlength 限制用户输入的最小字符数,浏览器会自动验证,少于这个数不让提交 正整数(比如 10、50) 例子:<textarea minlength="10" placeholder="最少输入10个字"></textarea>⚠️ 新手注意:配合 required 使用才有效,否则用户不输入内容也能提交。
placeholder 文本域的 "提示文字"------ 浅灰色,用户开始输入后自动消失 自定义字符串(比如 "请输入留言内容,最多 500 字") 例子:<textarea placeholder="请输入你的个人简介,最多500字"></textarea>⚠️ 新手注意:placeholder 只是提示文字,不是默认内容,不会被提交给后端,和 input 的 placeholder 完全一致。
readonly 只读模式 ------ 用户只能看内容,不能修改、不能输入,提交表单时,内容会被传递给后端 布尔属性,直接写属性名即可 例子:<textarea readonly>这是只读内容,不能修改</textarea>⚠️ 新手注意:和 disabled 的区别:readonly 的内容会被提交,外观和普通文本域一样,不会变灰;disabled 的内容不会被提交,会变灰。
disabled 禁用文本域 ------ 文本域变灰,用户不能输入、不能修改、不能选中,提交表单时,内容不会被传递给后端 布尔属性,直接写属性名即可 例子:<textarea disabled>这是禁用的内容,不能修改</textarea>
required 必填项 ------ 用户必须输入内容,否则浏览器不让提交表单 布尔属性,直接写属性名即可 例子:<textarea required placeholder="请输入留言内容"></textarea>
wrap 设置文本的换行方式(新手了解即可) 两个常用值:1. soft(默认值):输入时自动换行,提交给后端时不保留换行符;2. hard:输入时自动换行,提交给后端时保留换行符(必须配合 cols 属性使用) 例子:<textarea wrap="hard" cols="50"></textarea>⚠️ 新手注意:默认用 soft 即可,几乎不用改。
resize 控制用户是否可以拖动调整文本域的大小(CSS 属性,新手必用) CSS 取值:1. both(默认):可以调整宽度和高度;2. vertical:只能调整高度;3. none:禁止调整大小 例子:<textarea style="resize: none;"></textarea>(禁止用户调整大小,实际开发中常用)
1.6.3 完整实战例子
html 复制代码
<!-- 留言板文本域:配合label,5行50列,最多500字,必填,禁止调整大小 -->
<div>
  <label for="message">留言内容:</label>
  <br>
  <textarea 
    id="message" 
    name="message" 
    rows="5" 
    cols="50" 
    maxlength="500" 
    minlength="10"
    placeholder="请输入你的留言内容,最少10个字,最多500字" 
    required
    style="resize: none; padding: 8px; font-size: 14px;">
  </textarea>
</div>

<!-- 只读的订单备注文本域 -->
<div>
  <label for="orderRemark">订单备注:</label>
  <br>
  <textarea 
    id="orderRemark" 
    name="orderRemark" 
    rows="3" 
    cols="50" 
    readonly
    style="resize: none;">
1. 快递请放在小区丰巢柜;
2. 周末不送货,工作日下午配送;
3. 请电话联系,不要敲门。
  </textarea>
</div>
1.6.4 避坑指南
  1. 用 value 属性设置默认内容:textarea 的默认内容必须写在标签之间,用 value 完全无效!!!这是新手最容易犯的错误!!!
  2. 没写 name 属性:后端拿不到用户输入的内容,白写了!!!
  3. 标签之间加了多余的空格 / 换行 :比如<textarea> 这是默认内容 </textarea>,提交的内容会带多余的空格 / 换行,必须紧贴标签写,不要加多余的空白!!!
  4. 混淆 readonly 和 disabled:需要提交内容用 readonly,不需要提交用 disabled,不要搞反了!!!
  5. 用 rows/cols 设置精准宽高:rows/cols 只是大概的宽高,实际开发中用 CSS 的 width/height 设置更精准、更灵活!!!
1.6.5 最佳实践
  1. 所有 textarea 必须配合 label 使用:用 for+id 绑定,提升用户体验;
  2. 必须写 name 属性:这是后端能拿到数据的前提;
  3. 默认内容紧贴标签写:不要加多余的空格 / 换行,避免提交的内容带多余的空白;
  4. 必须设置 maxlength:限制用户输入的最大字符数,避免用户输入超长内容,导致后端报错;
  5. 建议禁止横向调整大小 :用 CSS 的resize: vertical;只允许调整高度,或者resize: none;完全禁止调整,避免用户把文本域拉得太宽,破坏页面布局;
  6. 大段文本必须用 textarea,不要用 input type="text":单行文本框只能输入少量内容,大段文本必须用 textarea,用户体验更好。

第二章 无语义标签:div & span------ 网页布局的 "万能容器"

学完了表单的所有核心标签,你一定会问:"我怎么把这些表单控件按'左 label 右控件'的方式排列?怎么把页面分成'头部、导航、内容、底部'?怎么给一段文字里的某个关键词标红、加粗?"

答案就是无语义标签:<div>和<span>。

它们和 h1、p、form、input 这些标签最大的区别是:它们没有任何固定的语义含义------h1 代表标题,p 代表段落,form 代表表单,而 div 和 span 不代表任何特定的内容类型,它们唯一的作用就是 **"包裹内容、分组管理、设置样式、控制布局"**,是网页布局的 "万能收纳工具"。

你可以把它们完美对应到生活中的收纳场景,永远不会忘:

  • <div> = 书桌上的 "大收纳箱":每个大收纳箱独占一层 / 一块地方,不会和其他大箱子挤在同一行;可以装任何东西 ------ 课本、文具、零食,甚至可以大箱子套小箱子;用来把书桌(网页)分成不同的大区域。
  • <span> = 大收纳箱里的 "小便利贴 / 标签贴":不会单独占地方,只会贴在某个小物件上,占的大小完全由内容决定;用来给局部内容做标记、加样式、改颜色,不会影响整体布局。

2.1 div 标签:块级元素的 "大收纳箱"(网页布局的主力军)

<div> 是块级元素(block element),是网页布局中用得最多的标签,没有之一!90% 的网页布局都是靠 div 实现的,它就像乐高积木里的基础方块,能搭出任何你想要的页面结构。

2.1.1 核心特点
  1. 独占一行,自动换行:不管 div 里的内容有多少,哪怕只有一个字,它默认都会占满整行,后面的元素必须换行显示,绝对不会和其他元素挤在同一行;就像大收纳箱往书桌上一放,左右两边都没地方放其他大箱子了,必须放下一行。
  2. 默认宽度 100%:div 的默认宽度会自动撑满它的 "父容器"(比如整个网页 body、或者它所在的另一个 div)的宽度;就像大收纳箱默认会占满书桌的整个宽度。
  3. 可以自由设置宽高:可以通过 CSS 的width和height属性,自由设置 div 的宽度和高度,想多大就多大;就像你可以买不同尺寸的收纳箱,自由调整大小。
  4. 可以嵌套任何元素:div 里面可以放任何东西 ------ 文本、图片、表单、其他 div(大箱子套小箱子)、span、h1、p、ul、table,几乎所有 HTML 标签都能放在 div 里面,兼容性拉满。
  5. 闭合标签:必须有开始标签<div>和结束标签</div>,哪怕里面没有内容,也必须写闭合标签,不能写成单标签。
2.1.2 核心使用场景(全覆盖,新手一看就懂)

div 是网页布局的 "万能工具",几乎所有布局场景都能用到,最常见的有 4 个:

场景 1:页面整体大布局

把整个页面分成不同的大区域,这是 div 最核心的用途,比如:

  • 页面头部(header):放 logo、标题、搜索框;
  • 导航栏(nav):放页面的主要链接;
  • 核心内容区(main):放页面的主要内容;
  • 侧边栏(sidebar):放相关推荐、热门标签;
  • 页面底部(footer):放版权信息、联系方式、备案号。

实战例子(页面大布局):

html 复制代码
<!-- 页面头部 -->
<div id="header" style="height: 80px; background: #f5f5f5; padding: 0 20px;">
  <h1>我的个人网站</h1>
</div>

<!-- 导航栏 -->
<div id="nav" style="height: 40px; background: #333; color: white; padding: 0 20px; line-height: 40px;">
  <a href="#" style="color: white; margin-right: 20px; text-decoration: none;">首页</a>
  <a href="#" style="color: white; margin-right: 20px; text-decoration: none;">教程</a>
  <a href="#" style="color: white; margin-right: 20px; text-decoration: none;">案例</a>
  <a href="#" style="color: white; text-decoration: none;">关于</a>
</div>

<!-- 主要内容区 -->
<div id="main" style="display: flex; padding: 20px;">
  <!-- 侧边栏 -->
  <div id="sidebar" style="width: 200px; background: #f5f5f5; padding: 10px; margin-right: 20px;">
    <h3>热门文章</h3>
    <ul>
      <li>HTML基础教程</li>
      <li>CSS布局技巧</li>
      <li>JS入门指南</li>
    </ul>
  </div>

  <!-- 核心内容 -->
  <div id="content" style="flex: 1; padding: 10px; border: 1px solid #eee;">
    <h2>HTML标签详解</h2>
    <p>本文详细讲解了HTML的所有核心标签,包括表单标签、布局标签等...</p>
  </div>
</div>

<!-- 页面底部 -->
<div id="footer" style="height: 60px; background: #333; color: white; text-align: center; line-height: 60px;">
  版权所有 © 2026 我的个人网站 | 备案号:粤ICP备12345678号
</div>
场景 2:组件 / 模块包裹

把页面里的独立组件 / 模块包裹起来,比如电商网站的商品卡片、新闻网站的新闻列表项、评论区的评论框、表单的分组模块,让代码结构更清晰,样式设置更方便。

实战例子(商品卡片):

html 复制代码
<!-- 商品卡片:一个div包裹所有内容,结构清晰,加样式非常方便 -->
<div class="product-card" style="width: 300px; border: 1px solid #eee; padding: 10px; margin: 10px; border-radius: 8px;">
  <!-- 商品图片 -->
  <img src="https://via.placeholder.com/280x200" alt="华为Mate60手机" style="width: 100%; border-radius: 4px;">
  <!-- 商品标题 -->
  <div class="product-title" style="font-size: 16px; font-weight: bold; margin: 10px 0; line-height: 1.5;">
    华为Mate60 128G 曜金黑 国行正品 全国联保
  </div>
  <!-- 商品价格 -->
  <div class="product-price" style="margin: 10px 0;">
    <span style="color: #f60; font-size: 20px; font-weight: bold;">¥5499</span>
    <span style="color: #999; text-decoration: line-through; font-size: 12px; margin-left: 5px;">¥5999</span>
  </div>
  <!-- 商品销量 -->
  <div class="product-sales" style="color: #666; font-size: 12px; margin-bottom: 10px;">
    已售:<span style="color: #f60;">10000+</span> 件
  </div>
  <!-- 按钮 -->
  <div class="product-btn">
    <button style="width: 100%; height: 40px; background: #f60; color: white; border: none; border-radius: 4px; font-size: 16px; cursor: pointer;">
      加入购物车
    </button>
  </div>
</div>
场景 3:表单控件分组

把表单里的不同模块(基本信息、上传文件、留言备注)用 div 分组,让表单结构更清晰,布局更整齐,后期维护更方便。

实战例子(表单分组):

html 复制代码
<form action="http://localhost:5000/api/register" method="post">
  <!-- 基本信息分组 -->
  <div class="form-group" style="margin-bottom: 15px;">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username" placeholder="请输入用户名">
  </div>

  <div class="form-group" style="margin-bottom: 15px;">
    <label for="pwd">密码:</label>
    <input type="password" id="pwd" name="pwd" placeholder="请输入密码">
  </div>

  <!-- 上传文件分组 -->
  <div class="form-group" style="margin-bottom: 15px;">
    <label for="avatar">上传头像:</label>
    <input type="file" id="avatar" name="avatar" accept="image/*">
  </div>

  <!-- 留言分组 -->
  <div class="form-group" style="margin-bottom: 15px;">
    <label for="intro">个人简介:</label>
    <br>
    <textarea id="intro" name="intro" rows="3" cols="50"></textarea>
  </div>

  <!-- 按钮分组 -->
  <div class="form-btn">
    <input type="submit" value="注册">
    <input type="reset" value="清空">
  </div>
</form>
场景 4:样式 / JS 操作的载体

给某一块内容加背景色、边框、圆角、阴影,或者用 JS 隐藏 / 显示某一块内容、修改某一块的内容,都需要用 div 把这块内容包裹起来,作为样式和 JS 操作的载体。

2.1.3 新手避坑指南
  1. 过度嵌套 div(div 地狱) :很多新手喜欢 div 套 div 套 div,比如<div><div><div><p>这是一段文字</p></div></div></div>,完全没必要的嵌套会让代码结构混乱,可读性极差,后期维护起来就是灾难,能少嵌套就少嵌套,够用就行。
  2. 用 div 代替语义化标签 :明明有 header、nav、footer、article 这些语义化标签,却全部用 div 代替,比如<div class="header">,虽然功能一样,但不利于 SEO 和无障碍访问,语义化标签优先,div 只做纯布局的容器。
  3. 用空 div 做布局间距 :很多新手喜欢用<div style="height: 20px;"></div>来实现元素之间的间距,这是非常不规范的写法,应该用 CSS 的margin和padding属性来实现间距,不要用空 div。
  4. 用无意义的类名 /id :给 div 加class="div1"、id="a1"这种无意义的名字,后期维护的时候完全不知道这个 div 是干嘛的,必须用header、product-card、form-group这种有意义的名字。
2.1.4 最佳实践
  1. 语义化优先:有合适的语义化标签(header、nav、footer、section、article),就优先用语义化标签,div 只做 "纯布局、无语义" 的容器;
  2. 最少嵌套原则:能不嵌套就不嵌套,能少嵌套就少嵌套,避免 "div 地狱",代码结构越简单越好;
  3. 类名 /id 必须有意义:用英文单词 / 拼音,准确描述 div 的用途,不要用无意义的名字,代码可读性更强;
  4. 不要用空 div 做布局:用 CSS 的 margin/padding 实现间距,不要用空 div;
  5. 闭合标签必须写 :哪怕 div 里面没有内容,也必须写</div>闭合标签,避免浏览器解析出错。

2.2 span 标签:行内元素的 "小便利贴"(局部内容的标记神器)

<span> 是行内元素 (inline element),和 div 正好相反,它不做页面的大布局,只做局部内容的精细化标记和样式调整,就像你贴在书本上的小便利贴,只占自己内容那么大的地方,不会影响整体布局。

2.2.1 核心特点
  1. 不独占一行,不会自动换行:span 只会占 "自己内容那么大的地方",会和其他行内元素(文本、图片、a 标签、其他 span)挤在同一行,不会换行;就像小便利贴,贴在文字旁边,不会单独占一行。
  2. 宽度和高度完全由内容决定:内容多就宽一点,内容少就窄一点,默认无法通过 CSS 的 width/height 设置宽高(修改 display 属性可以,新手了解即可);就像便利贴的大小由你写的字多少决定。
  3. 只能嵌套行内元素 :span 里面只能放文本、图片、a 标签、其他 span 等行内元素,绝对不能放 div、p、h1 等块级元素;就像便利贴只能贴在小物件上,不能贴在大收纳箱上。
  4. 不会破坏文本流:给一段文字里的某个词加 span,不会改变这段文字的排版,不会换行,不会影响其他文字的位置;就像给书本里的某个词贴个便利贴,不会改变书本的排版。
  5. 闭合标签 :必须有开始标签<span>和结束标签</span>,不能写成单标签。
2.2.2 核心使用场景

span 是 "局部内容的标记工具",只用于小范围的内容处理,最常见的有 3 个:

场景 1:局部文本的样式调整(最核心用途)

给一段文字里的某个关键词、某个数字、某几个字,单独设置样式 ------ 比如标红、加粗、改字体大小、改颜色、加下划线、加背景色,而不影响其他文字的样式,这是 span 最核心的用途,没有之一。

实战例子(局部样式调整,新手可直接复制):

html 复制代码
<p>
  【<span style="color: red; font-weight: bold;">限时特惠 最后3天</span>】
  华为Mate60手机,原价<span style="color: #999; text-decoration: line-through;">¥6999</span>,
  现在仅需<span style="color: #f60; font-size: 20px; font-weight: bold;">¥5499</span>,
  活动截止日期:<span style="color: #999; font-size: 12px;">2026-12-31</span>。
</p>

<p>
  本商品支持<span style="color: green;">7天无理由退货</span>、
  <span style="color: green;">假一赔十</span>、
  <span style="color: green;">全国联保</span>,
  放心购买!
</p>
场景 2:小范围内容的包裹,方便 JS 操作

包裹一段文本里的某个数字、某个词,方便后续用 JS 操作它 ------ 比如点击按钮修改购物车的数量、点击切换价格、实时修改倒计时,都需要用 span 把这个内容包裹起来,JS 才能精准找到它并修改。

实战例子(JS 操作的载体):

复制代码
<div>
  购物车:<span id="cart-count" style="color: #f60; font-weight: bold;">0</span> 件商品
  <button onclick="document.getElementById('cart-count').innerText = Number(document.getElementById('cart-count').innerText) + 1">
    加入购物车
  </button>
</div>

<div>
  倒计时:<span id="countdown">10</span> 秒
</div>
场景 3:相同内容的差异化标记

给多个相同的文字,用 span 包裹后加不同的类名,实现不同的样式,比如 "已发货" 标绿色,"待付款" 标橙色,"已取消" 标灰色,代码结构更清晰,样式设置更方便。

实战例子(差异化标记):

复制代码
<div>
  订单状态:<span class="status-success" style="color: green; font-weight: bold;">已发货</span>
</div>

<div>
  订单状态:<span class="status-pending" style="color: orange; font-weight: bold;">待付款</span>
</div>

<div>
  订单状态:<span class="status-canceled" style="color: #999; font-weight: bold;">已取消</span>
</div>
2.2.3 避坑指南
  1. 用 span 嵌套块级元素 :比如<span><div>这是div</div></span>,这是完全错误的!span 是行内元素,里面不能放 div、p、h1 等块级元素,会导致浏览器解析出错,布局完全混乱!!!
  2. 用 span 做页面大布局:很多新手分不清 div 和 span,用 span 做页面的大布局,这是完全错误的!span 是行内元素,无法设置宽高,无法做布局,大布局必须用 div!!!
  3. 过度使用 span :给每个字都套一个 span,比如<span>我</span><span>是</span><span>小</span><span>白</span>,完全没必要,只会让代码混乱,只有需要单独设置样式 / JS 操作的内容,才需要套 span!!!
2.2.4 最佳实践
  1. 只用于局部内容处理:span 只用来做局部文本的样式调整、JS 操作,不要用来做页面布局,布局用 div;
  2. 绝对不能嵌套块级元素:span 里面只能放文本、图片、a 标签、其他 span 等行内元素,绝对不能放 div、p、h1 等块级元素;
  3. 非必要不使用:不需要单独设置样式、不需要 JS 操作的内容,不要套 span,避免代码冗余;
  4. 类名必须有意义 :给 span 加的类名要准确描述用途,比如price、status-success、countdown,不要用无意义的名字。

2.3 div 和 span 的核心区别

很多新手一直分不清 div 和 span,用这个表格对比:

特性 div 标签(块级元素) span 标签(行内元素) 新手一句话总结
换行特性 ✅ 独占一行,默认占满整行,后面的元素必须换行 ❌ 不独占一行,和其他行内元素挤在同一行,不会换行 div 换行,span 不换行
宽度特性 默认宽度 100%,撑满父容器,可自由设置 width/height 宽度完全由内容决定,默认无法设置 width/height div 能调大小,span 不能
嵌套规则 可嵌套任何元素:块级元素(div/p/h1)、行内元素(span/a/img) 只能嵌套行内元素:文本、span、a、img 等,绝对不能嵌套块级元素 div 能装一切,span 只能装 "小东西"
核心用途 页面大布局、组件包裹、内容分组、大模块的样式 / JS 操作 局部文本的样式调整、小范围内容的 JS 操作、差异化标记 div 做大结构,span 做小细节
元素类型 块级元素(block) 行内元素(inline) 块级独占一行,行内同行显示

第三章 补充核心常用标签


3.1 语义化布局标签 ------ 让网页 "有意义" 的容器

很多新手会问:"有了 div,为什么还要这些语义化标签?"答案很简单:div 是 "无意义的箱子",搜索引擎、屏幕阅读器(给视障用户用)、浏览器,都看不懂这个 div 是干嘛的;而语义化标签有明确的含义,明确告诉所有设备 "这是页面头部""这是导航栏""这是文章内容",带来 3 个核心好处:

  1. 利于 SEO(搜索引擎优化):搜索引擎会优先抓取语义化标签里的内容,提升你的网站排名;
  2. 提升无障碍访问性:屏幕阅读器会根据语义化标签,给视障用户播报页面结构,比如 "这是页面头部,这是导航栏,这是文章内容";
  3. 代码可读性更强:其他开发者看你的代码,一眼就能看懂页面结构,不用猜这个 div 是干嘛的,后期维护更方便。

这些语义化标签和 div 的功能完全一样(都是块级元素,独占一行,可设置宽高,可嵌套任何元素),唯一的区别就是有明确的语义含义

3.1.1 常用语义化布局标签
标签名 核心含义(生活化比喻) 适用场景 实战例子 新手注意事项
<header> 页面 / 区域的 "头部 / 招牌" 1. 整个页面的头部:放 logo、网站标题、搜索框、登录入口;2. 某个模块的头部:比如文章的头部(放标题、发布时间、作者) ```html<header> <h1>我的博客</h1> <div class="search"> <input type="text" placeholder="搜索文章"> </div></header><article> <header> <h2>HTML 语义化标签详解</h2> <p>发布时间:2026-02-17 作者:前端博主</p> </header> <p>文章内容...</p></article>``` 一个页面可以有多个 header,不要用 header 代替 h1/h2 标题标签
<nav> 页面的 "导航栏 / 指示牌" 放页面的主要导航链接:顶部主导航、侧边栏导航、底部导航、分页导航 html<!-- 主导航栏 --><nav> <ul> <li><a href="#">首页</a></li> <li><a href="#">教程</a></li> <li><a href="#">案例</a></li> <li><a href="#">关于</a></li> </ul></nav> 一个页面可以有多个 nav,但不要把所有链接都放在 nav 里,只放主要的导航链接
<main> 页面的 "核心内容区 / 主营业区" 放页面的核心、唯一的主要内容,比如文章详情、商品详情、列表内容 html<body> <header>...</header> <nav>...</nav> <!-- 核心内容区,一个页面只能有一个main --> <main> <article>文章内容</article> <aside>侧边栏</aside> </main> <footer>...</footer></body> ⚠️ 一个页面只能有一个 main 标签!!!不要嵌套在 header/nav/footer 里,要放在页面的最外层
<section> 页面的 "章节 / 区块" 把页面内容分成独立的章节 / 模块,每个 section 都有自己的主题,比如 "热门商品""最新资讯""用户评价" html<main> <section> <h2>热门商品</h2> <div class="product-list">商品列表</div> </section> <section> <h2>最新资讯</h2> <div class="news-list">新闻列表</div> </section></main> 每个 section 都应该有一个标题(h2/h3),不要用 section 代替 div 做纯布局容器,没有主题的模块用 div
<article> 独立的 "文章 / 内容块" 放可以独立存在、单独拿出去也有完整意义的内容,比如博客文章、新闻详情、商品详情、用户评论、论坛帖子 html<article> <header> <h2>HTML标签详解</h2> <p>发布时间:2026-02-17</p> </header> <p>文章正文内容...</p> <footer> <p>作者:前端博主</p> </footer></article> article 是独立的内容块,可以嵌套 header/footer/section,一个页面可以有多个 article
<aside> 页面的 "侧边栏 / 附属内容" 放和核心内容相关的辅助内容,比如侧边栏、相关推荐、热门标签、作者信息、广告位 html<main> <article>文章内容</article> <!-- 侧边栏,附属内容 --> <aside> <h3>相关推荐</h3> <ul> <li><a href="#">CSS布局技巧</a></li> <li><a href="#">JS入门指南</a></li> </ul> </aside></main> 不要用 aside 放页面的主要内容,只放辅助、附属的内容
<footer> 页面 / 区域的 "底部 / 版权页" 1. 整个页面的底部:放版权信息、联系方式、备案号、友情链接;2. 某个模块的底部:比如文章的底部(放作者信息、版权声明) ```html<footer> <p>版权所有 © 2026 我的博客</p> <p>备案号:粤 ICP 备 12345678 号 联系方式:xxx@xxx.com</p></footer>``` 一个页面可以有多个 footer,不要在 footer 里放 main 标签

3.2 媒体标签 ------ 图片 / 音频 / 视频,让网页更丰富

网页不止有文字,还需要展示图片、播放音频 / 视频,这些都需要媒体标签来实现,下面把最常用的 3 个媒体标签讲透。


3.2.1 音频标签:``(网页的 "音乐播放器")

`` 是闭合标签,用于在网页中嵌入音频文件(音乐、语音、背景音乐),支持 MP3、WAV、OGG 格式,其中 MP3 格式的兼容性最好,所有浏览器都支持。

核心属性
属性名 作用 合法取值 实战例子
src 音频文件的地址 / 路径 绝对 URL / 相对 URL 必写属性! <audio src="music.mp3">
controls 显示浏览器自带的播放控件(播放 / 暂停按钮、进度条、音量调节) 布尔属性,直接写属性名即可 必写属性! 不写的话,页面上看不到播放器,用户无法操作!例子:<audio src="music.mp3" controls>
autoplay 页面加载后自动播放音频 布尔属性,直接写属性名即可 例子:<audio src="bg-music.mp3" autoplay muted>⚠️ 新手注意:现在几乎所有浏览器都禁止有声自动播放,必须配合muted(静音)才能自动播放!
loop 循环播放音频 布尔属性,直接写属性名即可 例子:<audio src="bg-music.mp3" loop controls>
muted 默认静音播放 布尔属性,直接写属性名即可 例子:<audio src="bg-music.mp3" muted controls>
兼容写法(适配所有浏览器)
复制代码
<audio controls>
  <!-- 优先加载MP3格式 -->
  <source src="music.mp3" type="audio/mpeg">
  <!-- 备用WAV格式 -->
  <source src="music.wav" type="audio/wav">
  <!-- 浏览器不支持时显示的文字 -->
  您的浏览器不支持音频播放,请升级浏览器!

3.2.2 视频标签:<video>(网页的 "视频播放器")

<video>是闭合标签,用于在网页中嵌入视频文件,支持 MP4、WEBM、OGG 格式,其中 MP4 格式的兼容性最好,所有浏览器都支持。

核心属性(和 audio 类似,新增 2 个核心属性)
属性名 作用 实战例子
src 视频文件的地址 / 路径(必写) <video src="movie.mp4"></video>
controls 显示播放控件(必写) <video src="movie.mp4" controls></video>
autoplay 自动播放(必须配合 muted) <video src="bg-video.mp4" autoplay muted></video>
loop 循环播放 <video src="bg-video.mp4" loop controls></video>
muted 默认静音 <video src="movie.mp4" muted controls></video>
width/height 视频的宽度 / 高度 <video src="movie.mp4" width="800" controls></video>(只写 width,height 自动等比例缩放)
poster 视频的封面图(播放前显示的图片) <video src="movie.mp4" poster="video-cover.jpg" controls></video>⚠️ 新手必用:没有 poster 的话,播放前会显示视频的第一帧,可能是黑屏,体验很差!
兼容写法(适配所有浏览器)
复制代码
<video controls width="800" poster="video-cover.jpg">
  <!-- 优先加载MP4格式 -->
  <source src="movie.mp4" type="video/mp4">
  <!-- 备用WEBM格式 -->
  <source src="movie.webm" type="video/webm">
  <!-- 浏览器不支持时显示的文字 -->
  您的浏览器不支持视频播放,请升级浏览器!
</video>

第四章 Emmet 快捷键------ 写代码快 10 倍的神器

Emmet 是 VS Code、WebStorm 等所有主流编辑器都内置的 "代码缩写工具",通过简单的缩写,按 Tab 键就能生成完整的 HTML 代码,不用手动敲每个标签的尖括号、闭合标签、属性,能让你写 HTML 的速度提升 10 倍,新手必须全部掌握!

4.1 基础快捷键(每天都用,必背)

缩写 作用 输入 + Tab 生成的 HTML 代码
! 一键生成 HTML5 完整基础模板(最常用!) ! + Tab html<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> </body></html>
标签名 生成单个标签 div + Tab <div></div>
标签名 * 数量 批量生成多个相同标签 li*5 + Tab html<li></li><li></li><li></li><li></li><li></li>
标签名 #id 名 生成带 id 的标签 div#header + Tab <div id="header"></div>
标签名。类名 生成带 class 类名的标签 div.product-card + Tab <div class="product-card"></div>
标签名 #id 名。类名 同时带 id 和类名 div#nav.nav-bar + Tab <div id="nav" class="nav-bar"></div>
父标签 > 子标签 生成嵌套的父子标签 ul>li + Tab html<ul> <li></li></ul>
标签 1 + 标签 2 生成同级的兄弟标签 div+p+span + Tab html<div></div><p></p><span></span>
标签 {内容} 生成带内容的标签 p{这是一段文字} + Tab <p>这是一段文字</p>

4.2 进阶快捷键(提升效率,必学)

缩写 作用 输入 + Tab 生成的 HTML 代码
标签 属性 = 值 生成带自定义属性的标签 a[href=https://www.baidu.com target=_blank] + Tab <a href="https://www.baidu.com" target="_blank"></a>
标签 {内容 $}* 数量 生成带编号的内容,$ 代表 1、2、3... li{第$.项}*3 + Tab html<li>第1.项</li><li>第2.项</li><li>第3.项</li>
() 分组,生成复杂的嵌套结构 div>(header>ul>li*3)+main+footer + Tab html<div> <header> <ul> <li></li> <li></li> <li></li> </ul> </header> <main></main> <footer></footer></div>

4.3 实战组合例子

  1. 生成完整的表单结构:form>div.form-group*3>label+input + Tab
  2. 生成商品列表:div.product-list>div.product-card*4>img+h3.product-title+p.price+button + Tab
  3. 生成导航栏:nav>ul>li*5>a{导航$} + Tab

第五章 HTML 特殊字符(深化版)------ 解决字符冲突的必备知识

HTML 中,<、>、&、"这些字符是 "保留字符",是 HTML 标签的组成部分,如果你直接在正文内容里写这些字符,浏览器会误以为是 HTML 标签,导致内容解析混乱、页面布局错乱;还有一些字符无法直接用键盘输入,比如空格、版权符号、人民币符号,这些都需要用 "HTML 特殊字符(字符实体)" 来替代。

5.1 特殊字符的格式

HTML 特殊字符的固定格式是:&字符名;(以 & 开头,以英文分号;结尾,中间是字符的名称),部分字符也可以用&#数字编码;的格式。

5.2 高频特殊字符

要显示的字符 字符实体(必记) 数字编码 作用 / 使用场景 实战例子
空格(多个连续空格) &nbsp; &#160; 浏览器默认会把多个连续的空格合并成一个,用&nbsp;可以实现多个连续空格 输入你&nbsp;&nbsp;&nbsp;好,显示你 好(3 个空格)
小于号 < &lt; &#60; 避免被浏览器解析为 HTML 标签的开头 要显示a < b,写a &lt; b
大于号 > &gt; &#62; 避免被浏览器解析为 HTML 标签的结尾 要显示b > a,写b &gt; a
和号 & &amp; &#38; 避免被浏览器解析为特殊字符的开头 要显示a & b,写a &amp; b
双引号 " &quot; &#34; 避免和 HTML 属性的双引号冲突 要显示他说:"你好",写他说:&quot;你好&quot;
单引号 ' ' &#39; 避免和 HTML 属性的单引号冲突 要显示他说:'你好',写他说:'你好'
版权符号 © &copy; &#169; 显示版权声明 写&copy; 2026 我的博客,显示© 2026 我的博客
人民币符号 ¥ &yen; &#165; 显示价格 写&yen;5499,显示¥5499
注册商标 ® &reg; &#174; 显示注册商标符号 写华为&reg;,显示华为®
乘号 × &times; &#215; 显示数学乘号 写3 &times; 4 = 12,显示3 × 4 = 12
除号 ÷ &divide; &#247; 显示数学除号 写12 &divide; 3 = 4,显示12 ÷ 3 = 4

5.3 实战例子(显示 HTML 代码片段)

如果你想在页面中显示 HTML 代码,而不是让浏览器解析它,必须用特殊字符替代<和>:

复制代码
<p>文本框的HTML代码是:&lt;input type="text" name="username" placeholder="请输入用户名"&gt;</p>

浏览器会显示:文本框的HTML代码是:<input type="text" name="username" placeholder="请输入用户名">,而不是解析成一个输入框。

结语

好啦,到这里咱们 HTML 常见核心标签的小完结篇就真的结束咯!回顾一下这篇博客,我们从表单标签聊起 ------ 它是用户与网站的 "对话窗口",form 标签划定范围、指定目标,input 像变形金刚一样满足各种输入需求,label 提升点击体验,select/option 做下拉选择,textarea 装大段文本;接着聊了无语义标签 div 和 span------div 是网页布局的 "大收纳箱",做整体大布局、组件包裹,span 是 "小便利贴",专门给局部内容加样式、做标记;然后补充了语义化布局标签、媒体标签、列表标签、链接标签,让网页不仅有结构,还更有意义、更丰富;最后讲了 Emmet 快捷键这个 "效率神器",以及 HTML 特殊字符这个解决字符冲突的必备知识。

其实 HTML 就像网页的 "骨架和砖瓦"------ 它本身没有华丽的外表,但却是所有网页的根基:没有 form 标签,用户没法和网站互动;没有 div/span,没法做精细化布局;没有语义化标签,搜索引擎和屏幕阅读器看不懂你的网页;没有媒体标签,网页就只有干巴巴的文字。所以千万别觉得这些标签简单就轻视它们,把基础打牢,后面学 CSS 给网页 "化妆"、学 JavaScript 让网页 "动起来" 的时候,才会更顺手~

接下来,大家可以试着把这两篇博客学的 HTML 标签结合起来,自己写一个完整的页面:比如写一个个人主页,用 header 放头部和导航,main 放核心内容,aside 放侧边栏,footer 放版权信息;再写一个注册表单,用上 form、input、label、select、textarea;最后用 Emmet 快捷键提升写代码的速度,遇到特殊字符记得用字符实体。不用怕写不好,编程就是在不断 "试错" 中进步的 ------ 修改一下标签的位置,调整一下属性的值,每一次小修改都会让你对 HTML 更熟悉。

等你能熟练写出结构清晰、语义化的 HTML 页面后,咱们就可以进入下一个阶段:用 CSS 给网页 "化妆"------ 给文字换颜色、给页面加背景、把内容排列得整整齐齐、给按钮加 hover 效果;再之后学 JavaScript,让网页 "动起来"------ 点击按钮弹出个弹窗、输入文字后实时给出反馈、轮播图自动播放,到时候你就能真正体会到前端开发的乐趣啦!

前端的世界才刚刚向你敞开大门,继续加油吧,期待看到你写出更精彩、更完整的网页!

相关推荐
恋猫de小郭1 小时前
Kotlin 2.5 的 Companion 改造,对 KMP 的重要升级
android·前端·flutter
前端双越老师1 小时前
程序员 1v1 访谈系列第二期:很焦虑但又不知道干啥
前端·ai编程·全栈
广州华水科技2 小时前
北斗形变监测传感器在大坝安全监测中的应用与优势分析
前端
倒头就睡的小比特2 小时前
HTML代码框架+标签初识1
html
孔令飞2 小时前
如何学习Go
前端
HUIBUR科技2 小时前
AI 中枢,面向企业场景构建的 AI 智能体
前端·数据库·人工智能
怕浪猫2 小时前
给AI配一台电脑,开源版Muse来了,OpenMuse赶紧去二次开发吧
javascript·面试·github
随便写个软件2 小时前
【新版本】EasyExplorer资源管理器 3.12.0——地址栏重要更新
运维·服务器·前端·everything·资源管理器
Jack N2 小时前
【Strapi 系列之二】Collection / Single / Component 怎么选?Strapi 字段大全一篇讲透
前端·javascript·strapi