CSS
一、CSS 选择器与优先级
1. CSS 选择器有哪些类型?
定义: CSS 选择器是用于选中 HTML 元素的模式,通过选择器可以将样式应用到对应的元素上。
选择器类型一览:
| 类型 | 语法 | 示例 | 说明 |
|---|---|---|---|
| 通配选择器 | * |
* { margin: 0; } |
选中所有元素 |
| 元素选择器 | element |
p { color: red; } |
选中所有指定标签 |
| 类选择器 | .class |
.active { font-weight: bold; } |
选中具有指定 class 的元素 |
| ID 选择器 | #id |
#header { background: #fff; } |
选中具有指定 id 的元素 |
| 属性选择器 | [attr]、[attr=value] |
input[type="text"] |
选中具有指定属性的元素 |
| 伪类选择器 | :pseudo-class |
a:hover, li:first-child |
选中元素的特定状态 |
| 伪元素选择器 | ::pseudo-element |
p::first-line, div::before |
选中元素的特定部分 |
| 后代选择器 | A B |
ul li |
选中 A 内部的所有 B |
| 子代选择器 | A > B |
ul > li |
选中 A 的直接子元素 B |
| 相邻兄弟选择器 | A + B |
h1 + p |
选中紧跟 A 后的 B |
| 通用兄弟选择器 | A ~ B |
h1 ~ p |
选中 A 后的所有同级 B |
详细示例:
css
/* 通配选择器 */
* { box-sizing: border-box; }
/* 元素选择器 */
p { color: #333; }
/* 类选择器 */
.btn-primary { background: #007bff; }
/* ID 选择器 */
#main-content { max-width: 1200px; }
/* 属性选择器 */
a[target="_blank"]::after { content: " \2197"; }
input[required] { border-left: 3px solid red; }
[class^="col-"] { float: left; } /* 以 col- 开头 */
[class$="-small"] { font-size: 12px; } /* 以 -small 结尾 */
[class*="grid"] { display: grid; } /* 包含 grid */
/* 伪类选择器 */
a:hover { text-decoration: underline; }
li:nth-child(odd) { background: #f5f5f5; }
input:focus { outline: 2px solid blue; }
p:first-of-type { font-size: 18px; }
/* 伪元素选择器 */
p::first-line { font-weight: bold; }
p::first-letter { font-size: 2em; }
.clearfix::after { content: ""; display: table; clear: both; }
/* 组合选择器 */
div > p { margin: 0; } /* 直接子元素 */
ul li a { color: blue; } /* 后代元素 */
h1 + p { font-size: 16px; } /* 相邻兄弟 */
h2 ~ p { color: gray; } /* 通用兄弟 */
常见误区:
- 过度使用 ID 选择器:导致样式难以覆盖和复用
- 选择器层级过深:影响性能且难以维护
- 伪类用单冒号
:,伪元素用双冒号::(CSS3 规范)
2. CSS 选择器优先级如何计算?
定义: CSS 优先级(Specificity)是浏览器决定当多个样式规则作用于同一元素时,哪个规则生效的算法。
优先级计算规则:
优先级按四位权重表示 (a, b, c, d),从左到右依次比较:
| 权重位 | 含义 | 示例 |
|---|---|---|
| a | 内联样式(style 属性) |
style="color: red;" |
| b | ID 选择器数量 | #header, #nav |
| c | 类/属性/伪类选择器数量 | .btn, [type], :hover |
| d | 元素/伪元素选择器数量 | div, ::before |
对比表格:
| 选择器 | a | b | c | d | 优先级值 |
|---|---|---|---|---|---|
* |
0 | 0 | 0 | 0 | 0,0,0,0 |
li |
0 | 0 | 0 | 1 | 0,0,0,1 |
li::first-line |
0 | 0 | 0 | 2 | 0,0,0,2 |
ul li |
0 | 0 | 0 | 2 | 0,0,0,2 |
.active |
0 | 0 | 1 | 0 | 0,0,1,0 |
ul ol + li |
0 | 0 | 0 | 3 | 0,0,0,3 |
h1 + *[rel=up] |
0 | 0 | 1 | 1 | 0,0,1,1 |
ul ol li.active |
0 | 0 | 1 | 3 | 0,0,1,3 |
#nav |
0 | 1 | 0 | 0 | 0,1,0,0 |
#nav .item |
0 | 1 | 1 | 0 | 0,1,1,0 |
style="" |
1 | 0 | 0 | 0 | 1,0,0,0 |
!important |
无限大 | - | - | - | 最高 |
优先级排序(从低到高):
less
通配符(*) < 元素/伪元素 < 类/属性/伪类 < ID选择器 < 内联样式 < !important
计算示例:
html
<div id="box" class="container active">
<p class="text">Hello</p>
</div>
css
/* 0,0,0,1 */
p { color: blue; }
/* 0,0,1,1 */
p.text { color: green; }
/* 0,1,0,0 */
#box p { color: red; }
/* 0,1,1,1 = 0,1,1,1 */
#box .container p { color: purple; }
/* 0,2,0,1 */
#box #box p { color: orange; }
/* !important 最高优先级 */
p { color: yellow !important; } /* 最终生效 */
!important 特殊规则:
!important的优先级高于一切(包括内联样式)- 多个
!important冲突时,按正常优先级比较 - 应尽量避免使用,仅在必要时使用
常见误区:
- 认为选择器写在后面就优先级高:只有在优先级相同时,后面的覆盖前面的
- 误以为
!important可以被后续规则覆盖:同样优先级的!important才遵循后写优先 - 组合选择器的优先级是累加的:
div.container p.text=0,0,2,2
二、盒模型与布局
3. CSS 盒模型是什么?它包含哪些部分?
定义: CSS 盒模型(Box Model)是 CSS 布局的基础概念,它将每个 HTML 元素视为一个矩形盒子,由内到外包含:内容(content)、内边距(padding)、边框(border)和外边距(margin)。
盒模型组成:
lua
+----------------------------- 外边距(margin) -----------------------------+
| +-------------------------- 边框(border) ---------------------------+ |
| | +--------------------- 内边距(padding) ----------------------+ | |
| | | +-----------------------------------------------------+ | | |
| | | | 内容(content) | | | |
| | | | width x height | | | |
| | | +-----------------------------------------------------+ | | |
| | +---------------------------------------------------------+ | |
| +-------------------------------------------------------------+ |
+---------------------------------------------------------------------+
各部分说明:
| 部分 | 说明 | 相关属性 |
|---|---|---|
| content | 元素的实际内容区域 | width, height |
| padding | 内容与边框之间的空间,背景色延伸至此 | padding-top/right/bottom/left |
| border | 围绕 padding 的边框 | border-width/style/color |
| margin | 元素与其他元素之间的空间,透明 | margin-top/right/bottom/left |
4. W3C 标准盒模型与 IE 盒模型的区别
定义 : CSS 中有两种盒模型计算方式,通过 box-sizing 属性控制。
对比表格:
| 特性 | W3C 标准盒模型(content-box) | IE 盒模型(border-box) |
|---|---|---|
box-sizing 值 |
content-box(默认) |
border-box |
width 含义 |
仅 content 宽度 | content + padding + border 总宽度 |
height 含义 |
仅 content 高度 | content + padding + border 总高度 |
| 实际占用宽度 | width + padding + border + margin |
width + margin |
| 实际占用高度 | height + padding + border + margin |
height + margin |
| 布局可预测性 | 差(需手动计算) | 好(所见即所得) |
计算示例:
css
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid black;
margin: 10px;
}
| 盒模型 | 内容宽度 | 总宽度(含 margin) | 总高度(含 margin) |
|---|---|---|---|
| content-box | 200px | 200+40+10+20 = 270px | 100+40+10+20 = 170px |
| border-box | 200-40-10 = 150px | 200+20 = 220px | 100+20 = 120px |
代码示例:
css
/* W3C 标准盒模型(默认) */
.standard-box {
box-sizing: content-box;
width: 300px; /* 内容区 300px */
}
/* IE 盒模型(推荐) */
.ie-box {
box-sizing: border-box;
width: 300px; /* 总宽度 300px(含 padding 和 border) */
}
/* 全局最佳实践:所有元素使用 border-box */
*, *::before, *::after {
box-sizing: border-box;
}
选择策略:
- 现代项目统一使用
border-box:布局更直观,不需要复杂计算 - 在 CSS 文件开头添加全局重置:
*, *::before, *::after { box-sizing: border-box; }
5. box-sizing 属性的作用及取值
定义 : box-sizing 属性用于控制元素的宽高计算方式。
取值说明:
| 值 | 说明 | 计算公式 |
|---|---|---|
content-box |
默认值,W3C 标准盒模型 | width/height 仅指 content 区域 |
border-box |
IE 盒模型,宽高包含 padding 和 border | width/height = content + padding + border |
inherit |
继承父元素的 box-sizing | - |
实际应用场景:
css
/* 场景:固定宽度容器,需要内边距 */
.container {
box-sizing: border-box;
width: 100%;
padding: 20px;
/* 实际内容宽度 = 100% - 40px */
}
/* 场景:输入框与按钮同宽对齐 */
.input, .button {
box-sizing: border-box;
width: 100%;
padding: 10px;
/* 两者总宽度一致,视觉上对齐 */
}
常见误区:
- 认为
padding和border会增加border-box的总宽度:不会,它们会压缩 content 区域 - 忘记在重置样式中设置全局
border-box:导致不同组件计算方式不一致
三、Flexbox 与 Grid 布局
6. Flex 布局的原理、属性及应用场景
定义: Flexbox(Flexible Box Layout)是一维布局模型,用于在容器内灵活分配空间和对齐元素。它通过弹性项目(flex items)在主轴(main axis)和交叉轴(cross axis)上的分布来实现布局。
工作原理:
- 父容器设置
display: flex或display: inline-flex后,直接子元素成为弹性项目 - 弹性项目可以自动伸展、收缩、对齐,无需使用浮动或定位
- 通过设置主轴方向,可以轻松实现水平或垂直布局
容器属性:
| 属性 | 说明 | 常用值 |
|---|---|---|
flex-direction |
主轴方向 | row(默认)、row-reverse、column、column-reverse |
flex-wrap |
是否换行 | nowrap(默认)、wrap、wrap-reverse |
flex-flow |
flex-direction + flex-wrap 简写 |
row wrap |
justify-content |
主轴对齐方式 | flex-start、flex-end、center、space-between、space-around、space-evenly |
align-items |
交叉轴对齐方式 | stretch(默认)、flex-start、flex-end、center、baseline |
align-content |
多行时交叉轴对齐 | flex-start、flex-end、center、space-between、space-around |
项目属性:
| 属性 | 说明 | 常用值 |
|---|---|---|
order |
排列顺序 | 数字(默认 0,越小越靠前) |
flex-grow |
放大比例 | 数字(默认 0,不放大) |
flex-shrink |
缩小比例 | 数字(默认 1,空间不足时缩小) |
flex-basis |
基准尺寸 | auto(默认)、长度值、0 |
flex |
grow + shrink + basis 简写 |
1 1 auto、1、none |
align-self |
单独设置交叉轴对齐 | 覆盖 align-items |
代码示例:
css
/* 场景1:水平垂直居中 */
.center-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* 场景2:导航栏布局 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
/* 场景3:等分栏布局 */
.equal-columns {
display: flex;
}
.equal-columns > .column {
flex: 1; /* 等分空间 */
}
/* 场景4:固定侧边栏 + 自适应内容 */
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px; /* 不放大、不缩小、固定 250px */
}
.main-content {
flex: 1 1 auto; /* 自动放大填充剩余空间 */
}
适用场景:
- 一维布局(单行或单列)
- 元素居中对齐
- 导航栏、工具栏
- 响应式卡片布局
- 表单元素对齐
常见误区:
flex只对直接子元素生效,不影响孙元素flex-shrink的计算基于超出空间的比例,不是固定值align-items和align-content不同:前者控制单行,后者控制多行
7. Grid 布局的特点和应用场景
定义: CSS Grid Layout 是二维布局系统,可以同时控制行和列。它将页面划分为网格容器(grid container)和网格项目(grid items),提供强大的布局能力。
工作原理:
- 父容器设置
display: grid或display: inline-grid - 通过
grid-template-columns和grid-template-rows定义网格轨道 - 项目可以通过
grid-column和grid-row指定跨越的网格区域
容器属性:
| 属性 | 说明 | 示例 |
|---|---|---|
grid-template-columns |
定义列 | 1fr 2fr 1fr、repeat(3, 1fr) |
grid-template-rows |
定义行 | 100px auto 100px |
grid-template-areas |
定义命名区域 | "header header" "sidebar main" "footer footer" |
grid-gap |
网格间距 | grid-gap: 20px; 或 gap: 20px; |
justify-items |
单元格内水平对齐 | start、end、center、stretch |
align-items |
单元格内垂直对齐 | start、end、center、stretch |
项目属性:
| 属性 | 说明 | 示例 |
|---|---|---|
grid-column |
跨越列 | 1 / 3、span 2 |
grid-row |
跨越行 | 1 / 2、span 2 |
grid-area |
命名区域 | header、main |
justify-self |
单元格内水平对齐 | 覆盖 justify-items |
align-self |
单元格内垂直对齐 | 覆盖 align-items |
代码示例:
css
/* 场景1:经典圣杯布局 */
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 场景2:响应式卡片布局 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
/* 场景3:等分网格 */
.equal-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 200px);
gap: 15px;
}
/* 场景4:项目跨越 */
.special-item {
grid-column: 1 / 3; /* 跨越第1-2列 */
grid-row: span 2; /* 跨越2行 */
}
适用场景:
- 二维布局(同时需要控制行和列)
- 复杂页面布局(页眉、侧边栏、主内容、页脚)
- 响应式卡片网格
- 需要元素跨越多个单元格
Flexbox vs Grid 对比:
| 维度 | Flexbox | Grid |
|---|---|---|
| 布局维度 | 一维(行或列) | 二维(行和列同时) |
| 适用场景 | 组件级布局 | 页面级布局 |
| 内容驱动 | 是(内容大小影响布局) | 否(先定义网格再放内容) |
| 学习成本 | 较低 | 较高 |
| 兼容性 | 优秀 | 现代浏览器支持良好 |
8. 圣杯布局的实现方式
定义: 圣杯布局(Holy Grail Layout)是一种经典的三栏布局,中间栏优先渲染且自适应宽度,两侧为固定宽度的侧边栏。
实现方案对比:
| 方案 | 技术 | 优点 | 缺点 |
|---|---|---|---|
| Flexbox | 弹性布局 | 简洁直观 | 旧浏览器不支持 |
| Grid | 网格布局 | 最简洁 | 旧浏览器不支持 |
| 浮动 + 负边距 | 传统方法 | 兼容性好 | 代码复杂 |
Flexbox 实现(推荐):
html
<div class="holy-grail">
<header>Header</header>
<div class="content">
<main>Main Content</main>
<aside class="left">Left Sidebar</aside>
<aside class="right">Right Sidebar</aside>
</div>
<footer>Footer</footer>
</div>
css
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
display: flex;
flex: 1;
}
main {
flex: 1; /* 自适应宽度 */
}
.left {
flex: 0 0 200px; /* 固定宽度 */
order: -1; /* 移到最左边 */
}
.right {
flex: 0 0 150px; /* 固定宽度 */
}
header, footer {
width: 100%;
}
Grid 实现(最简洁):
css
.holy-grail {
display: grid;
grid-template-columns: 200px 1fr 150px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"left main right"
"footer footer footer";
min-height: 100vh;
}
header { grid-area: header; }
main { grid-area: main; }
.left { grid-area: left; }
.right { grid-area: right; }
footer { grid-area: footer; }
浮动 + 负边距实现(传统兼容方案):
css
.content {
padding: 0 150px 0 200px; /* 为两侧留出空间 */
}
main, .left, .right {
float: left;
position: relative;
}
main {
width: 100%;
}
.left {
width: 200px;
margin-left: -100%; /* 移到最左边 */
right: 200px; /* 补偿 padding */
}
.right {
width: 150px;
margin-left: -150px; /* 移到最右边 */
}
四、响应式设计与移动端适配
9. 响应式设计的实现方法
定义: 响应式设计(Responsive Web Design, RWD)使网页能够根据设备屏幕尺寸自动调整布局,提供最佳浏览体验。
核心实现技术:
(1)视口设置(Viewport)
html
<!-- 必须设置:移动端适配基础 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">
(2)媒体查询(Media Queries)
css
/* 移动优先(Mobile First) */
/* 基础样式:移动端 */
.container {
width: 100%;
padding: 15px;
}
/* 平板设备 */
@media screen and (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
}
}
/* 桌面设备 */
@media screen and (min-width: 992px) {
.container {
max-width: 960px;
}
}
/* 大屏设备 */
@media screen and (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
/* 横屏检测 */
@media screen and (orientation: landscape) {
.container { max-width: 90vh; }
}
/* 高分辨率屏幕 */
@media screen and (-webkit-min-device-pixel-ratio: 2),
screen and (min-resolution: 192dpi) {
.logo { background-image: url("logo@2x.png"); }
}
常用断点参考:
| 设备 | 断点 | 说明 |
|---|---|---|
| 手机 | < 768px | 竖屏手机 |
| 平板 | 768px - 991px | iPad 等平板 |
| 桌面 | 992px - 1199px | 笔记本、台式 |
| 大屏 | >= 1200px | 大显示器 |
(3)相对单位使用
css
/* 使用相对单位 */
.box {
width: 50%; /* 相对于父元素 */
font-size: 1.2rem; /* 相对于根元素 */
padding: 2em; /* 相对于当前元素字号 */
margin: 5vw; /* 相对于视口宽度 */
}
(4)响应式图片
css
/* 图片自适应容器 */
img {
max-width: 100%;
height: auto;
}
/* 背景图响应式 */
.hero {
background-image: url("hero.jpg");
background-size: cover;
background-position: center;
}
html
<!-- HTML 响应式图片 -->
<picture>
<source media="(max-width: 480px)" srcset="mobile.jpg">
<source media="(max-width: 768px)" srcset="tablet.jpg">
<img src="desktop.jpg" alt="响应式图片">
</picture>
10. 移动端适配的常用方法
适配方法对比:
| 方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Viewport 适配 | 设置 viewport meta | 简单直接 | 仅控制缩放 | 所有移动端页面 |
| rem 适配 | 根据根字号缩放 | 统一比例 | 需计算 | 复杂移动页面 |
| vw/vh 适配 | 视口单位 | 天然响应 | 兼容性 | 现代项目 |
| 媒体查询 | 断点适配 | 灵活控制 | 断点维护 | 响应式网站 |
| 弹性布局 | Flexbox/Grid | 自动分配 | 学习成本 | 各类布局 |
rem 适配方案:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// 动态设置根字号(基于设计稿 375px)
const docEl = document.documentElement;
const fontSize = docEl.clientWidth / 375 * 100;
docEl.style.fontSize = fontSize + 'px';
</script>
</head>
<body>
<style>
/* 设计稿 100px = 1rem */
.header { height: 0.88rem; } /* 实际 88px */
.title { font-size: 0.32rem; } /* 实际 32px */
</style>
</body>
</html>
vw/vh 适配方案:
css
/* 基于设计稿 375px 宽度 */
.container {
width: 100vw;
padding: 4vw; /* 15px / 375px * 100 */
font-size: 4.27vw; /* 16px / 375px * 100 */
}
.card {
width: 48vw; /* 占屏幕宽度 48% */
height: 30vh; /* 占视口高度 30% */
margin: 1vw;
}
最佳实践:
- 移动优先:先写移动端样式,再用媒体查询逐步增强
- 避免固定宽度:使用百分比、
max-width等相对单位 - 测试多设备:使用浏览器 DevTools 的设备模拟器
五、CSS 动画与过渡
11. animation、transition、transform 的区别
定义对比:
| 特性 | transition |
animation |
transform |
|---|---|---|---|
| 定义 | 过渡效果,属性值变化时的平滑过渡 | 关键帧动画,可定义复杂多阶段动画 | 变换效果,不触发布局变化 |
| 触发方式 | 需要触发(hover、点击、JS) | 自动播放或 JS 控制 | 配合 transition/animation 使用 |
| 关键帧控制 | 不支持,只有起始和结束 | 支持 @keyframes 多阶段 |
不支持 |
| 可重复 | 单次 | 可无限循环(infinite) |
配合使用 |
| 暂停/恢复 | 困难 | 简单(animation-play-state) |
配合使用 |
| 性能 | 高(GPU 加速) | 高(GPU 加速) | 最高(GPU 加速) |
transition 详解:
css
/* 语法:transition: property duration timing-function delay; */
.button {
background: #007bff;
color: white;
/* 平滑过渡效果 */
transition: background 0.3s ease, color 0.3s ease;
}
.button:hover {
background: #0056b3;
color: #f0f0f0;
}
/* 简写:所有属性过渡 */
.card {
transition: all 0.3s ease;
}
animation 详解:
css
/* 定义关键帧 */
@keyframes slideIn {
0% {
transform: translateX(-100%);
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
/* 应用动画 */
.slide-element {
animation: slideIn 0.5s ease forwards;
/* animation-name | duration | timing-function | delay | iteration-count | direction | fill-mode | play-state */
}
/* 复杂动画:旋转 */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
transform 详解:
css
/* 位移 */
.element { transform: translate(50px, 100px); }
/* 缩放 */
.element { transform: scale(1.5); }
.element { transform: scaleX(2) scaleY(0.5); }
/* 旋转 */
.element { transform: rotate(45deg); }
.element { transform: rotateX(180deg); }
/* 倾斜 */
.element { transform: skew(10deg, 5deg); }
/* 组合变换 */
.element {
transform: translate(50px, 0) rotate(45deg) scale(1.2);
}
/* 3D 变换 */
.element {
transform: perspective(500px) rotateY(30deg);
}
/* 变换原点 */
.element {
transform-origin: center center; /* 默认 */
transform-origin: top left;
}
简单动画示例:
html
<div class="bounce-ball"></div>
css
/* 弹跳球动画 */
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-50px);
}
}
.bounce-ball {
width: 50px;
height: 50px;
background: #ff6b6b;
border-radius: 50%;
animation: bounce 1s ease-in-out infinite;
}
六、BFC 与浮动
12. 什么是 BFC?它有什么作用?
定义: BFC(Block Formatting Context,块级格式化上下文)是 Web 页面中一个独立的渲染区域,内部元素的布局不受外部影响,同时也不会影响外部元素。
原理:
- BFC 是一个独立的容器,内部元素按照特定规则布局
- BFC 内部和外部的元素不会相互影响(如 margin 折叠、浮动覆盖)
- 触发 BFC 的元素会创建一个隔离的布局环境
BFC 的触发条件:
| 条件 | 示例 |
|---|---|
根元素(<html>) |
默认触发 |
float 不为 none |
float: left/right |
position 为 absolute 或 fixed |
position: absolute |
display 为 inline-block、flex、grid、table-cell 等 |
display: flex |
overflow 不为 visible |
overflow: hidden/auto/scroll |
contain 为 layout、content、strict |
contain: layout |
BFC 的作用与应用场景:
(1)清除浮动(防止父元素高度塌陷)
css
/* 触发 BFC 清除浮动 */
.clearfix {
overflow: hidden; /* 或 overflow: auto */
}
/* 或使用伪元素方案 */
.clearfix::after {
content: "";
display: table;
clear: both;
}
(2)防止 Margin 折叠
html
<!-- 无 BFC:上下 margin 折叠,取较大值 -->
<div class="parent">
<div class="child1" style="margin-bottom: 30px;">内容1</div>
<div class="child2" style="margin-top: 20px;">内容2</div>
<!-- 实际间距:30px(不是 50px) -->
</div>
<!-- 有 BFC:margin 不折叠 -->
<div class="parent" style="overflow: hidden;">
<div class="child1" style="margin-bottom: 30px;">内容1</div>
<div class="bfc-wrapper" style="overflow: hidden;">
<div class="child2" style="margin-top: 20px;">内容2</div>
</div>
<!-- 实际间距:50px -->
</div>
(3)防止元素被浮动元素覆盖
css
/* 浮动元素旁边的自适应内容 */
.float-left {
float: left;
width: 200px;
}
.auto-content {
overflow: hidden; /* 触发 BFC,不会被浮动覆盖 */
/* 内容会自动填充剩余空间 */
}
13. 浮动与清除浮动的方法
定义: 浮动(Float)最初用于实现文字环绕图片效果,后来被广泛用于页面布局。浮动元素会脱离正常文档流,向左或向右移动直到碰到容器边缘或其他浮动元素。
浮动特性:
- 浮动元素脱离正常文档流,但仍在文本流中(文字会环绕)
- 父元素如果不设置高度,会出现高度塌陷
- 浮动元素之间不会重叠
清除浮动的必要性:
- 父元素高度塌陷:内部子元素浮动后,父元素高度变为 0
- 后续元素被影响:浮动元素会覆盖后续非浮动元素
清除浮动的常用方法:
方法 1:父元素触发 BFC(推荐简单场景)
css
.container {
overflow: hidden; /* 或 overflow: auto */
}
优点 :代码简洁 缺点:可能裁剪内容(如阴影、下拉菜单)
方法 2:额外空元素清除
html
<div class="container">
<div class="float-left">左浮动</div>
<div class="float-right">右浮动</div>
<div style="clear: both;"></div> <!-- 额外元素 -->
</div>
优点 :兼容性好 缺点:增加无意义 HTML 结构
方法 3:::after 伪元素清除(推荐)
css
.clearfix::after {
content: "";
display: table;
clear: both;
}
优点 :语义清晰,无额外 HTML 缺点:不支持 IE6-7
方法 4:双伪元素清除(最佳兼容方案)
css
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
.clearfix::after {
clear: both;
}
.clearfix {
*zoom: 1; /* IE6-7 兼容 */
}
现代最佳实践:
- 优先使用 Flexbox/Grid 布局,避免浮动
- 必须使用浮动时,采用
::after伪元素方案清除
七、元素居中方法
14. 如何实现元素的水平垂直居中?
定义: 水平垂直居中是前端开发中最常见的布局需求之一,有多种实现方式。
方法对比:
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Flexbox | 简洁、现代 | 旧浏览器不支持 | 推荐首选 |
| Grid | 最简洁 | 旧浏览器不支持 | 现代项目 |
| 定位 + transform | 无需知道尺寸 | 可能模糊(旧浏览器) | 通用方案 |
| 定位 + 负边距 | 兼容性好 | 需知道尺寸 | 固定尺寸元素 |
| 表格布局 | 兼容性好 | 语义不当 | 老项目兼容 |
方法 1:Flexbox(推荐):
css
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
min-height: 100vh;
}
方法 2:Grid(最简洁):
css
.parent {
display: grid;
place-items: center; /* 同时水平垂直居中 */
min-height: 100vh;
}
方法 3:定位 + transform:
css
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
方法 4:定位 + 负边距(需知道尺寸):
css
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin-top: -50px; /* -height/2 */
margin-left: -100px; /* -width/2 */
}
方法 5:表格布局:
css
.parent {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child {
display: inline-block;
}
仅水平居中方法:
css
/* 方法1:margin auto(块级元素) */
.child {
width: 200px;
margin: 0 auto;
}
/* 方法2:text-align(行内/行内块元素) */
.parent {
text-align: center;
}
/* 方法3:Flexbox */
.parent {
display: flex;
justify-content: center;
}
仅垂直居中方法:
css
/* 方法1:Flexbox */
.parent {
display: flex;
align-items: center;
}
/* 方法2:定位 + transform */
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* 方法3:line-height(单行文本) */
.parent {
height: 100px;
line-height: 100px;
}
八、position 定位属性
15. position 属性有哪些值?定位基准是什么?
定义 : position 属性控制元素的定位方式,决定元素在页面中的位置计算规则。
取值对比:
| 值 | 定位基准 | 是否脱离文档流 | top/right/bottom/left 有效 |
典型场景 |
|---|---|---|---|---|
static |
默认,正常流 | 否 | 否 | 默认值,一般不显式设置 |
relative |
相对于自身原位置 | 否(保留原位置) | 是 | 微调位置、作为 absolute 的参照 |
absolute |
最近的非 static 祖先 | 是 | 是 | 弹窗、图标、覆盖层 |
fixed |
相对于视口 | 是 | 是 | 固定导航栏、回到顶部 |
sticky |
相对于滚动容器 | 否(达到阈值后固定) | 是 | 吸顶导航、表头固定 |
代码示例:
css
/* relative:相对于自身偏移 */
.relative-box {
position: relative;
top: 10px; /* 向下偏移 10px */
left: 20px; /* 向右偏移 20px */
/* 原位置仍然保留,不影响其他元素 */
}
/* absolute:相对于最近的非 static 祖先 */
.parent {
position: relative; /* 创建定位上下文 */
}
.parent .child {
position: absolute;
top: 0;
right: 0;
/* 定位在父元素的右上角 */
}
/* fixed:相对于视口 */
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
/* 始终在屏幕顶部,不随滚动 */
}
/* sticky:滚动到阈值后固定 */
.sticky-header {
position: sticky;
top: 0;
/* 滚动到顶部时固定,否则正常流动 */
}
sticky 注意事项:
- 需要设置
top/bottom阈值才会生效 - 仅在直接滚动容器内生效
- 父元素
overflow: hidden/auto/scroll可能导致失效
九、display 属性与元素类型
16. display 属性的常用值及其作用
定义 : display 属性定义元素的显示类型,决定元素如何参与布局。
常用值一览:
| 值 | 类型 | 特点 | 示例 |
|---|---|---|---|
block |
块级 | 独占一行,可设宽高 | div, p, h1 |
inline |
行内 | 不独占一行,宽高由内容决定 | span, a, strong |
inline-block |
行内块 | 不换行但可设宽高 | img, input |
none |
隐藏 | 不显示,不占空间 | - |
flex |
弹性容器 | 启用 Flexbox 布局 | - |
inline-flex |
行内弹性容器 | 同 flex,但行内显示 | - |
grid |
网格容器 | 启用 Grid 布局 | - |
inline-grid |
行内网格容器 | 同 grid,但行内显示 | - |
table |
表格 | 类似 <table> |
- |
table-cell |
表格单元格 | 类似 <td> |
- |
list-item |
列表项 | 类似 <li> |
- |
17. 行内元素与块级元素的差异
对比表格:
| 特性 | 块级元素 | 行内元素 |
|---|---|---|
| 独占一行 | 是 | 否 |
| 可设置宽度/高度 | 是 | 否 |
margin 有效方向 |
上下左右 | 左右有效,上下不影响布局 |
padding 有效方向 |
上下左右 | 上下左右(但上下不影响其他元素布局) |
| 默认宽度 | 父元素 100% | 内容宽度 |
| 可包含子元素 | 块级和行内 | 一般只包含行内元素 |
| 垂直对齐 | 默认顶部对齐 | vertical-align 有效 |
常见标签:
html
<!-- 块级元素 -->
<div>, <p>, <h1>-<h6>, <ul>, <ol>, <li>, <table>, <form>,
<header>, <footer>, <section>, <article>, <nav>, <aside>
<!-- 行内元素 -->
<span>, <a>, <strong>, <em>, <b>, <i>, <code>, <img>,
<input>, <label>, <abbr>, <cite>
类型转换:
css
/* 行内转块级 */
a {
display: block;
width: 200px;
height: 40px;
}
/* 块级转行内 */
li {
display: inline;
}
/* 行内块(保留行内特性,可设宽高) */
span {
display: inline-block;
width: 100px;
height: 100px;
}
行内块元素的间隙问题:
html
<!-- HTML 中的换行和空格会导致间隙 -->
<button>按钮1</button>
<button>按钮2</button>
css
/* 解决方案1:父元素 font-size: 0 */
.parent {
font-size: 0;
}
.parent button {
font-size: 14px;
}
/* 解决方案2:使用 Flexbox */
.parent {
display: flex;
}
18. display: none 与 visibility: hidden 的区别
对比表格:
| 特性 | display: none |
visibility: hidden |
|---|---|---|
| 显示 | 不显示 | 不显示 |
| 占空间 | 否(脱离布局) | 是(保留占位) |
| 事件响应 | 无法点击 | 无法点击 |
| 子元素可显示 | 否(继承隐藏) | 是(visibility: visible 可覆盖) |
| 重排/重绘 | 触发重排 + 重绘 | 仅触发重绘 |
| 过渡动画 | 不支持 | 不支持(用 opacity 代替) |
代码示例:
css
/* display: none - 完全消失 */
.hidden {
display: none;
}
/* visibility: hidden - 隐藏但保留空间 */
.invisible {
visibility: hidden;
}
/* 子元素覆盖 visibility */
.parent {
visibility: hidden;
}
.parent .visible-child {
visibility: visible; /* 子元素可以显示 */
}
选择策略:
- 需要完全移除 元素时使用
display: none - 需要保留布局空间 时使用
visibility: hidden - 需要淡入淡出动画 时使用
opacity: 0配合transition
十、重绘与回流(性能优化)
19. 什么是重绘(Repaint)与回流(Reflow)?如何优化?
定义:
| 概念 | 定义 | 触发条件 | 性能消耗 |
|---|---|---|---|
| 回流(Reflow) | 元素尺寸、位置、布局发生变化,浏览器重新计算布局 | 增删 DOM、尺寸变化、位置变化、内容变化 | 高(需要重新计算布局) |
| 重绘(Repaint) | 元素外观变化但不影响布局,浏览器重新绘制 | 颜色、背景、阴影等视觉属性变化 | 低(仅重新绘制像素) |
回流触发场景:
css
/* 触发回流的属性 */
.box {
width: 200px; /* 尺寸变化 */
height: 100px;
margin: 20px; /* 位置变化 */
padding: 10px;
border: 2px solid; /* 边框变化 */
font-size: 16px; /* 字体大小 */
display: none; /* 显示/隐藏 */
position: absolute; /* 定位变化 */
top: 50px;
}
重绘触发场景:
css
/* 仅触发重绘的属性 */
.box {
color: red; /* 文字颜色 */
background: #fff; /* 背景色 */
box-shadow: 0 2px 4px; /* 阴影 */
outline: none; /* 外边框 */
visibility: hidden; /* 可见性(不占空间除外) */
}
优化策略:
(1)批量修改 DOM
javascript
// 坏:每次修改都触发回流
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';
// 好:一次性修改(使用 class 或 cssText)
element.style.cssText = 'width: 100px; height: 100px; margin: 10px;';
// 更好:使用 class
element.classList.add('new-style');
(2)使用 transform 替代位置属性
css
/* 坏:触发回流 */
.box {
top: 100px; /* 位置变化,触发回流 */
}
/* 好:使用 transform,触发合成(GPU 加速) */
.box {
transform: translateY(100px); /* 不触发回流 */
}
(3)脱离文档流
css
/* 动画元素使用 fixed/absolute 脱离文档流 */
.animated-element {
position: absolute;
/* 动画不会影响其他元素布局 */
}
(4)避免频繁读取布局属性
javascript
// 坏:读写交替,多次回流
element.style.width = '100px';
const width1 = element.offsetWidth; // 强制回流
element.style.height = '100px';
const height1 = element.offsetHeight; // 强制回流
// 好:集中读取,然后写入
const width1 = element.offsetWidth;
const height1 = element.offsetHeight;
element.style.width = '100px';
element.style.height = '100px';
(5)使用 will-change 提示浏览器
css
.animated {
will-change: transform, opacity; /* 提前优化 */
}
注意事项:
will-change不要滥用,仅在真正需要时使用- 动画优先使用
transform和opacity(合成属性) - 避免在滚动事件中执行触发布局的代码
十一、CSS 预处理器与命名规范
20. CSS 预处理器(Sass/Less)的使用
定义: CSS 预处理器是 CSS 的扩展语言,添加了变量、嵌套、混合、函数等编程特性,最终编译为标准 CSS。
Sass 与 Less 对比:
| 特性 | Sass (SCSS) | Less |
|---|---|---|
| 变量符号 | $ |
@ |
| 编译环境 | Ruby / Dart | Node.js |
| 混合指令 | @mixin / @include |
.mixin() |
| 继承 | @extend |
无原生支持 |
| 函数 | 内置丰富 | 内置较少 |
| 生态 | 更成熟 | 较简单 |
Sass 核心特性:
scss
/* 1. 变量 */
$primary-color: #007bff;
$font-size-base: 16px;
$spacing-unit: 8px;
/* 2. 嵌套 */
.navbar {
background: $primary-color;
padding: $spacing-unit * 2;
&__logo { /* BEM 命名 */
height: 40px;
}
&__item {
color: white;
&:hover {
opacity: 0.8;
}
}
}
/* 3. 混合(Mixin) */
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
@mixin responsive($breakpoint) {
@if $breakpoint == mobile {
@media (max-width: 767px) { @content; }
} @else if $breakpoint == tablet {
@media (min-width: 768px) { @content; }
}
}
.container {
@include flex-center;
@include responsive(mobile) {
padding: 10px;
}
}
/* 4. 继承 */
%button-base {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-primary {
@extend %button-base;
background: $primary-color;
color: white;
}
/* 5. 函数 */
@function px-to-rem($px) {
@return $px / $font-size-base * 1rem;
}
.card {
padding: px-to-rem(20);
}
21. BEM 等命名规范
定义: BEM(Block Element Modifier)是一种 CSS 命名方法论,旨在提高代码的可维护性和可读性。
命名规则:
| 部分 | 说明 | 命名格式 | 示例 |
|---|---|---|---|
| Block | 独立模块 | 小写字母,连字符分隔 | header, search-form |
| Element | 块内元素 | block__element |
header__logo, search-form__input |
| Modifier | 状态/变体 | block--modifier 或 block__element--modifier |
btn--primary, search-form__input--disabled |
代码示例:
html
<!-- BEM 命名示例 -->
<div class="card card--featured">
<img class="card__image" src="photo.jpg">
<div class="card__content">
<h3 class="card__title">标题</h3>
<p class="card__description">描述</p>
<button class="card__button card__button--primary">按钮</button>
</div>
</div>
css
/* Block */
.card {
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
/* Modifier */
.card--featured {
border-color: #ffc107;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* Element */
.card__image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card__content {
padding: 16px;
}
.card__title {
font-size: 18px;
margin-bottom: 8px;
}
/* Element with Modifier */
.card__button {
padding: 8px 16px;
border: none;
border-radius: 4px;
}
.card__button--primary {
background: #007bff;
color: white;
}
BEM 优势:
- 扁平选择器,避免嵌套过深
- 命名自解释,降低理解成本
- 模块独立,易于复用
十二、CSS3 新特性与伪类
22. CSS3 新增属性有哪些?
CSS3 核心新特性:
(1)选择器增强
css
/* 结构伪类 */
li:nth-child(2n) { background: #f5f5f5; } /* 偶数行 */
li:nth-of-type(3) { color: red; } /* 第3个同类 */
p:empty { display: none; } /* 空元素 */
input:disabled { opacity: 0.5; } /* 禁用状态 */
input:required { border-left: 3px solid red; } /* 必填字段 */
/* UI 伪类 */
a:visited { color: purple; }
button:active { transform: scale(0.95); }
(2)圆角与阴影
css
/* 圆角 */
.box {
border-radius: 10px;
border-radius: 50%; /* 圆形 */
border-radius: 10px 20px 30px 40px; /* 分别设置四个角 */
}
/* 盒阴影 */
.box {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); /* 内阴影 */
}
/* 文字阴影 */
.text {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
(3)渐变
css
/* 线性渐变 */
.linear-gradient {
background: linear-gradient(to right, #ff6b6b, #4ecdc4);
background: linear-gradient(45deg, red, blue);
background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.5));
}
/* 径向渐变 */
.radial-gradient {
background: radial-gradient(circle, #ff6b6b, #4ecdc4);
background: radial-gradient(ellipse at center, red, blue);
}
/* 圆锥渐变(较新) */
.conic-gradient {
background: conic-gradient(red, yellow, green, blue, red);
}
(4)多列布局
css
.columns {
column-count: 3; /* 列数 */
column-gap: 20px; /* 列间距 */
column-rule: 1px solid #ddd; /* 列分隔线 */
}
(5)transform 变换
css
/* 2D 变换 */
.element {
transform: translate(50px, 100px); /* 位移 */
transform: rotate(45deg); /* 旋转 */
transform: scale(1.5); /* 缩放 */
transform: skew(10deg); /* 倾斜 */
}
/* 3D 变换 */
.element-3d {
transform: perspective(500px) rotateY(30deg);
transform-style: preserve-3d;
}
(6)transition 过渡
css
.button {
background: #007bff;
transition: background 0.3s ease, transform 0.2s;
}
.button:hover {
background: #0056b3;
transform: translateY(-2px);
}
(7)animation 动画
css
@keyframes slideIn {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.animated {
animation: slideIn 0.5s ease forwards;
}
(8)opacity 透明度
css
.transparent {
opacity: 0.5; /* 0 = 完全透明, 1 = 完全不透明 */
}
23. CSS3 新增了哪些伪类?如何使用?
CSS3 新增伪类分类:
(1)结构伪类
| 伪类 | 说明 | 示例 |
|---|---|---|
:first-child |
第一个子元素 | li:first-child |
:last-child |
最后一个子元素 | li:last-child |
:nth-child(n) |
第 n 个子元素 | li:nth-child(2n) 偶数行 |
:nth-last-child(n) |
倒数第 n 个 | li:nth-last-child(3) |
:first-of-type |
同类第一个 | p:first-of-type |
:last-of-type |
同类最后一个 | p:last-of-type |
:nth-of-type(n) |
同类第 n 个 | p:nth-of-type(2) |
:only-child |
唯一子元素 | p:only-child |
:only-of-type |
同类唯一 | p:only-of-type |
css
/* 表格隔行变色 */
tr:nth-child(odd) { background: #f9f9f9; }
tr:nth-child(even) { background: #ffffff; }
/* 列表第一个和最后一个 */
li:first-child { border-top: none; }
li:last-child { border-bottom: none; }
/* 选中倒数第二个 */
.card:nth-last-child(2) { margin-bottom: 0; }
/* 前3个元素 */
.item:nth-child(-n+3) { font-weight: bold; }
/* 最后3个元素 */
.item:nth-last-child(-n+3) { border: none; }
(2)UI 状态伪类
| 伪类 | 说明 | 示例 |
|---|---|---|
:enabled |
启用状态 | input:enabled |
:disabled |
禁用状态 | input:disabled |
:checked |
选中状态 | input:checked |
:focus |
聚焦状态 | input:focus |
:hover |
悬停状态 | a:hover |
:active |
激活状态 | button:active |
:target |
锚点目标 | :target |
css
/* 复选框自定义样式 */
input[type="checkbox"]:checked + label::before {
content: "✓";
background: #007bff;
}
/* 禁用输入框样式 */
input:disabled {
background: #f5f5f5;
cursor: not-allowed;
}
/* 锚点目标高亮 */
section:target {
background: #fff3cd;
}
(3)否定伪类
css
/* 排除特定元素 */
p:not(.intro) { font-size: 14px; }
input:not([type="submit"]) { border: 1px solid #ddd; }
li:not(:last-child) { margin-bottom: 10px; }
十三、CSS 变量(自定义属性)
24. CSS 变量(自定义属性)的使用
定义: CSS 变量(Custom Properties)允许开发者在 CSS 中定义可复用的值,支持级联、继承和 JavaScript 动态修改。
语法:
- 定义:
--variable-name: value;(以--开头) - 使用:
var(--variable-name, fallback-value);
代码示例:
css
/* 1. 全局定义(通常在 :root) */
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--font-size-base: 16px;
--spacing-unit: 8px;
--border-radius: 4px;
--shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 2. 使用变量 */
.button {
background: var(--primary-color);
color: white;
padding: calc(var(--spacing-unit) * 2);
border-radius: var(--border-radius);
box-shadow: var(--shadow);
}
/* 3. 带回退值 */
.card {
background: var(--card-bg, #ffffff); /* 如果变量不存在,使用 #ffffff */
}
/* 4. 局部变量(覆盖全局) */
.dark-theme {
--primary-color: #333333;
--card-bg: #1a1a1a;
}
/* 5. 在 calc() 中使用 */
.container {
width: calc(100% - var(--spacing-unit) * 4);
}
JavaScript 操作 CSS 变量:
javascript
// 读取变量
const rootStyles = getComputedStyle(document.documentElement);
const primaryColor = rootStyles.getPropertyValue('--primary-color');
console.log(primaryColor.trim()); // "#007bff"
// 设置变量
document.documentElement.style.setProperty('--primary-color', '#ff6b6b');
// 删除变量
document.documentElement.style.removeProperty('--primary-color');
主题切换示例:
css
/* 默认主题 */
:root {
--bg-color: #ffffff;
--text-color: #333333;
}
/* 暗色主题 */
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #ffffff;
}
body {
background: var(--bg-color);
color: var(--text-color);
}
javascript
// 切换主题
function toggleTheme() {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
}
十四、其他实用技巧
25. 如何用 CSS 创建一个三角形?
原理 : 利用元素的 border 属性,将宽高设为 0,通过设置透明边框来创建三角形。
代码示例:
css
/* 向上三角形 */
.triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #007bff;
}
/* 向下三角形 */
.triangle-down {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 50px solid #007bff;
}
/* 向左三角形 */
.triangle-left {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-right: 50px solid #007bff;
}
/* 向右三角形 */
.triangle-right {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid #007bff;
}
等腰直角三角形:
css
/* 45度直角三角形 */
.right-triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 0 50px 50px 50px;
border-color: transparent transparent #007bff transparent;
}
常见应用场景:
- 下拉菜单箭头
- 提示框(Tooltip)指示箭头
- 对话框气泡
26. CSS Sprites(雪碧图)的原理
定义 : CSS Sprites 是将多个小图标合并成一张大图,通过 background-position 控制显示区域的技术,目的是减少 HTTP 请求次数。
原理:
- 将多个小图片拼接到一张大图中
- 通过设置容器宽高和
background-position显示特定区域 - 浏览器只需下载一次大图,而非多次下载小图
代码示例:
css
/* 图标容器基础样式 */
.icon {
display: inline-block;
background-image: url("sprites.png");
background-repeat: no-repeat;
}
/* 各个图标的位置 */
.icon-home {
width: 24px;
height: 24px;
background-position: 0 0;
}
.icon-user {
width: 24px;
height: 24px;
background-position: -24px 0;
}
.icon-search {
width: 24px;
height: 24px;
background-position: -48px 0;
}
html
<!-- 使用示例 -->
<span class="icon icon-home"></span>
<span class="icon icon-user"></span>
<span class="icon icon-search"></span>
优缺点:
| 优点 | 缺点 |
|---|---|
| 减少 HTTP 请求 | 制作和维护复杂 |
| 提高加载速度 | 大图体积可能过大 |
| 减少服务器压力 | 不适合大图或频繁变化的图标 |
现代替代方案:
- 使用 SVG Sprite(更灵活,支持矢量缩放)
- 使用 Icon Font(如 FontAwesome)
- 使用 HTTP/2(多路复用,减少请求优化效果不明显)
27. @import 指令的缺陷
定义 : @import 是 CSS 中引入外部样式表的方式,但存在明显的性能问题。
对比表格:
| 特性 | @import |
<link> |
|---|---|---|
| 加载方式 | 串行加载(先下载主 CSS,再下载 import 的 CSS) | 并行加载 |
| 加载性能 | 差(增加加载时间) | 好 |
| 优先级 | 低 | 高 |
| 兼容性 | 所有浏览器 | 所有浏览器 |
代码示例:
css
/* 使用 @import(不推荐) */
@import url("reset.css");
@import url("base.css");
@import url("components.css");
html
<!-- 使用 <link>(推荐) -->
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="components.css">
性能分析:
less
@import 加载流程:
HTML → 下载主 CSS → 解析发现 @import → 下载其他 CSS(串行)
<link> 加载流程:
HTML → 同时下载所有 CSS 文件(并行)
选择策略:
- 始终使用
<link>标签引入样式表 - 避免在 CSS 中使用
@import - 如果必须使用
@import,将其放在文件顶部(在其他规则之前)
28. CSS 属性简写规则
定义: CSS 简写(Shorthand)允许用一行代码设置多个相关属性,提高代码简洁性。
常用简写属性:
margin / padding
css
/* 四边相同 */
.box { margin: 10px; } /* 上下左右 10px */
/* 上下 / 左右 */
.box { margin: 10px 20px; } /* 上下 10px, 左右 20px */
/* 上 / 左右 / 下 */
.box { margin: 10px 20px 30px; } /* 上 10px, 左右 20px, 下 30px */
/* 上 / 右 / 下 / 左(顺时针) */
.box { margin: 10px 20px 30px 40px; }
记忆口诀 :上 → 右 → 下 → 左(顺时针方向)
border
css
/* 完整简写 */
.box { border: 2px solid #000; }
/* 单边 */
.box { border-top: 1px dashed red; }
background
css
/* 完整简写 */
.box {
background: #fff url("bg.png") no-repeat center / cover fixed;
/* background-color | background-image | background-repeat | background-position / background-size | background-attachment */
}
font
css
/* 简写:font-style font-variant font-weight font-size/line-height font-family */
.text {
font: italic bold 16px/1.5 "Microsoft YaHei", sans-serif;
}
transition
css
/* 简写:property duration timing-function delay */
.box {
transition: all 0.3s ease 0s;
transition: width 0.3s, height 0.3s; /* 多属性 */
}
animation
css
/* 简写:name duration timing-function delay iteration-count direction fill-mode play-state */
.box {
animation: slideIn 0.5s ease 0s 1 normal forwards;
}
常见误区:
-
简写会重置未指定的子属性为默认值
css/* 危险:会重置 border-style 为 solid */ .box { border-width: 2px; } .box { border: 2px; } /* border-style 被重置为 none */ -
font简写必须包含font-size和font-family,否则无效
29. margin 与 padding 的使用场景区别
对比表格:
| 特性 | margin |
padding |
|---|---|---|
| 定义 | 元素外边距,与其他元素的距离 | 元素内边距,内容与边框的距离 |
| 背景色 | 透明,不继承背景 | 继承元素背景色 |
| 百分比计算 | 相对于父元素宽度 | 相对于父元素宽度 |
| 负值 | 允许 | 不允许 |
| 折叠 | 垂直方向相邻 margin 会折叠 | 不会折叠 |
使用场景:
css
/* 使用 margin:控制元素之间的距离 */
.card {
margin-bottom: 20px; /* 卡片间距 */
}
.button + .button {
margin-left: 10px; /* 按钮间距 */
}
/* 使用 padding:控制内容与边框之间的距离 */
.card {
padding: 20px; /* 内容内边距 */
}
.input {
padding: 10px 15px; /* 输入框内文字间距 */
}
/* 背景色延伸到 padding,不延伸到 margin */
.box {
background: #f0f0f0; /* 背景色覆盖 padding 区域 */
padding: 20px;
margin: 20px; /* margin 区域透明 */
}
30. px 与 em 的区别
对比表格:
| 单位 | 定义 | 基准 | 特点 | 适用场景 |
|---|---|---|---|---|
px |
像素(绝对单位) | 屏幕像素 | 固定大小,不随用户设置变化 | 边框、阴影等精细控制 |
em |
相对单位 | 当前元素的 font-size |
相对大小,会继承和累积 | 内边距、行高等 |
rem |
相对单位 | 根元素(<html>)的 font-size |
相对大小,不会累积 | 字体大小、间距等全局控制 |
vw |
视口宽度百分比 | 视口宽度 | 响应式 | 响应式布局 |
vh |
视口高度百分比 | 视口高度 | 响应式 | 全屏布局 |
代码示例:
css
/* px:固定值 */
.box {
width: 200px;
border: 1px solid #000;
}
/* em:相对于当前元素字号 */
.parent {
font-size: 16px;
}
.child {
font-size: 1.5em; /* 16 * 1.5 = 24px */
padding: 1em; /* 24px(相对于自身字号) */
}
/* rem:相对于根元素字号 */
:root {
font-size: 16px;
}
.box {
font-size: 1rem; /* 16px */
padding: 1rem; /* 16px */
margin: 2rem; /* 32px */
}
/* em 的累积效应 */
.level1 { font-size: 1.2em; } /* 16 * 1.2 = 19.2px */
.level2 { font-size: 1.2em; } /* 19.2 * 1.2 = 23.04px */
最佳实践:
- 字体大小使用
rem:便于全局统一控制 - 间距使用
rem或em:保持比例关系 - 边框、阴影使用
px:保持清晰度
31. 图片导出格式的选择依据
格式对比:
| 格式 | 特点 | 压缩类型 | 透明度 | 动画 | 适用场景 |
|---|---|---|---|---|---|
| JPG | 色彩丰富,体积小 | 有损压缩 | 不支持 | 不支持 | 照片、复杂图像 |
| PNG-8 | 256色,体积小 | 无损压缩 | 支持(1位透明) | 不支持 | 简单图标、小图标 |
| PNG-24/32 | 真彩色,体积大 | 无损压缩 | 支持(Alpha透明) | 不支持 | Logo、需要高质量透明 |
| GIF | 256色,支持动画 | 无损压缩 | 支持 | 支持 | 简单动画、表情包 |
| WebP | 现代格式,体积小30% | 有损/无损 | 支持 | 支持 | 通用替代(推荐) |
| SVG | 矢量,无限缩放 | - | 支持 | 支持 | 图标、Logo、图表 |
| AVIF | 最新,压缩率最高 | 有损/无损 | 支持 | 支持 | 未来通用格式 |
选择策略:
html
<!-- 照片类:JPG 或 WebP -->
<img src="photo.webp" alt="照片">
<!-- Logo/图标:SVG -->
<img src="logo.svg" alt="Logo">
<!-- 需要透明的复杂图像:PNG-24 -->
<img src="hero.png" alt="英雄图">
<!-- 简单动画:GIF 或 WebP 动画 -->
<img src="loading.gif" alt="加载动画">
<!-- 响应式格式:优先使用现代格式 -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="图片">
</picture>
32. Div+CSS 布局对比 Table 布局的优势
对比表格:
| 维度 | Div+CSS 布局 | Table 布局 |
|---|---|---|
| 语义化 | 内容结构与样式分离 | 结构混入展示逻辑 |
| 加载速度 | 文件体积小,加载快 | 表格结构复杂,加载慢 |
| 维护性 | CSS 集中管理,易于维护 | 修改需改 HTML 结构 |
| SEO | 搜索引擎友好 | 搜索引擎不友好 |
| 响应式 | 易于实现响应式 | 固定结构,难以适配 |
| 可访问性 | 支持屏幕阅读器等辅助技术 | 表格仅用于表格数据 |
| 代码量 | 简洁 | 冗长(大量 <tr>, <td>) |
示例对比:
html
<!-- Table 布局(不推荐) -->
<table>
<tr>
<td width="200">侧边栏</td>
<td>主内容区域</td>
<td width="150">右侧栏</td>
</tr>
</table>
<!-- Div+CSS 布局(推荐) -->
<div class="layout">
<aside class="sidebar">侧边栏</aside>
<main class="main-content">主内容区域</main>
<aside class="right-sidebar">右侧栏</aside>
</div>
<style>
.layout {
display: flex;
}
.sidebar { flex: 0 0 200px; }
.main-content { flex: 1; }
.right-sidebar { flex: 0 0 150px; }
</style>
<table> 的正确使用场景:
- 仅用于展示表格数据(如财务报表、统计信息)
- 不应用于页面布局
33. 如何让 Chrome 浏览器显示小于 12px 的文字?
问题描述: Chrome 浏览器默认最小字体为 12px,小于 12px 的设置不生效。
解决方案:
方法 1:使用 transform: scale()(推荐)
css
.small-text {
font-size: 10px; /* 原始设置不生效 */
transform: scale(0.833); /* 10/12 = 0.833 */
transform-origin: left center; /* 缩放基点 */
display: inline-block; /* transform 对行内元素无效 */
}
方法 2:使用 -webkit-text-size-adjust
css
.small-text {
-webkit-text-size-adjust: none;
font-size: 10px;
}
注意:Chrome 47+ 已弃用此属性,不推荐依赖
方法 3:使用 zoom(仅 Webkit)
css
.small-text {
font-size: 12px;
zoom: 0.833; /* 整体缩放,包含布局 */
}
最佳实践:
- 优先使用
transform: scale()方案 - 考虑使用
rem单位替代绝对像素值 - 从设计角度,建议最小字体不小于 12px(可访问性考虑)
34. 重置 CSS 样式的原因及处理方法
定义: 重置 CSS(CSS Reset)是将所有浏览器默认样式统一,消除不同浏览器之间的样式差异。
为什么需要重置:
- 不同浏览器对 HTML 元素有不同的默认样式(margin、padding、字体等)
- 确保页面在所有浏览器中表现一致
- 避免浏览器默认样式干扰设计
常用重置方案:
方案 1:传统 Reset(Eric Meyer Reset)
css
/* http://meyerweb.com/eric/tools/css/reset/ */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
方案 2:Normalize.css(推荐)
Normalize.css 保留了有用的默认值,同时统一样式:
html
<!-- 引入 Normalize.css -->
<link rel="stylesheet" href="normalize.css">
css
/* Normalize.css 特点: */
/* 1. 保留有用的浏览器默认值 */
/* 2. 修复浏览器 Bug */
/* 3. 提高跨浏览器一致性 */
/* 4. 详细的注释说明 */
/* 示例:统一 HTML5 元素显示 */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, nav, section, summary {
display: block;
}
/* 示例:统一字体 */
body {
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
}
方案 3:现代轻量 Reset
css
/* 现代项目常用:仅重置关键属性 */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
line-height: 1.15;
-webkit-text-size-adjust: 100%;
}
body {
min-height: 100vh;
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%;
}
input, button, textarea, select {
font: inherit;
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
}
选择策略:
- 新项目推荐使用 Normalize.css 或现代轻量 Reset
- 需要完全统一时使用 Eric Meyer Reset
- 避免过度重置,保留有用的默认行为