前言
前端开发的概述
前端开发(Front-end Development)是指创建网站或 Web 应用程序用户界面(UI)及用户体验(UX)部分的过程,涉及用户直接与之交互的所有内容。
通常我们说的前端就是 WEB 前端,也就是写网页的。
核心职责
- 界面实现:将设计稿转化为可交互的网页
- 用户体验优化:确保界面响应迅速、操作流畅
- 浏览器兼容性:保证在不同浏览器和设备上表现一致
- 性能优化:提高页面加载速度和运行效率
- 与后端协作:通过 API 获取和提交数据
核心技术栈
- 基础三件套
- HTML:页面结构和内容
- CSS:样式和布局
- JavaScript:交互逻辑和行为
- 现代技术生态
- 框架/库:Vue、React、Angular 等
- CSS 预处理器:Sass、Less
- 构建工具:Vite、Webpack、Parcel
- 包管理器:npm、yarn、pnpm
- 类型系统:TypeScript
- 测试工具:Jest、Cypress、Testing Library
简单概括三件套的作用与关系:HTML 是网页的元素骨架,CSS 是网页的装潢皮肤,JavaScript 是网页的大脑。三者共同构建完整的网页。
开发环境的搭建
推荐使用以下工具进行开发:
- 浏览器:谷歌 Chrome / Edge(或其他主流浏览器)
- 编辑器:VS Code

HTML 基础
HTML 简介
HTML(HyperText Markup Language,超文本标记语言)是用于创建网页的标准标记语言。写好的 HTML 代码文件,拖拽到浏览器上,就可以让它解析并渲染出相应的内容!
你可以理解为,如果你想写一个页面展示出来,那么里面的各种展示元素就是用 HTML 代码编写的。
HTML 特点
- 它并不是严格意义上的编程语言,而是一种标记语言,但对我们来说也是得写代码的~
- 它使用一种叫做标签的东西来描述网页上的内容,HTML 代码就是由标签组成的
- 它的文件扩展名为 .html 或 .htm
- HTML 是由浏览器解析并渲染成可视化网页的(也就是说浏览器认识这个 HTML,然后能解析并渲染出东西来)
<!-- 首先就是注释标签,它是长这样子的,在 HTML 后缀代码文件里,注释也是标签形式的 -->
<!DOCTYPE html>
<!-- 这个的意思是让浏览器解析该文档的时候按照 HTML 代码标准去解析 -->
<html lang="zh-CN">
<!-- html 标签代表着当前页面是 HTML 代码渲染出来的,我们可以观察到它是由一对尖括号组成的 -->
<head>
<!-- 头标签,这个标签内部存放着网页基本与重要的信息内容,比如说这个网页名也就是网页标题叫什么,这个网页是什么编码的,图标是什么等等 -->
<meta charset="UTF-8">
<title>我的第一个网页</title>
</head>
<body>
<!-- 那么说完了 head 头标签,就要说 HTML 中的 body 主体标签了,主体标签很吊,它其实就是网页上看到的内容,是真正能看到的!展示给我们的! -->
Hello HTML!
</body>
</html>
- 双标签格式:
<标签名 属性名="属性值">双标签内容</标签名> - 单标签格式:
<标签名 属性名="属性值"/> - 文档类型声明:
<!DOCTYPE html>声明文档类型为HTML5 - 根元素:
<html>是文档的根元素,包含整个 HTML 文档,浏览器解析的时候,会直接解析 html 标签内部的文本内容! - 头部区域:
<head>包含元数据(网页重要信息设置)、网页的标题、引入文件(引入一些便携的代码文件,辅助开发)等 - 主体区域:
<body>包含网页的可见内容,这才是以后总打交道的区域~
标签的属性,是为了让标签实现具体功能效果的~ 而具体怎么去实现,实现怎样的效果,就需要开发者按照需求去定义了,当然,只要这个标签支持就问题~
最常用标签与语义化布局标签
最常用标签
我们先直接来介绍很多常用的标签,分别是大标题标签,文字段落标签,地址链接标签,换行标签以及图片标签。
<h1>欢迎来到我的网站</h1>
<p>这是一个段落,<strong>加粗文字</strong> 和 <em>斜体文字</em> 示例。</p>
<a href="https://www.example.com" target="_blank">访问示例网站</a>
<br>
<img src="logo.png" alt="网站 Logo" width="200">
布局类标签(语义化标签)
顾名思义就是这些标签的名字,就代表了它们应该在网页的哪个部分出现!但这些标签又本身没有这个实际效果...
<header>, <nav>, <main>, <section>, <footer>
header就是页头区域nav就是网页导航栏区域main就是主体区域section指的是一个段落区域footer是页尾区域(这个页尾区域,基本上每个正规的网页都应该是差不多固定长那样的,啥样呢?我随便打开个网站哈,大家看到了吧,就是备案的信息,几乎都在页尾区域的!这个时候肯定有人好奇,欸?敲上了这些标签,但它们并没有按照你说的位置去渲染在网页上啊,这是怎么回事?)
答:这个就是比较有意思的地方了,规定是 CSS 做这种位置的布局,而不能用 HTML 去做这部分的功能,对,这是一个约定、规定。也就导致了,HTML 这几个布局类标签,失去了布局的功能,仅存的只有语义化本身了,所以也有很多人将他们称之为语义化标签或语义化布局标签!
链接与图片
<a href="https://www.google.com">Google</a>
<a href="about.html">关于我们</a>
<a href="https://www.example.com" target="_blank">在新标签页打开</a>
<a href="https://example.com" target="_blank" rel="noopener">这个 rel = noopener 就是安全的新窗口链接</a>
<a href="#section1">锚点</a>
<h2 id="section1">第一部分内容</h2>
<img src="图片路径" alt="图片显示不出来的替代文本(图片描述文本)">
<img src="images/photo.jpg" alt="一张风景照片">
<img src="banner.png" alt="网站首页横幅" width="800" height="200" loading="lazy">
<a href="https://www.example.com"><img src="logo.png" alt="Example 公司 Logo"></a>
列表
<!-- 无序列表 -->
<ul>
<li>列表项 1</li>
<li>列表项 2</li>
<li>列表项 3</li>
</ul>
<!-- 有序列表 -->
<ol>
<li>第一步</li>
<li>第二步</li>
<li>第三步</li>
</ol>
<!-- 很显然我们可以嵌套列表 -->
<ul>
<li>水果
<ul>
<li>苹果</li>
<li>香蕉</li>
</ul>
</li>
<li>蔬菜
<ul>
<li>胡萝卜</li>
<li>菠菜</li>
</ul>
</li>
</ul>

