重新学习前端之CSS

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;
  /* 两者总宽度一致,视觉上对齐 */
}

常见误区

  • 认为 paddingborder 会增加 border-box 的总宽度:不会,它们会压缩 content 区域
  • 忘记在重置样式中设置全局 border-box:导致不同组件计算方式不一致

三、Flexbox 与 Grid 布局

6. Flex 布局的原理、属性及应用场景

定义: Flexbox(Flexible Box Layout)是一维布局模型,用于在容器内灵活分配空间和对齐元素。它通过弹性项目(flex items)在主轴(main axis)和交叉轴(cross axis)上的分布来实现布局。

工作原理

  • 父容器设置 display: flexdisplay: inline-flex 后,直接子元素成为弹性项目
  • 弹性项目可以自动伸展、收缩、对齐,无需使用浮动或定位
  • 通过设置主轴方向,可以轻松实现水平或垂直布局

容器属性

属性 说明 常用值
flex-direction 主轴方向 row(默认)、row-reversecolumncolumn-reverse
flex-wrap 是否换行 nowrap(默认)、wrapwrap-reverse
flex-flow flex-direction + flex-wrap 简写 row wrap
justify-content 主轴对齐方式 flex-startflex-endcenterspace-betweenspace-aroundspace-evenly
align-items 交叉轴对齐方式 stretch(默认)、flex-startflex-endcenterbaseline
align-content 多行时交叉轴对齐 flex-startflex-endcenterspace-betweenspace-around

项目属性

属性 说明 常用值
order 排列顺序 数字(默认 0,越小越靠前)
flex-grow 放大比例 数字(默认 0,不放大)
flex-shrink 缩小比例 数字(默认 1,空间不足时缩小)
flex-basis 基准尺寸 auto(默认)、长度值、0
flex grow + shrink + basis 简写 1 1 auto1none
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-itemsalign-content 不同:前者控制单行,后者控制多行

7. Grid 布局的特点和应用场景

定义: CSS Grid Layout 是二维布局系统,可以同时控制行和列。它将页面划分为网格容器(grid container)和网格项目(grid items),提供强大的布局能力。

工作原理

  • 父容器设置 display: griddisplay: inline-grid
  • 通过 grid-template-columnsgrid-template-rows 定义网格轨道
  • 项目可以通过 grid-columngrid-row 指定跨越的网格区域

容器属性

属性 说明 示例
grid-template-columns 定义列 1fr 2fr 1frrepeat(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 单元格内水平对齐 startendcenterstretch
align-items 单元格内垂直对齐 startendcenterstretch

项目属性

属性 说明 示例
grid-column 跨越列 1 / 3span 2
grid-row 跨越行 1 / 2span 2
grid-area 命名区域 headermain
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. animationtransitiontransform 的区别

定义对比

特性 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
positionabsolutefixed position: absolute
displayinline-blockflexgridtable-cell display: flex
overflow 不为 visible overflow: hidden/auto/scroll
containlayoutcontentstrict 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: nonevisibility: 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 不要滥用,仅在真正需要时使用
  • 动画优先使用 transformopacity(合成属性)
  • 避免在滚动事件中执行触发布局的代码

十一、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--modifierblock__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-sizefont-family,否则无效


29. marginpadding 的使用场景区别

对比表格

特性 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. pxem 的区别

对比表格

单位 定义 基准 特点 适用场景
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:便于全局统一控制
  • 间距使用 remem:保持比例关系
  • 边框、阴影使用 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
  • 避免过度重置,保留有用的默认行为

相关推荐
walking9571 小时前
重新学习前端之Git
前端·vue.js·面试
walking9571 小时前
重新学习前端之小程序
前端
魔术师Grace1 小时前
AI让我退化成原始人了
前端·程序员
铁皮饭盒1 小时前
今天你会学到这些关键词
前端·后端
李剑一1 小时前
耗时 2 小时!我复刻了全网超火的通透 3D 水晶球动效,Vue3+Three.js 做出高级视觉特效
前端·three.js
oil欧哟1 小时前
🤔 很长时间没写文章了,分享一下最近的一些思考
前端·后端
Hello--_--World2 小时前
Vue指令:v-if vs v-show、v-if 与 v-for 的优先级冲突、自定义指令
前端·javascript·vue.js
神の愛2 小时前
ReactHooks
前端·javascript·react.js
蝎子莱莱爱打怪2 小时前
用好CC,事半功倍!Claude Code 命令大全,黄金命令推荐、多模型配置、实践指南、Hooks 和踩坑记录大全
前端·人工智能·后端