HTML 先描述内容的含义,再由 CSS 决定外观。标题、导航、文章、表单有不同用途;浏览器、搜索引擎和辅助技术会利用这些结构。把所有东西写成 div,会把现成的键盘操作、表单行为和可访问名称都变成自己的维护工作。
从文档到控件
一个独立页面至少说明文档类型、语言、字符集、标题和视口。主内容用 main;一组站点链接可以用 nav;标题按照内容层级排列。section 通常有自己的主题标题。article 表示可独立使用的内容。不要根据默认字号选 h1 或 h3,字号交给 CSS。
链接负责前往某个地址,button 负责当前页面的动作。表单里的 button 默认可能提交,所以非提交按钮要明确写 type=“button”。每个输入框用 label 关联;placeholder 在输入后会消失,不能承担标签的全部职责。
<form id="signup">
<label for="email">邮箱</label>
<input id="email" name="email" type="email"
autocomplete="email" required>
<label for="topic">想学习的方向</label>
<select id="topic" name="topic">
<option value="web">Web 基础</option>
<option value="mobile">跨端应用</option>
</select>
<button type="submit">检查信息</button>
</form>
<p id="status" role="status"></p>
name 决定字段在 FormData 中的键,id 用于关联标签和定位元素。disabled 控件通常不参与提交;readonly 控件仍会提交。checkbox 没有选中时一般不产生同名字段,不能把“缺字段”直接解释成接口损坏。
跑通一次提交
完整示例 可以直接在浏览器打开。尝试空邮箱、格式错误的邮箱和有效邮箱,再只用 Tab、Shift+Tab、Enter 操作。
const form = document.querySelector("#signup");
form.addEventListener("submit", (event) => {
event.preventDefault();
const data = new FormData(form);
document.querySelector("#status").textContent =
"已检查:" + data.get("email") + ",方向:" + data.get("topic");
});
submit 事件发生前,浏览器会进行约束验证。required、type、min、max、pattern 能处理一部分输入错误。自定义错误可以用 setCustomValidity;条件恢复时必须传空字符串清除旧错误。前端验证帮助用户及时改正,服务端仍须独立验证并检查权限。
真实提交还需要区分等待、成功、失败,保留用户已经输入的内容。错误信息应说明哪个字段、什么条件不满足,并用 aria-describedby 关联帮助文字;提交失败不能只把按钮变红。
练习与自查
给表单加一个学习时长字段,范围 10–120 分钟。解释为什么 value 仍可能是字符串,以及为什么服务端不能信任浏览器的 min/max。检查点击标签是否能聚焦输入框、错误是否能被朗读、非提交按钮是否意外触发提交。
面试时应能回答:语义标签如何影响可访问性?GET 查询表单和修改数据的 POST 表单有什么差别?为什么不能把密码放进 URL?