定义列表
<dl>
<dt>术语名称</dt>
<dd>术语的定义或描述</dd>
<dt>另一个术语</dt>
<dd>它的解释</dd>
</dl>
表格


<table>
<caption>我是表格的标题</caption>
<thead>
<tr>
<th>商品</th>
<th>价格</th>
<th>库存</th>
</tr>
</thead>
<tbody>
<tr>
<td>苹果</td>
<td>5 元/斤</td>
<td>100</td>
</tr>
<tr>
<td>香蕉</td>
<td>3 元/斤</td>
<td>200</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">总计</td>
<td>300 件</td>
</tr>
</tfoot>
</table>
合并单元格
- 横向合并:用
colspan="n"(跨 n 列) - 纵向合并:用
rowspan="n"(跨 n 行)
<table border="1">
<tr>
<th>姓名</th>
<th colspan="2">联系方式</th><!-- 合并两列 -->
</tr>
<tr>
<td>王五</td>
<td>电话</td>
<td>邮箱</td>
</tr>
<tr>
<td rowspan="2">赵六</td><!-- 合并两行 -->
<td>138****1234</td>
<td>[email protected]</td>
</tr>
<tr>
<td>139****5678</td>
<td>[email protected]</td>
</tr>
</table>
完整案例:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>学生成绩表</title>
<style>
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th, td { border: 1px solid #999; padding: 10px; text-align: center; }
th { background-color: #e0e0e0; }
caption { font-size: 1.2em; font-weight: bold; margin-bottom: 10px; }
</style>
</head>
<body>
<table>
<caption>高一(3)班期中考试成绩</caption>
<thead>
<tr>
<th>姓名</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
</tr>
</thead>
<tbody>
<tr>
<td>小明</td>
<td>85</td>
<td>92</td>
<td>88</td>
</tr>
<tr>
<td>小红</td>
<td>90</td>
<td>87</td>
<td>93</td>
</tr>
</tbody>
</table>
</body>
</html>
表单
HTML 表单(Form)是网页中用于收集用户输入用的,属于核心的构成部分。比如登录、注册、搜索、留言、下单等交互功能都需要它来配合完成。
此外对于表单这一块内容,我们还需要先单独为大家讲解下何为请求。以及 Post/Get 这两种请求方式的区别。(PS:虽然我们并没有正儿八经的后端与 JS 的学习,但也可以用 HTML 先来观察请求发送数据的效果。这样也有助于我们后续的学习。)
基本的网络请求相关知识
- 网络请求:是指
客户端(如浏览器、手机 App、程序等)向服务器发送的一种数据交互行为,目的是获取资源、提交数据或执行某种操作。它是现代互联网应用实现数据通信的基础。- 最基本、常见的请求:在浏览器中打开一个网页(其实就是浏览器向服务器请求 HTML 文件 ~)
- URL:统一资源定位符。在现代互联网中,通常用作网络请求的目标地址(知道地址,才能知道要把数据发送到哪里)
- https://api.example.com (长这样大概)
- 也可以是本地某些资源文件
目前,我们说的网络请求,通常指的都是 HTTP 协议的请求。
- 就像两个人聊天要遵守语言语法一样,浏览器和服务器通信也要遵守 HTTP 这套'网络语言'。
- HTTP 请求报文
- 方法(Method):GET(获取)、POST(提交)等
- 路径(Path):/ 表示首页
- 协议版本:HTTP/1.1
- 请求头(Headers):附加信息,比如浏览器类型、语言偏好
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html
- HTTP 响应报文
- 状态码:200 表示成功,404 表示页面没找到
- 响应头:说明内容类型(HTML、图片、JSON 等)
- 响应体:真正的数据(网页、图片、API 返回的数据)

HTTPS:你把要求写在加密信封里,只有厨房能打开——别人偷看也看不懂
✅ 所以登录、支付等敏感操作,必须用 HTTPS(地址栏有 🔒 图标)
何为字符编码
我们都知道,计算机其实只懂 0 和 1(也就是二进制)。包括各种各样的文件,本质也是二进制。所以计算机是不能直接理解'你好'、'Hello'或者一个表情 😊。
所以,这就很烦,人类只能发明一种方法:给每个 字符 分配一个 数字编号,然后把 数字 转成 二进制,这样计算机就能存储和传输文字了。
这个'字符 ↔ 数字'的对应规则,就叫做 字符编码(Character Encoding)。
我来给大家举个例子吧,要不然太抽象了。。。
// 比如像下面这样,做个映射表。我们称之为 ASCII 编码
A → 65
B → 66
C → 67
// 那么此时,我们就把 A 当作 65 再转为 二进制 01000001,计算机就能看懂了。
// 再由某些带有翻译功能的终端,就可以根据你提供的编码规则,将二进制数据进行翻译,最终还原为 A 这个字母。
// 我们的浏览器,肯定是支持这种翻译功能的。所以你只需要告诉浏览器,你的编码规则是啥就行了。
Unicode:天下一统,它是一个超级大表,给世界上几乎所有的字符都分配了一个唯一的编号(叫'码点')。但这玩意可不是数字啊,所以就有了 UTF-8 把 Unicode 编号转成字节序列。
- 兼容 ASCII:所有 ASCII 字符(0–127)在 UTF-8 中和原来一模一样(1 个字节)。
- ✅ 节省空间:英文用 1 字节,中文一般用 3 字节,生僻字或 emoji 用 4 字节。
- ✅ 无乱码风险:只要大家都用 UTF-8,文字就能正确显示。
- ✅ 互联网主流:现在 98% 以上的网页都用 UTF-8!

所以,unicode 是一种编码的标准,而 utf-8 是编码方式,是真正的做事的东西。
Get 与 Post 请求方式
网络请求,也是要分请求方式来进行的。目前主流的,还是 Get 与 Post,这俩种方式,在进行数据交互时,各有特色。
- get 方式:比较裸露,会把发送的数据直接拼到 URL 上。以
https://api.example.com为例 - post 方式:数据藏在 HTTP 请求的'身体(请求体)'里,对用户不可见,也更安全(相对而言)。
正文


<form action="/submit" method="post">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="email" placeholder="邮箱">
<input type="number" name="age" min="0" max="120">
<input type="radio" name="gender" value="male"> 男
<input type="radio" name="gender" value="female"> 女
<input type="checkbox" name="hobby" value="reading"> 阅读
<input type="checkbox" name="hobby" value="music"> 音乐
<select name="city">
<option value="">请选择城市</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
</select>
<textarea name="message" rows="4" cols="50" placeholder="请输入留言..."></textarea>
<input type="file" name="avatar" accept="image/*">
<input type="submit" value="提交表单">
<!-- 或 -->
<button type="submit">提交</button>
</form>

<input type="date">
<input type="range" min="0" max="100">
<input type="color" name="theme_color">
<input type="url">
<input type="search">

完整案例
<form action="/register" method="post">
<label>用户名:<input type="text" name="username" required></label><br>
<label>邮箱:<input type="email" name="email" required></label><br>
<label>密码:<input type="password" name="password" minlength="6" required></label><br>
<label>性别: <input type="radio" name="gender" value="m"> 男 <input type="radio" name="gender" value="f"> 女 </label><br>
<label>兴趣: <input type="checkbox" name="hobbies" value="sports"> 运动 <input type="checkbox" name="hobbies" value="music"> 音乐 </label><br>
<label>头像:<input type="file" name="avatar" accept="image/*"></label><br>
<button type="submit">注册</button>
</form>
语义化标签
<header>页眉</header>
<nav>导航</nav>
<section>区域</section>
<article>文章</article>
<aside>侧边栏</aside>
<footer>页脚</footer>
多媒体标签
<video src="movie.mp4" controls></video>
<audio src="music.mp3" controls></audio>


Iframe 嵌入
<iframe src="URL" width="宽度" height="高度"></iframe>
<iframe src="https://example.com" width="800" height="600"></iframe>
<iframe src="local-page.html" style="width:100%;height:400px"></iframe>
<!-- YouTube 视频 -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/视频 ID" frameborder="0" allowfullscreen></iframe>
<!-- Google 地图 -->
<iframe src="https://maps.google.com/maps?q=地址" width="600" height="450"></iframe>
<iframe srcdoc="<h1>直接嵌入的内容</h1><p>这段 HTML 代码会被直接渲染</p>" width="300" height="150"></iframe>
<iframe src="..." sandbox="allow-scripts allow-forms"></iframe>
<iframe src="doc.pdf" type="application/pdf" width="100%" height="600px"></iframe>

sandbox
- allow-scripts - 允许执行脚本
- allow-forms - 允许提交表单
- allow-same-origin - 允许同源访问
- allow-popups - 允许弹出窗口
CSS 样式与布局
CSS 语法与规则
在学习 HTML 的时候,我们就提到过。CSS 是专门装潢的,给网页内容装潢的。也就是给 HTML 标签,这些元素装潢的。比如对文字进行大小、颜色控制,设置背景图片,改变某些元素的位置,设计元素们的布局等。
语法结构
CSS 语法结构由 选择器(Selector) 和 声明块(Declaration Block) 组成: 大概意思是说,我们必须得通过一些标识符,来确定某个页面上的元素,然后对其进行装潢工作。
选择器 {
属性 1: 值 1;
/* 这个就是 CSS 的注释 */
属性 2: 值 2;
/* 我们看到,装潢,其实也是通过属性名与属性值,而这种格式,就是我们说的键值对格式。 */
}
现在,我来给大家介绍两个常用于文本的修饰属性,然后直接用标签名来作为选择器。
h1 {
/* 选择器(选中所有 <h1> 元素) */
color: red;
/* 颜色通常我们用 语义化的英文单词,rgb,rgba,其它的用的比较少,可以自行搜索,学习。 */
font-size: 24px;
/* 这个就是 字体的大小 */
}
本人在这里,再给大家介绍一些常用的单位:px、%、vw、vh
CSS 使用规则
目前 CSS 支持三种使用方式。
- 行内样式(内联样式优先级最大):每个标签都可以在 style 属性里面,写它的 CSS 声明。
<p style="color:red;">我是一个段落</p>
- 内部样式(优先级仅次于行内样式):css 样式代码,写到 head 标签内的 style 标签里。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个网页</title>
<style>
p { color: blueviolet; font-size: 15px; }
h2 { color: coral; }
</style>
</head>
<body>
<h1>我是 h1 标题</h1>
<h2>我是 h2 标题</h2>
<p style="color: red; font-size: 30px;">我是一个段落</p>
<p>我是第二个段落</p>
</body>
</html>
- 外联样式(与内联优先级一致,看谁后写的,就会覆盖前面):从外部 css 文件,引入进来的。
demo.css
p {
color: darkorange !important;
/* 如果后面加上了 !important 代表优强制最高,覆盖所有该属性的样式。也就是 color */
font-size: 75px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个网页</title>
<style>p{color: blueviolet;font-size: 15px;}h2{color:coral;}</style>
<link rel="stylesheet" href="./demo.css">
</head>
<body>
<h1>我是 h1 标题</h1>
<h2>我是 h2 标题</h2>
<p style="color: red; font-size: 30px;">我是一个段落</p>
<p>我是第二个段落</p>
</body>
</html>
CSS 选择器

基本选择器

- 元素选择器:选择器就是标签名,然后修饰这个标签名,那么只要是这个标签的,就都会有这个装潢效果。
- 类选择器:一般,强调一组,我们才会使用类选择器。但随着互联网发展,类选择器,无论你强调啥,几乎都用类选择器。
- ID 选择器:强调唯一性,只有是这个 ID 的元素,才会生效装潢。
- 通配符选择器:最常用的就是 *,一般都是用在 网页初始化样式上。目前了解即可。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个网页</title>
<style>
p { color: blueviolet; font-size: 15px; }
#PID { color: red; }
.ppap { color: green; }
</style>
</head>
<body>
<p id="PID" class="ppap">我有 id、class</p>
</body>
</html>
组合选择器

div p { color: blue; /* div 内的所有 p 元素变蓝 */ }
div > p { font-size: 18px; /* 仅 div 的直接子 p 元素生效 */ }
h1 + p { margin-top: 0; /* h1 后的第一个 p 元素上边距为 0 */ }
常用伪类与伪元素选择器
伪类和伪元素是 CSS 中用于选择元素的特殊状态或特定部分的机制,它们不是直接通过 HTML 标签、类或 ID 选择的,而是由 CSS 动态生成的。
打个比方:某个元素鼠标经过的状态,我需要对这个元素进行装潢。那么你就得用 伪类选择器
选择器:hover。后面的 :hover 就是状态。
交互状态伪类

button:hover { background: #555; /* 鼠标悬停时按钮变暗 */ }
input:focus { border: 2px solid blue; /* 输入框聚焦时边框变蓝 */ }
结构伪类(选择特定位置的元素)

/* 表格隔行变色 */
tr:nth-child(odd) { background: #f2f2f2; }
/* 排除特定类 */
button:not(.disabled) { cursor: pointer; }
表格状态伪类

input:disabled { opacity: 0.5; /* 禁用输入框变半透明 */ }
input:invalid { border-color: red; /* 非法输入时边框变红 */ }
内容插入伪元素

.tooltip::after { content:"提示文字"; display: none; }
.tooltip:hover::after { display: block; /* 悬停时显示提示 */ }
文本修饰伪元素

p::first-letter { font-size: 24px; /* 首字母放大 */ }
::selection { background: #ffcc00; /* 选中文本时背景变黄 */ }

还有一个选择器,叫做属性选择器(相信大家在进行完前面选择器学习后。是可以查资料,自行去了解学习的。所以,由于本人在实际开发中,用到的不多,也就不再做过多的讲述 ~)
PS:其实在真实的项目开发中,我们可以边去查资料,边去开发。没有谁是刻意去背这些东西的。犯不上 ~
文本与字体样式
字体样式
p {
font-family: "Arial", "Helvetica", sans-serif; /* 字体族 */
font-size: 24px;
font-weight: bold; /* 或使用数字值 100-900 */
font-style: oblique; /* normal oblique 模糊斜体 inherit 继承父元素的字体样式 italic 斜体样式 */
/* font-variant: small-caps; /* 小型大写字母 */ */
line-height: 1.5; /* 行高 */
font: italic bold 16px/1.5 "Times New Roman", serif;
}
文本样式
p {
color: #336699;
text-align: center; /* 一般都是在某个容器/父元素上使用,意思是说里面的文本元素,是居中的。 */
text-decoration: none; /* 常用于去除链接下划线 underline overline 上划线 line-through 中划线 */
/* text-decoration: underline wavy red 2px; 可以这样一起写,比较方便 ~ */
text-decoration-color: red; /* 给装潢线设置颜色 */
text-decoration-style: solid; /* 装潢线样式 solid double dotted dashed wavy */
/* text-transform: uppercase; /* none 不转换 upper 转大写 lowercase 转小写 capitalize 每个单词首字母大写 full-width 全部变为全角字符 "Hello" → "Hello" */ */
text-indent: 2em; /* 段落首行缩进 em 单位优势:2em 表示缩进两个字体大小的距离(自适应字体变化) */
letter-spacing: 2px; /* 字符之间的距离 */
word-spacing: 0.5em; /* 单词之间的距离 */
white-space: pre; /* pre 保留空白和换行 normal */
text-shadow: 2px 2px 4px rgba(0,0,0,0.5); /* 水平偏移(正值 右)垂直偏移(正值 下)模糊半径 颜色 */
}
white-space

text-shadow

文本省略号(实际开发中,直接 复制粘贴即可 ~)
/* 单行 */
.ellipsis {
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis; /* 显示省略号 */
width: 200px; /* 必须设置宽度(或 max-width) */
}
/* 多行 */
.multi-line-ellipsis {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 限制显示行数 */
overflow: hidden;
text-overflow: ellipsis;
}
盒模型概念
盒模型概念:其实就是 CSS 的'俄罗斯套娃',当然,你必须得知道 双标签都可以当作一个盒子来看待。然后你才要去定义盒子内容、内边距、边框、外边距等概念。
默认盒模型
.box {
box-sizing: content-box; /* 不用写,默认就是 */
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid blue;
margin: 10px;
}
这个 .box 的总占用空间是:
- 总宽度:200 (width) + 20+20 (padding) + 5+5 (border) + 10+10 (margin) = 270px
- 总高度:100 (height) + 20+20 (padding) + 5+5 (border) + 10+10 (margin) = 170px
怪异盒模型
规则:你设置的 width 和 height 已经包含了 Content、Padding 和 Border。
.box {
box-sizing: border-box; /* 开启怪异盒模型 */
width: 200px; /* 这个 200px 已经包含了 content+padding+border! */
height: 100px;
padding: 20px;
border: 5px solid blue;
margin: 10px;
}
这个 .box 的总占用空间是:
- 总宽度:200 (width) + 10+10 (margin) = 220px
- 总高度:100 (height) + 10+10 (margin) = 120px
传统布局
默认文档流
- 块级元素是垂直排列的
- 行内元素是水平排列的
.block { display: block; } /* 独占一行 */
.inline { display: inline; } /* 同行排列 */
.inline-block { display: inline-block; /* 同行但可设宽高宽高 */ width: 100px; }
浮动布局(了解即可)
元素直接脱离正常流,向左右浮动
<div class="container">
<div class="sidebar">侧边栏</div>
<div class="main">主内容</div>
</div>
.sidebar { float: left; width: 200px; background: #f0f0f0; }
.main { margin-left: 220px; /* 避免重叠 */ background: #e0e0e0; }
/* 清除浮动 - 重要! */
.container::after {
content:"";
display: table;
clear: both;
}
定位布局
.relative { position: relative; /* 相对自身原位置去进行定位 */ top: 10px; left: 20px; }
.absolute { position: absolute; /* 相对最近定位祖先 */ top: 0; right: 0; }
.fixed { position: fixed; /* 相对视口 */ bottom: 20px; right: 20px; }
.sticky { position: sticky; /* 滚动时粘性定位 */ top: 0; }
现代布局
弹性布局
容器可以改变其子项的宽度/高度,以最好地填充可用空间,适应所有类型的显示设备和屏幕尺寸。
基础概念:
- 容器:display: flex
- 主轴:flex-direction 定义的方向
- 交叉轴:与主轴垂直的方向
<div class="flex-container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.flex-container {
display: flex;
justify-content: center; /* 主轴对齐 */
align-items: center; /* 交叉轴对齐 */
gap: 10px; /* 项间距 */
flex-wrap: wrap; /* 换行 */
}
.item { flex: 1; /* 弹性增长 */ min-width: 100px; }
主轴方向
.container {
display: flex; /* 四种可能的值 */
flex-direction: row; /* 默认:从左到右 */
flex-direction: row-reverse; /* 从右到左 */
flex-direction: column; /* 从上到下 */
flex-direction: column-reverse; /* 从下到上 */
}
是否换行
.container {
display: flex;
flex-wrap: nowrap; /* 默认:不换行,压缩项目 */
flex-wrap: wrap; /* 换行:第一行在上方 */
flex-wrap: wrap-reverse; /* 换行:第一行在下方 */
}
主轴方向对齐方式
.container {
display: flex;
justify-content: flex-start; /* 默认:左对齐 */
justify-content: flex-end; /* 右对齐 */
justify-content: center; /* 居中 */
justify-content: space-between; /* 两端对齐,项目间间隔相等 */
justify-content: space-around; /* 每个项目两侧间隔相等 */
justify-content: space-evenly; /* 项目间间隔完全相等 */
}
交叉轴对齐
.container {
display: flex;
align-items: stretch; /* 默认:拉伸填满容器高度 */
align-items: flex-start; /* 顶部对齐 */
align-items: flex-end; /* 底部对齐 */
align-items: center; /* 居中对齐 */
align-items: baseline; /* 基线对齐 */
}
多行对齐
.container {
display: flex;
flex-wrap: wrap;
height: 400px; /* 需要有高度才能看出效果 */
align-content: stretch; /* 默认:拉伸填满 */
align-content: flex-start; /* 各行在顶部紧贴 */
align-content: flex-end; /* 各行在底部紧贴 */
align-content: center; /* 各行在中间 */
align-content: space-between; /* 第一行顶头,最后一行底尾 */
align-content: space-around; /* 每行上下间隔相等 */
}
项排序
.item:nth-child(1) { order: 3; } /* 第三个显示 */
.item:nth-child(2) { order: 1; } /* 第一个显示 */
.item:nth-child(3) { order: 2; } /* 第二个显示 */
项放大比例
.item:nth-child(1) { flex-grow: 1; } /* 占 1 份剩余空间 */
.item:nth-child(2) { flex-grow: 2; } /* 占 2 份剩余空间 */
/* 这意味着第二个项目会是第一个的两倍宽 */
/* 33.33% 与 66.66% 宽度 */
项缩小比例
.item:nth-child(1) { flex-shrink: 0; } /* 禁止缩小 */
.item:nth-child(2) { flex-shrink: 1; } /* 默认缩小 */
项单独对齐
允许单个项目有与其他项目不一样的对齐方式
.item:nth-child(1) {
align-self: auto; /* 默认:继承 align-items */
align-self: flex-start; /* 单独顶部对齐 */
align-self: center; /* 单独居中对齐 */
}


