1.grid-template-areas
作用:在划分完网页区域之后,网页页面的布局就是一个网格的形式,而"grid-template-areas"则是用于将需要的网格进行融合,通俗易懂的讲就是告诉浏览器,网格中的哪些部分属于一个整体区域
语法简介:
- 用“ ”括起来的内容表示一行
- 用分隔号分开的每一个区域名字都表示一列;
- 相同区域名的网格会合成到一起
初始状态:最基础的网格(2 行 3 列)
先定义一个 2 行 3 列的网格,用 x、y、z 作为区域名(随便起的简单名字),初始代码和文本图如下:
css
.container {
display: grid;
grid-template-columns: 100px 100px 100px; /* 3列,每列100px */
grid-template-rows: 80px 80px; /* 2行,每行80px */
/* 初始区域定义:2行,每行3个区域名(空格分隔) */
grid-template-areas:
"x y z" /* 第1行:3列分别是x、y、z */
"x y z"; /* 第2行:3列分别是x、y、z */
}
对应的文本图(像表格一样,每个格子对应区域名):
+------+------+------+
| x | y | z | 第1行
+------+------+------+
| x | y | z | 第2行
+------+------+------+
语法 1:每个字符串 = 一行,空格分隔 = 列
- 上面代码中,
"x y z"和"x y z"是两个字符串,对应网格的「第 1 行」和「第 2 行」; - 字符串里的
x y z用空格隔开,对应每行的「第 1 列」「第 2 列」「第 3 列」。
规则:所有字符串的「单词数量必须相同」(保证列数一致),比如上面每行都是 3 个词(3 列),如果改一行少一个词就会报错:
/* 错误示例:第1行3列,第2行2列,列数不匹配 */
grid-template-areas:
"x y z"
"x y"; /* 语法错误!浏览器会忽略整个属性 */
语法 2:相同名称 = 合并成一个大区域
如果多个格子用「相同的名称」,它们会自动合并成一个连续的矩形区域。比如把初始网格的 x 换成 a,y 换成 a,看看变化:
grid-template-areas:
"a a z" /* 第1行:前两列都是a,第三列z */
"a a z"; /* 第2行:前两列都是a,第三列z */
更新后的文本图(a 合并成了一个 “2 行 2 列” 的大区域):
+------+------+------+
| | |
| a | z | 第1行:a占前2列
| | |
+------+------+------+
| | |
| a | z | 第2行:a占前2列
| | |
+------+------+------+
关键:合并的区域必须是「矩形」(不能是凹形或 L 形)。比如下面的 a 是错的(不是矩形):
/* 错误示例:a的形状是L形,不合法 */
grid-template-areas:
"a a z"
"a z z"; /* 浏览器会忽略这个定义 */
语法 3:. 代表空区域(该位置不放元素)
用 . 表示 “这个格子是空的,不分配元素”。比如在上面的基础上,把 z 换成 .(空):
grid-template-areas:
"a a ." /* 第1行:前两列a,第三列空 */
"a a ."; /* 第2行:前两列a,第三列空 */
文本图(第三列变成空格子):
+------+------+------+
| | |
| a | . | 第1行:第三列空
| | |
+------+------+------+
| | |
| a | . | 第2行:第三列空
| | |
+------+------+------+
小技巧:多个连续的空格子可以简写(比如 .. 代表两列空),但推荐用空格分开(. .)更易读。
语法 4:元素通过 grid-area 对应区域
定义好区域后,给元素设置 grid-area: 区域名,元素就会自动进入对应区域。比如在上面的网格中,加一个元素 .box 对应 a:
.box { grid-area: a; } /* 元素放到a区域 */
最终布局文本图(.box 填满 a 的大区域):
+------+------+------+
| |
| .box | 第1行:.box占前2列
| |
+------+------+------+
| |
| .box | 第2行:.box占前2列
| |
+------+------+------+
总结:核心逻辑
grid-template-areas 就像用 “文字画表格”:
- 每行一个字符串 → 对应网格的一行;
- 空格分隔的单词 → 对应每行的一列;
- 相同单词 → 合并成矩形区域;
-
.→ 空格子;
2.grid切分区域逻辑
切分逻辑:
- 列(grid-template-columns) 负责横向切分宽度,顺序是 从左到右 划分;
- 行(grid-template-rows) 负责纵向切分高度,顺序是 从上到下 划分。
示例代码:
:root{
--ridebar-width:24rem;
--top-bar-height:6rem;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 62.5%;
}
body{
height: 100dvh;
display: grid;
grid-template-columns:var(--ridebar-width) 1fr ;
grid-template-rows: var(--top-bar-height) 1fr;
grid-template-areas:
"sidebar top-bar"
"sidebar content-area"
}
第一步:明确初始状态(未布局时的页面)
在没加任何网格布局时,页面是一个「完整的视口高度区域」(因为 body { height: 100dvh; },100dvh 表示占满屏幕可视高度)。
初始文本图(整个页面是一个大盒子):
plaintext
+----------------------------------------+
| |
| 整个页面(100dvh高) |
| |
+----------------------------------------+
第二步:横向切分(列)—— grid-template-columns
代码中用 grid-template-columns: var(--ridebar-width) 1fr 定义了列的划分,先看变量::root { --ridebar-width: 24rem; } → 侧边栏宽度固定为 24rem(rem 是相对单位,1rem 通常 = 16px,这里约 384px)。
列的切分逻辑:
- 第 1 列:宽度 =
--ridebar-width(24rem),专门给侧边栏用; - 第 2 列:宽度 =
1fr(fraction,比例单位),表示 “占剩余所有空间”,给主内容相关区域用。
此时页面被横向切成了「左右两列」,文本图如下:
plaintext
+------------------+-----------------------+
| | |
| 第1列(24rem) | 第2列(1fr) |
| (侧边栏预留) | (顶部栏+内容区预留) |
| | |
+------------------+-----------------------+
关键:
1fr 会自动 “吃掉” 剩余空间。比如屏幕宽度是 100rem,第 1 列占 24rem,第 2 列就占 76rem(100-24);如果屏幕变宽,第 2 列会自动变宽,第 1 列始终 24rem。
第三步:纵向切分(行)—— grid-template-rows
代码中用 grid-template-rows: var(--top-bar-height) 1fr 定义了行的划分,变量::root { --top-bar-height: 6rem; } → 顶部栏高度固定为 6rem(约 96px)。
行的切分逻辑:
- 第 1 行:高度 =
--top-bar-height(6rem),专门给顶部栏用; - 第 2 行:高度 =
1fr,表示 “占剩余所有空间”,给主内容区用。
此时页面在横向两列的基础上,又被纵向切成了「上下两行」,形成一个「2 行 2 列」的网格(共 4 个单元格)。文本图如下:
plaintext
+------------------+-----------------------+
| | |
| 第1行第1列 | 第1行第2列 |
| (高6rem) | (高6rem) |
| | |
+------------------+-----------------------+
| | |
| 第2行第1列 | 第2行第2列 |
| (高1fr) | (高1fr) |
| | |
+------------------+-----------------------+
关键:
整个页面高度是 100dvh(比如屏幕高 80rem),第 1 行占 6rem,第 2 行就占 74rem(80-6);屏幕高度变化时,第 2 行会自动适配剩余空间。
第四步:给网格区域命名 —— grid-template-areas
有了 2 行 2 列的网格后,用 grid-template-areas 给每个单元格(或合并单元格)起名字,对应页面的具体区域:
css
grid-template-areas:
"sidebar top-bar" /* 第1行:第1列叫sidebar,第2列叫top-bar */
"sidebar content-area"; /* 第2行:第1列叫sidebar,第2列叫content-area */
区域合并逻辑:
- 第 1 行第 1 列和第 2 行第 1 列都叫
sidebar→ 这两个单元格合并成一个大区域(占 2 行 1 列),就是侧边栏; - 第 1 行第 2 列叫
top-bar→ 单独作为顶部栏区域(占 1 行 1 列); - 第 2 行第 2 列叫
content-area→ 单独作为主内容区(占 1 行 1 列)。
最终布局文本图(标注区域名):
plaintext
+------------------+-----------------------+
| | |
| | top-bar |
| sidebar | (顶部导航/工具栏) |
| | |
+------------------+-----------------------+
| | |
| | |
| sidebar | content-area |
| (侧边导航) | (主要内容展示区) |
| | |
| | |
+------------------+-----------------------+
总结:各部分的作用
-
:root变量 → 统一管理侧边栏宽度和顶部栏高度,改一处全页面生效; -
grid-template-columns→ 横向切分左右两列(固定宽 + 自适应宽); -
grid-template-rows→ 纵向切分上下两行(固定高 + 自适应高); -
grid-template-areas→ 给网格单元格命名并合并,形成三个功能区域:-
sidebar(侧边栏):左列全高(2 行 1 列); -
top-bar(顶部栏):右列第一行(1 行 1 列); -
content-area(内容区):右列第二行(1 行 1 列)。
-
3.overflow-y: auto
作用:
比如在一个 100px×100px 的容器中(容器高度固定为 100px,可视化高度 100px),如果内容高度为 200px,容器会先显示内容的前 100px,超出的 100px 会被容纳在容器内部(视觉上隐藏),同时会显示垂直滚动条,拖动滚动条往下滚动,就能查看到之前隐藏的内容。
4.flex-direction:column;和flex-direction:column;
flex中的一种布局模式,direction是方向的意思,column表示列的意思,row表示行的意思
flex中的列(column)布局:
+---------------------+
| |
| Item 1 |
| |
+---------------------+
| |
| Item 2 |
| |
+---------------------+
| |
| Item 3 |
| |
+---------------------+
flex中的行(row)布局:
+---------------------+---------------------+---------------------+
| | | |
| Item 1 | Item 2 | Item 3 |
| | | |
+---------------------+---------------------+---------------------+
| 属性值 | 布局方向 | 主轴方向 | 项目排列方式 |
|---|---|---|---|
flex-direction: row |
水平布局(默认) | 水平(左→右) | 从左到右依次排列 |
flex-direction: column |
垂直布局 | 垂直(上→下) | 从上到下依次排列 |
5.flex: 0 0 auto和flex: 1 1 auto
| 特性 | flex: 0 0 auto(固定尺寸) | flex: 1 1 auto(自适应填充) |
|---|---|---|
| 空间充足时 | 不拉伸,剩余空间留白 | 拉伸,填满剩余空间 |
| 空间不足时 | 不收缩,直接溢出 | 收缩,适配容器不溢出 |
| 项目尺寸来源 | 自身内容 / 手动设置(width/height) | 容器剩余空间 + 自身内容 |
| 比喻 | 「固定大小的箱子」,不能变形 | 「可伸缩的气球」,能胀能缩 |
6.object-fit:contain;
object:对象 fit:适应 contain:容纳
object 指的是 被替换元素的内容。最常见的就是 <img> 标签所引用的图片文件
contain 在这里是一个 形容词或副词,用来修饰 fit 这个动作的方式。它规定了 “适应” 的 具体规则。这个规则就是:“要把那个东西(object)完整地、全部地容纳(contain)在容器里面”。
- 保持内容的宽高比:无论容器的尺寸如何变化,图片或视频的宽高比都不会被破坏,不会被拉伸或压缩变形。
- 完整显示内容:确保图片或视频的全部内容都能在容器内可见。
- 适应容器:将内容缩放至最大尺寸,以使其能够完全容纳在容器内。
7.border-radius: 10px;
border-radius 是一个 用于设置元素圆角的 CSS 属性。
逐词拆解
-
border- 英语本意: 边界、边缘、边框。
- 在 CSS 中的含义: 指的是元素的边框。
-
radius- 英语本意: 半径。
-
在 CSS 中的含义: 这里指的是圆角的半径。一个圆的半径越大,圆就越大、越平缓。在
border-radius中,这个值越大,元素的角就越圆、越明显。
-
border-radius- 组合含义: 字面意思就是 “边框的半径”。
- 在 CSS 中的作用: 这个属性用来定义元素四个角的圆角弧度。它通过将元素的直角用一段圆弧来代替。
8.cursor: pointer;
cursor: pointer; 是一个 用于设置鼠标指针样式 的 CSS 属性,它的作用是:当鼠标指针悬停在一个元素上时,将其形状改变为一只 “手” 的图标。
这个视觉上的变化向用户传递了一个非常重要的信息:“这个元素是可点击的(clickable)” 或者 “这个元素是一个链接(link)”。
逐词拆解
-
cursor- 英语本意: 光标、指针。
- 在 CSS 中的含义: 指的是你在屏幕上看到的、由鼠标控制的那个移动的小图标。
- 在 CSS 中,
cursor属性就是用来定义这个图标的外观的。
-
pointer- 英语本意: 指针、指示物。
-
在 CSS 中的含义: 在这里,
pointer是一个关键字,它代表了一种特定的光标样式。 - 这个样式就是我们通常所说的 “手型光标” 或 “指向手光标”。这个视觉上的变化向用户传递了一个非常重要的信息:“这个元素是可点击的(clickable)” 或者 “这个元素是一个链接(link)”。
9.css里面.menu-item.active { ... }
| 场景 | 写法 | 示例 | 解释 |
|---|---|---|---|
| HTML | 多个类名用空格分隔 | <li class="menu-item active"> |
这个 <li> 元素同时属于 menu-item 类和 active 类。 |
| CSS | 多个类选择器直接连接(无空格) | .menu-item.active { ... } |
选择所有同时拥有 menu-item 类 并且 拥有 active 类的元素。 |
- 目的:为了能给同一个 HTML 元素设置基础样式和状态样式,并让它们能独立工作和组合。
-
HTML:一个元素可以通过
class属性拥有多个类名,类名之间用空格分隔。 - CSS:可以通过将多个类选择器直接连接(中间没有空格)的方式,来精准选择同时拥有这些类的元素。
10..menu-item:not(.active):hover
为什么需要两个冒号?
这里要同时满足「两个条件」:
- 元素不是激活状态(
:not(.active)); - 元素正被鼠标悬停(
:hover)。
在 CSS 中,冒号 : 是用来表示「伪类(Pseudo-class)」的语法标志,它的作用是为选择器增加一个条件,只有满足该条件的元素才会被选中。
你可以把它理解为:
“冒号后面的内容,就是对前面选中的元素所施加的一个额外要求。”
关键点详解
-
冒号的作用:
- 它标识着一个伪类,用来描述元素的一种特殊状态或特定关系。
- 例如,
:hover表示 “鼠标悬停时” 的状态,:not(.active)表示 “不包含.active类” 的条件。
-
常见的伪类条件:
-
动态状态:
:hover(悬停)、:active(点击)、:focus(聚焦)。 -
否定条件:
:not(selector)(排除满足selector的元素)。 -
位置关系:
:first-child(第一个子元素)、:last-child(最后一个子元素)。 -
表单状态:
:checked(被选中)、:disabled(被禁用)。
-
动态状态:
-
多条件叠加:
- 你可以将多个伪类直接连接在一起,对元素施加多个同时存在的条件。
- 例如
.menu-item:not(.active):hover,就表示一个元素必须同时满足以下所有条件:- 是
.menu-item。 -
并且 不带有
.active类。 - 并且 正被鼠标悬停。
- 是
11.width:100%和100px的区别
一、父容器设定
我们设定两个父容器:
- 「大容器」:宽度 20 个字符(用
+------------------+表示,共 20 字符宽); - 「小容器」:宽度 10 个字符(用
+----------+表示,共 10 字符宽)。
二、width: 100px → 固定尺寸(用 10 个 # 模拟)
100px 是「固定宽度」,不管父容器多大 / 多小,子元素宽度永远不变(这里用 10 个 # 代表 100px 的宽度)。
场景 1:父容器是「大容器」(20 字符宽)
plaintext
父容器(大,20 字符宽):
+------------------+
| ########## | ← 子元素(10 个 #,对应 100px)
| | ← 左右留空隙(20-10=10 字符)
+------------------+
- 子元素宽度固定(10 个 #),父容器比它宽,所以左右会留空白。
场景 2:父容器是「小容器」(10 字符宽)
plaintext
父容器(小,10 字符宽):
+----------+
| ##########... | ← 子元素(10 个 #)超出父容器(10 字符),溢出部分用...表示
+----------+
- 子元素宽度固定(10 个 #),父容器不够宽,所以子元素会从右边 “露出来”(溢出)。
三、width: 100% → 自适应尺寸(用和父容器同宽的 # 模拟)
100% 是「跟随父容器宽度」,子元素宽度永远和父容器一致(父容器多少字符宽,子元素就用多少个 #)。
场景 1:父容器是「大容器」(20 字符宽)
plaintext
父容器(大,20 字符宽):
+------------------+
| ################## | ← 子元素(20 个 #,和父容器同宽)
+------------------+
- 子元素宽度 = 父容器宽度(20 字符),刚好填满父容器,不留空隙。
场景 2:父容器是「小容器」(10 字符宽)
plaintext
父容器(小,10 字符宽):
+----------+
| ########## | ← 子元素(10 个 #,和父容器同宽)
+----------+
- 子元素宽度 = 父容器宽度(10 字符),也刚好填满父容器,不溢出。
四、核心区别总结
| 特性 | width: 100px(固定尺寸) | width: 100%(自适应尺寸) |
|---|---|---|
| 比喻 | 「固定大小的积木」 | 「伸缩的橡皮筋」 |
| 父容器大时 | 子元素不变,留空隙 | 子元素变大,填满父容器 |
| 父容器小时 | 子元素不变,会溢出(或者换行) | 子元素变小,填满父容器 |
| 核心依赖 | 和父容器无关,自己固定 | 完全依赖父容器宽度 |
简单说:
-
100px是「死尺寸」,不管父容器怎么变,它都不变; -
100%是「活尺寸」,父容器变大它就变大,父容器变小它就变小,永远贴着父容器的边。
11.padding(不止控制内边距,还可以控制宽高)
当元素没有设置 width/height 时,padding 会通过 “增加内边距” 间接撑开元素的可视大小(看起来像影响了宽高,就效果来说这里也可以理解成可以控制宽高);同时,元素的点击区域是整个可视范围(包括 padding 的留白、内容本身、边框),留白只是点击区域的一部分,而非全部。
| padding 参数写法 | 对应方向(精准匹配) | 通俗理解(好记) |
|---|---|---|
| padding: 1px | 上 = 1px、右 = 1px、下 = 1px、左 = 1px | 1 个参数:上下左右全相同 |
| padding: 1px 2px | 上 = 1px、下 = 1px;左 = 2px、右 = 2px | 2 个参数:上下一组,左右一组 |
| padding: 1px 2px 3px | 上 = 1px;左 = 2px、右 = 2px;下 = 3px | 3 个参数:上 → 左右 → 下(左右一伙) |
| padding: 1px 2px 3px 4px | 上 = 1px、右 = 2px、下 = 3px、左 = 4px | 4 个参数:顺时针绕一圈(上→右→下→左) |
12.margin(不止控制外边距,还可以控制元素向上\下\左\右移动)
规则同padding
当然,想单独设置也可以
例如:margin-left:1px
13.background:transparent;
一般有一些样式(例如:按钮<button>,输入框<input> 等默认是自带背景色的,但是如果你希望你的元素下方的背景(页面背景、父容器背景)透出来,视觉上就像元素背景和页面背景一样了,你就可以用background:transparent;把原本样式自带的背景色变透明
后续在学习的过程中会慢慢补充......