2.1 HTML、CSS 与浏览器
本章目标: 写出简单的语义化页面,知道 CSS 如何定位元素,理解浏览器里发生了什么。
浏览器和服务器各做什么
服务器返回 HTML、CSS、JS 文件以及 API 数据。浏览器解析 HTML 形成 DOM,应用 CSS 计算布局,执行 JavaScript 处理交互。
Vue 单页应用通常先加载前端入口,再调用 ASP.NET Core API 获取 JSON。路由切换可以在浏览器完成,不必每次向服务器请求一份 Razor 页面。
MVC 的 Controller 仍可以作为 API 后端。Vue 接管交互和页面状态,服务端继续负责认证、权限、数据验证和持久化。
HTML 是结构
以下片段可放在 App.vue 的 <template> 中:
<main>
<h1>任务管理</h1>
<form>
<label for="title">任务名称</label>
<input id="title" name="title" type="text" required maxlength="100" />
<button type="submit">添加</button>
</form>
<ul>
<li>学习 JavaScript</li>
<li>学习 Vue 3</li>
</ul>
</main>
main 表示主体,h1 是页面标题,form 是表单,ul/li 是无序列表。label 的 for 与输入框 id 对应,点击标签能聚焦输入框,辅助技术也能读出名称。
注意:普通表单默认可能提交并刷新页面。Vue 里通常用 @submit.prevent 接管提交,详见事件与表单。非提交按钮要写 type="button"。
CSS 是样式与布局
main {
max-width: 48rem;
margin: 2rem auto;
padding: 1rem;
}
form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
}
input {
flex: 1;
min-width: 0;
padding: 0.5rem;
border: 1px solid #a0a6ad;
}
| 选择器 | 示例 | 意义 |
|---|---|---|
| 标签 | input | 所有输入框 |
| 类 | .task-row | class="task-row" 的元素 |
| ID | #app | 指定 ID 的元素 |
| 状态 | button:disabled | 禁用的按钮 |
| 后代 | .task-row span | 任务行中的所有后代 span |
选择器冲突时会比较来源、层叠层、优先级等规则,不能简单认为“写在后面总是赢”。初学阶段优先用清晰的类名,避免大量 !important。
盒模型与响应式布局
元素的尺寸包括内容、padding、border 和 margin。统一使用:
*, *::before, *::after {
box-sizing: border-box;
}
这样声明的宽度包含内边距和边框,更容易计算。max-width 限制大屏阅读宽度,padding 保留小屏边距,flex-wrap 让表单在窄屏换行。
布局重点是让内容在不同宽度下都能使用,先掌握 Flex 和 Grid,不必先背完全部 CSS 属性。
用开发者工具观察
在浏览器按 F12:Elements 查看 DOM 与样式;Console 查看 JS 日志;Network 查看 API 请求。把屏幕宽度调整到手机尺寸,检查横向溢出和按钮是否能正常点击。
required 和 maxlength 可以改善体验,但用户可绕过页面直接请求 API。ASP.NET Core 必须独立验证输入。
练习
给任务列表加 .tasks 类,把每个任务行变成左右分布的布局。将浏览器缩窄到 375px,检查表单能否换行。
参考答案
.tasks { padding: 0; list-style: none; }
.tasks li {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 0.75rem 0;
border-bottom: 1px solid #d9dde2;
}
如果内容很长,文字区域可增加 min-width: 0 和 overflow-wrap: anywhere,避免撑破父容器。