常见的CSS选择器
-
元素选择器 :如
p,选中所有<p>元素。 -
类选择器 :如
.class,选中所有class="class"的元素。 -
ID 选择器 :如
#id,选中id="id"的唯一元素。 -
后代选择器 :如
div p,选中div内所有后代<p>元素。 -
子选择器 :如
div > p,选中div的直接子元素<p>。 -
相邻兄弟选择器 :如
h1 + p,选中紧接在<h1>后的<p>。 -
通用兄弟选择器 :如
h1 ~ p,选中<h1>之后所有同级<p>。 -
属性选择器 :如
[type="text"],选中具有指定属性的元素。 -
伪类选择器 :如
:hover、:nth-child(2),选中特定状态或位置的元素。 -
通配符选择器 :
*,匹配所有元素。 -
元素(类型)选择器
csselement { }示例:
p { color: blue; }--- 选中所有<p>元素。 -
类选择器
css.classname { }示例:
.btn { font-weight: bold; }--- 选中所有class="btn"的元素。 -
ID 选择器
css#idname { }示例:
#header { background: #fff; }--- 选中id="header"的唯一元素。 -
后代选择器
cssancestor descendant { }示例:
div p { margin: 0; }--- 选中所有在div内的<p>(不限层级)。 -
子选择器
cssparent > child { }示例:
ul > li { list-style: none; }--- 仅选中ul的直接子元素<li>。 -
相邻兄弟选择器
csselement + sibling { }示例:
h2 + p { margin-top: 0; }--- 选中紧跟在<h2>后的同级<p>。 -
通用兄弟选择器
csselement ~ siblings { }示例:
h2 ~ p { color: gray; }--- 选中<h2>之后所有同级<p>。 -
属性选择器
css[attribute] { } [attribute="value"] { } [attribute^="value"] { } /* 以 value 开头 */ [attribute$="value"] { } /* 以 value 结尾 */ [attribute*="value"] { } /* 包含 value */示例:
input[type="text"] { width: 100%; } -
伪类选择器
csselement:pseudo-class { }常见示例:
a:hover { color: red; }li:nth-child(2) { font-weight: bold; }input:focus { outline: none; }
-
通配符选择器
css* { }示例:
* { box-sizing: border-box; }--- 应用于所有元素。
如何计算CSS的优先级
CSS 优先级(Specificity)决定了当多个规则同时作用于一个元素时,哪条规则最终生效。其计算遵循以下规则(从高到低):
一、优先级层级(权重)
每条 CSS 规则的选择器按以下四部分计算权重,格式为:
(内联, ID, 类/属性/伪类, 元素/伪元素)
| 类型 | 权重值(每出现一次) |
|---|---|
内联样式 (style="") |
1,0,0,0 |
ID 选择器 (#id) |
0,1,0,0 |
类选择器 (.class)、属性选择器 ([type])、伪类 (:hover) |
0,0,1,0 |
元素选择器 (div)、伪元素 (::before) |
0,0,0,1 |
通配符 (*)、组合符(如 >, +, ~) |
0,0,0,0(无影响) |
注意 :
!important优先级最高,会覆盖所有其他规则(包括内联),但应慎用。
二、计算示例
#nav .item a:hover
→ 1 个 ID + 1 个类 + 1 个伪类 + 1 个元素
→ (0,1,2,1)div.container p
→ 1 个类 + 2 个元素
→ (0,0,1,2)style="color: red"(内联)
→ (1,0,0,0)* { margin: 0 }
→ (0,0,0,0)(最低)
三、比较规则
- 从左到右逐位比较:高位优先 。
例如:(0,1,0,0) > (0,0,10,10)(ID 胜过任意多个类和元素)。 - 如果优先级相同,则后定义的规则生效(遵循"层叠"原则)。
四、快速口诀
内联 > ID > 类/属性/伪类 > 元素
!important最强,但别滥用!
CSS中可继承和不可继承的属性有哪些
在 CSS 中,继承(inheritance) 是指子元素自动获得父元素的某些样式属性值。但并非所有属性都可继承。以下是常见分类(言简意赅):
✅ 可继承的属性(常见)
这些属性默认会从父元素继承到子元素:
- 文本相关
colorfont-family,font-size,font-weight,font-style,fontline-heighttext-align,text-indent,text-transform,letter-spacing,word-spacingwhite-space,direction,unicode-bidi
- 列表相关
list-style,list-style-type,list-style-position,list-style-image
- 其他
visibilitycursorborder-collapse(仅限表格)
💡 可继承属性若未显式设置,会自动取
inherit值。
❌ 不可继承的属性(常见)
这些属性不会自动继承,子元素需显式设置:
- 盒模型相关
width,height,margin,padding,border,display,box-sizing
- 定位与布局
position,top/left/right/bottom,float,clear,z-indexflex,grid,align-items,justify-content等布局属性
- 背景
background,background-color,background-image等
- 其他
overflow,vertical-align,text-decoration,outlinetransform,animation,transition
💡 不可继承属性的默认值通常是
initial(如margin: 0),而非父元素的值。
⚠️ 特殊说明
-
所有属性都可以通过显式设置
inherit值强制继承:
css.child { margin: inherit; } -
使用
all: inherit可让元素继承所有属性(慎用)。
✅ 记忆技巧:
"文字可继承,盒子不继承" ------ 与文本排版相关的通常可继承,与布局、尺寸、装饰相关的通常不可继承。
display属性的值及其作用
CSS 的 display 属性用于控制元素的显示类型和布局行为,是布局的核心属性之一。以下是常见值及其作用:
🔹 常见 display 值及作用
| 值 | 作用说明 |
|---|---|
block |
元素表现为块级元素 : • 独占一行 • 可设置宽高、内外边距 • 默认宽度为父容器 100% (如 <div>, <p>) |
inline |
元素表现为行内元素 : • 不换行,与其他行内元素在同一行 • 不能 设置宽高、上下 margin/padding 无效 (如 <span>, <a>) |
inline-block |
行内块元素 : • 像 inline 一样不换行 • 像 block 一样可设置宽高和所有方向的 margin/padding (常用于水平排列的按钮、图标) |
none |
完全隐藏元素 : • 不占据任何空间(与 visibility: hidden 不同) • 子元素也一并隐藏 |
flex |
创建**弹性盒布局(Flexbox)**容器: • 子元素成为 flex 项目 • 支持主轴/交叉轴对齐、伸缩等强大布局能力 |
inline-flex |
行内级的 flex 容器: • 行为类似 inline-block,但内部使用 flex 布局 |
grid |
创建**网格布局(Grid)**容器: • 子元素按行/列网格排列 • 适合二维布局 |
inline-grid |
行内级的 grid 容器 |
table , table-row , table-cell 等 |
模拟 HTML 表格布局行为(不推荐用于非表格内容) |
contents |
元素自身不生成盒子,但子元素正常渲染(仿佛"消失"了,仅保留内容) |
list-item |
像 <li> 一样显示:块级 + 项目符号(可配合 list-style) |
利用css隐藏元素的方法有哪些
在 CSS 中,有多种方式可以"隐藏"元素,但它们的行为和效果完全不同。以下是常见方法及其特点(言简意赅):
✅ 1. display: none
css
.element { display: none; }
- 完全移除元素(不渲染)
- 不占据任何空间
- 子元素也被隐藏
- 无法通过 JavaScript 获取尺寸 (如
offsetWidth为 0) - 最彻底的隐藏
⚠️ 页面重排(reflow)会发生
✅ 2. visibility: hidden
css
.element { visibility: hidden; }
- 元素不可见 ,但仍占据空间
- 子元素默认也隐藏,但可单独设
visibility: visible覆盖 - 可响应事件 (如点击,除非指定了
pointer-events: none) - 不影响布局流
⚠️ 仅视觉隐藏,布局保留
✅ 3. opacity: 0
css
.element { opacity: 0; }
- 元素完全透明 ,但仍占据空间
- 可交互(能点击、聚焦等)
- 常用于过渡动画(如淡入淡出)
- 可配合
pointer-events: none禁用交互
✅ 4. 移出可视区域(视觉隐藏)
css
.element {
position: absolute;
left: -9999px;
top: -9999px;
}
/* 或 */
.element {
clip: rect(0, 0, 0, 0);
clip-path: inset(50%);
position: absolute;
white-space: nowrap;
width: 1px;
height: 1px;
overflow: hidden;
}
- 元素不在屏幕显示 ,但仍存在于 DOM
- 保留语义 ,对屏幕阅读器友好(适合"仅视觉隐藏,但保留无障碍访问")
- 常用于隐藏表单标签、跳转链接等
✅ 推荐无障碍场景使用(如
.sr-only类)
✅ 5. height: 0; overflow: hidden
css
.element {
height: 0;
overflow: hidden;
}
- 隐藏内容且不占高度
- 若有
padding/border仍会占空间,需一并设为 0 - 不如
display: none彻底
✅ 6. transform: scale(0) 或 translateX(-100%)
css
.element { transform: scale(0); }
- 元素被缩放或移出,仍占据原始空间(transform 不影响布局)
- 可交互 (除非配合
pointer-events: none) - 常用于动画隐藏
🆚 对比总结
| 方法 | 占据空间? | 可交互? | 屏幕阅读器可读? | 触发布局重排? |
|---|---|---|---|---|
display: none |
❌ | ❌ | ❌ | ✅ |
visibility: hidden |
✅ | ✅(默认) | ❌ | ❌ |
opacity: 0 |
✅ | ✅ | ✅ | ❌ |
移出视区(如 left: -9999px) |
✅(但视觉不可见) | ✅ | ✅ | ❌ |
height: 0 + overflow: hidden |
❌(需清 padding/border) | ❌ | ✅ | ✅ |
transform 隐藏 |
✅(布局位置不变) | ✅ | ✅ | ❌ |
使用link和@import引用css的区别
在 HTML/CSS 中,<link> 和 @import 都可以用来引入外部样式表,但它们在本质、性能、兼容性、加载行为等方面有显著区别。以下是核心对比(言简意赅):
🔹 1. 本质不同
| 方式 | 类型 | 说明 |
|---|---|---|
<link> |
HTML 标签 | 属于 HTML 文档结构的一部分 |
@import |
CSS 规则 | 必须写在 CSS 文件或 <style> 标签内部 |
html
<!-- HTML 中使用 link -->
<link rel="stylesheet" href="style.css">
<!-- CSS 中使用 @import -->
<style>
@import url("style.css");
</style>
🔹 2. 加载与渲染行为(关键区别)
<link> |
@import |
|
|---|---|---|
| 并行加载 | ✅ 支持多个 CSS 并行下载 | ❌ 串行加载(必须等当前 CSS 解析完才加载 @import 的文件) |
| 阻塞渲染 | 阻塞,但可并行解析 | 更严重阻塞:主 CSS 下载 → 解析 → 再下载 @import → 再解析 |
| FOUC 风险 | 低 | 高(尤其在旧浏览器中可能出现"无样式内容闪烁") |
📌 性能建议 :
<link>加载更快,推荐用于关键样式。
🔹 3. 兼容性
<link>:所有浏览器都支持(包括非常老的 IE)@import:IE5+ 支持,但 IE6-8 中有严重性能问题(会阻塞页面渲染更久)
✅ 总结口诀:
<link>是 HTML 的"亲儿子",加载快、性能好;
@import是 CSS 的"内部工具",适合模块化,慎用于主文档。
优先用 <link>,让页面更快呈现!
transition和animation的区别
transition 和 animation 都是 CSS 中实现动态效果 的重要属性,但它们的用途、语法和能力有本质区别。
🔹 1. 触发方式不同
| 属性 | 触发条件 |
|---|---|
transition |
需要状态变化 (如 :hover、focus、JS 修改 class)才能触发 |
animation |
自动播放(页面加载后即可开始,无需状态变化) |
css
/* transition:只有 hover 时才动 */
.box {
width: 100px;
transition: width 0.3s;
}
.box:hover { width: 200px; }
/* animation:页面加载后自动动 */
.box {
animation: slide 2s infinite;
}
@keyframes slide {
from { transform: translateX(0); }
to { transform: translateX(100px); }
}
🔹 2. 控制能力不同
| 能力 | transition |
animation |
|---|---|---|
| 关键帧控制 | ❌ 仅支持"开始 ↔ 结束"两个状态 | ✅ 支持多关键帧(@keyframes) |
| 循环播放 | ❌ 不能循环 | ✅ 支持 infinite、animation-iteration-count |
| 方向/延迟/速度曲线 | ✅ 支持(ease, delay 等) |
✅ 更丰富(animation-direction, animation-play-state 等) |
| 暂停/恢复 | ❌ 无法暂停 | ✅ 可用 animation-play-state: paused 控制 |
🔹 3. 语法复杂度
-
transition:简单,一行搞定csstransition: property duration timing-function delay; /* 例:transition: opacity 0.5s ease-in 0.1s; */ -
animation:需配合@keyframes,更复杂但更强大cssanimation: name duration timing-function delay iteration-count direction; @keyframes name { /* 定义关键帧 */ }
🔹 4. 适用场景
| 场景 | 推荐属性 |
|---|---|
| 按钮 hover 效果、开关切换 | ✅ transition |
| 加载动画、轮播、复杂路径运动 | ✅ animation |
| 简单状态过渡(如颜色、大小变化) | ✅ transition |
| 需要精确控制中间过程(如弹跳、呼吸效果) | ✅ animation |
✅ 总结对比表
| 特性 | transition |
animation |
|---|---|---|
| 触发方式 | 依赖状态变化 | 自动播放 |
| 关键帧 | 仅起止两点 | 多关键帧(@keyframes) |
| 循环 | 不支持 | 支持 |
| 暂停/控制 | 不支持 | 支持(play-state) |
| 性能 | 轻量 | 稍重(但现代浏览器优化良好) |
| 典型用途 | 交互反馈(hover/focus) | 装饰性动画、复杂动效 |
transition是"响应式变化",animation是"主动表演"。简单交互用
transition,复杂动效用animation。
两者可结合使用,但通常不作用于同一属性,以免冲突。
对盒模型的理解
CSS 盒模型(Box Model)是布局的基础核心概念,它描述了 HTML 元素在页面中如何占据空间------每个元素都被视为一个"盒子",由四个部分组成:
一、盒模型的四个组成部分(由内到外)
| 部分 | 说明 |
|---|---|
| content(内容区) | 实际内容(文本、图片等),由 width / height 控制大小 |
| padding(内边距) | 内容与边框之间的空白,背景色/图会延伸至此 |
| border(边框) | 围绕 padding 的边界线,可设置宽度、样式、颜色 |
| margin(外边距) | 盒子与其他元素之间的透明间距,不占背景,可为负值 |
+---------------------------+
| margin |
| +---------------------+ |
| | border | |
| | +---------------+ | |
| | | padding | | |
| | | +---------+ | | |
| | | | content | | | |
| | | +---------+ | | |
| | +---------------+ | |
| +---------------------+ |
+---------------------------+
二、盒模型的两种计算方式
1. 标准盒模型(content-box)(默认)
width/height仅指 content 区域- 元素总宽度 =
width + padding-left + padding-right + border-left + border-right + margin-left + margin-right - 缺点:设置固定宽度后,加 padding/border 会撑大盒子
2. IE 盒模型(border-box)
width/height包含 content + padding + border- 元素总宽度 =
width + margin-left + margin-right - 优点:更符合直觉,布局更可控
✅ 推荐全局重置:
css
*, *::before, *::after {
box-sizing: border-box;
}
三、相关 CSS 属性
| 属性 | 说明 |
|---|---|
width / height |
内容区或整个盒子的尺寸(取决于 box-sizing) |
padding / margin |
支持 top/right/bottom/left 四方向 |
border |
如 border: 1px solid #000 |
box-sizing |
控制盒模型类型:content-box(默认)或 border-box |
四、常见问题与技巧
- 外边距合并(Margin Collapse) :
相邻块级元素的上下 margin 会合并为较大者(非叠加),父子元素也可能发生。 - 100% 宽度 + padding 溢出?
使用box-sizing: border-box可避免。 - 获取实际尺寸(JS) :
offsetWidth= content + padding + borderclientWidth= content + paddingscrollWidth= 实际内容宽度(含溢出)
✅ 总结
盒模型 = 内容 + 内边距 + 边框 + 外边距
用box-sizing: border-box让布局更简单可靠
为什么有时候用translate来改变位置
使用 transform: translate() 来改变元素位置,而不是传统的 top/left、margin 或 position,主要有以下几个关键原因:
✅ 1. 性能更高(GPU 加速)
translate()属于 合成(compositing)属性 ,浏览器会将其交给 GPU 处理 ,不触发重排(reflow)和重绘(repaint),只触发合成(composite)。- 而修改
top/left(配合position: absolute)会触发 重排 → 重绘 → 合成,性能开销大。
📌 尤其在动画 或频繁移动 场景下,
translate更流畅。
✅ 2. 不影响文档流
translate()不会改变元素在文档流中的原始位置 ,其他元素不会重新布局。- 而用
margin或position移动元素,可能会影响周围元素的位置(如margin会推挤邻居,relative仍占原位但视觉偏移)。
html
<div class="box">A</div>
<div class="box">B</div>
.box {
width: 100px; height: 50px;
background: lightblue;
}
/* 用 translate:B 不动 */
.box:first-child { transform: translateX(50px); }
/* 用 margin-left:B 会被挤开 */
/* .box:first-child { margin-left: 50px; } */
✅ 3. 更精确的像素控制(避免亚像素问题)
translate()支持小数(如translateX(0.5px)),在高分辨率屏幕下能实现更平滑的动画。- 某些情况下,
top: 10.5px可能被浏览器舍入为整数,而translate保留亚像素精度。
✅ 4. 便于做高性能动画
- 配合
transition或animation,translate是推荐的位移动画方式。 - 浏览器对其做了深度优化(如创建独立图层)。
css
.element {
transition: transform 0.3s;
}
.element:hover {
transform: translateX(10px); /* 推荐 */
/* 而不是 left: 10px; */
}
✅ 5. 居中定位更简洁
-
经典垂直水平居中:
css.center { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* 精准居中,无论宽高 */ }比
margin: -height/2 0 0 -width/2更灵活(无需知道具体尺寸)。
⚠️ 注意事项
| 场景 | 是否适合用 translate |
|---|---|
| 需要真正改变布局位置(如让其他元素"让位") | ❌ 不适合 |
| 仅做视觉偏移、动画、悬停效果 | ✅ 非常适合 |
| 需要响应式或动态尺寸居中 | ✅ 推荐 |
| 元素需被屏幕阅读器按新位置理解 | ❌ translate 不改变语义位置(无障碍需额外处理) |
重排和文档流
在 CSS 和浏览器渲染机制中,重排(Reflow) 和 文档流(Document Flow) 是两个核心但常被混淆的概念。下面分别清晰解释:
一、文档流(Document Flow)------也常被误称为"文本流"
✅ 正确术语是 "文档流" (Document Flow),不是"文本流"。
它指的是 HTML 元素在页面中默认的布局排列方式。
🔹 什么是文档流?
- 浏览器按照 HTML 代码顺序,从上到下、从左到右依次摆放元素。
- 块级元素(如
<div>、<p>)独占一行,垂直堆叠; - 行内元素(如
<span>、<a>)在同一行内水平排列,直到放不下才换行。
🔹 脱离文档流
某些 CSS 属性会让元素脱离正常文档流,不再影响其他元素布局:
position: absolute/fixedfloat: left/rightdisplay: nonetransform(视觉上偏移,但仍占原始位置 ,不算完全脱离)
💡 关键点:在文档流中的元素会"互相影响位置";脱离后,其他元素会当作它"不存在"来布局。
二、重排(Reflow)------也叫"回流"
重排 = 重新计算元素的几何位置和尺寸,并重建页面布局
🔹 什么会触发重排?
当影响布局的属性发生变化时,浏览器必须重新计算:
- 改变
width/height/padding/margin/border - 改变
position/display/float - 添加/删除 DOM 元素
- 调整窗口大小、字体大小、滚动
- 读取某些布局属性(如
offsetWidth,clientHeight)也会强制触发重排
🔹 重排的代价
- 性能开销大:涉及整个或部分页面的重新布局
- 会触发重绘(Repaint):位置变了,自然要重新画
- 频繁重排会导致页面卡顿
为什么li与li元素之间有看不见的空白间隙 如何解决
<li> 元素之间出现看不见的空白间隙 ,其实根源不在 <li> 本身,而在于它的父元素------通常是 <ul> 或 <ol> ------当 <li> 被设置为 display: inline 或 inline-block 时,才会暴露出这个问题。
❓那为什么网上常说 "<li> 之间有空白间隙"?
这是因为:只有当 <li> 被设置为 display: inline 或 display: inline-block 时,才会触发"空白符被渲染为间隙"的问题。
举个典型场景(导航菜单):
<ul>
<li>首页</li>
<li>关于</li>
<li>联系</li>
</ul>
li {
display: inline-block; /* 想让 li 水平排列 */
padding: 10px;
background: #ccc;
}
这时候,HTML 中 <li> 标签之间的换行和空格 会被浏览器当作一个空格字符 ,显示在两个 inline-block 元素之间,看起来就像"莫名其妙的间隙"。
🔍 问题本质:HTML 中的空白符(Whitespace)被渲染
当多个 行内(inline)或行内块(inline-block)元素 写在 HTML 中时,元素之间的换行符、空格、制表符 会被浏览器当作一个空格字符渲染,从而产生间隙。
html
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
如果 CSS 设置:
css
li {
display: inline-block;
}
那么浏览器实际渲染效果类似于:
html
<li>Item 1</li> <li>Item 2</li> <li>Item 3</li>
<!-- ↑ 这个空格就是间隙来源 -->
✅ 解决方案(任选其一)
方法 1:删除 HTML 中的空白符(不推荐,可读性差)
html
<ul>
<li>Item 1</li><li>Item 2</li><li>Item 3</li>
</ul>
或
html
<ul>
<li>Item 1</li
><li>Item 2</li
><li>Item 3</li>
</ul>
方法 2:设置父元素 font-size: 0,子元素重置字体
css
ul {
font-size: 0; /* 消除空格宽度 */
}
li {
display: inline-block;
font-size: 16px; /* 恢复文字大小 */
}
✅ 简单有效,兼容性好,最常用方案之一
方法 3:使用 Flexbox 布局(推荐现代方案)
css
ul {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
li {
/* 不需要 display: inline-block */
}
✅ 无间隙、语义清晰、响应式友好,强烈推荐用于新项目
方法 4:设置 letter-spacing 或 word-spacing 为负值(不推荐)
css
ul {
letter-spacing: -4px;
}
li {
letter-spacing: normal;
}
⚠️ 数值需调试,不同字体表现不一,易出问题
方法 5:使用注释消除空白(折中)
html
<ul>
<li>Item 1</li><!--
--><li>Item 2</li><!--
--><li>Item 3</li>
</ul>
✅ 保留换行可读性,但 HTML 略显啰嗦
📌 补充说明
- 如果
<li>是默认的display: list-item(块级),不会出现间隙。 - 间隙只在
inline或inline-block时出现。 - 间隙宽度 ≈ 当前字体下的一个空格宽度(受
font-size影响)。
css3中有哪些新特性
CSS3 是对 CSS2 的重大扩展,引入了大量模块化的新特性 ,极大增强了网页的样式表现力和布局能力。以下是 CSS3 中核心且常用的新特性:
一、选择器增强
- 属性选择器扩展 :
[attr^="val"](开头)、[attr$="val"](结尾)、[attr*="val"](包含) - 结构伪类:
:nth-child(n)/:nth-of-type(n):first-of-type/:last-of-type:only-child/:empty:not(selector)
✅ 无需 JavaScript 即可精准选中复杂结构。
二、盒模型与视觉效果
1. 圆角
css
border-radius: 10px; /* 支持四个角分别设置 */
2. 阴影
- 盒阴影:
box-shadow: h v blur spread color inset; - 文字阴影:
text-shadow: h v blur color;
3. 边框图像
css
border-image: url(border.png) 30 round;
4. 背景增强
- 多背景:
background: url(a.png), url(b.png); - 背景尺寸:
background-size: cover / contain / 100% 50%; - 背景原点/裁剪:
background-origin,background-clip
三、渐变(Gradients)
- 线性渐变:
background: linear-gradient(to right, red, blue); - 径向渐变:
background: radial-gradient(circle, red, blue); - 重复渐变:
repeating-linear-gradient(...)
✅ 无需图片即可实现平滑色彩过渡。
四、2D/3D 变换(Transform)
css
transform: translate(10px, 20px)
rotate(30deg)
scale(1.2)
skew(10deg)
matrix(...);
- 3D 支持:
rotateX(),translateZ(),perspective,transform-style: preserve-3d
五、过渡(Transition)
css
transition: property duration timing-function delay;
/* 例:transition: all 0.3s ease; */
实现属性变化的平滑过渡(需有状态变化触发,如 hover)。
六、动画(Animation)
css
@keyframes slide {
0% { left: 0; }
100% { left: 100px; }
}
.element { animation: slide 2s infinite; }
支持多关键帧、循环、方向控制等复杂动效。
七、弹性盒布局(Flexbox)
css
.container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
一维布局神器,轻松实现居中、等高、自适应排列。
八、网格布局(Grid)(虽常归为 CSS3,实为 CSS Grid Level 1)
css
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
}
强大的二维布局系统,彻底改变页面结构方式。
九、媒体查询(Media Queries)------响应式基础
css
@media (max-width: 768px) {
.sidebar { display: none; }
}
实现移动优先、多端适配的核心技术。
十、其他实用新特性
| 特性 | 说明 |
|---|---|
| 多列布局 | column-count, column-gap, column-rule |
| RGBA / HSLA 颜色 | 支持透明度:rgba(255,0,0,0.5) |
| Opacity | 元素整体透明:opacity: 0.8 |
| Resize | 允许用户调整元素大小:resize: both; overflow: auto; |
| Box-sizing | box-sizing: border-box(改变盒模型计算方式) |
| Filters | 滤镜效果:filter: blur(2px) grayscale(100%); |
| Custom Properties (CSS 变量) | :root { --main-color: #333; } → color: var(--main-color); |
💡 注:CSS 变量虽在 CSS3 时代普及,但属于 CSS Custom Properties 模块。
✅ 总结
CSS3 不是一个单一版本,而是模块化演进的集合。它让开发者能够:
- 实现丰富视觉效果(圆角、阴影、渐变)
- 创建流畅动画(transition + animation)
- 构建灵活布局(Flexbox + Grid)
- 适配多端设备(Media Queries)
🌟 现代 CSS 开发 = CSS3 特性 + 浏览器兼容策略(如 Autoprefixer)
说说margin和padding的使用场景
margin 和 padding 都是用来控制元素间距的 CSS 属性,但它们的作用区域和语义完全不同。正确区分它们的使用场景,是写出清晰、可维护、语义化 CSS 的关键。
一、核心区别回顾
margin(外边距) |
padding(内边距) |
|
|---|---|---|
| 作用区域 | 元素边框之外,与其他元素之间的距离 | 元素边框之内,内容与边框之间的距离 |
| 是否占背景 | ❌ 透明,不显示背景 | ✅ 背景色/背景图会延伸至此区域 |
| 是否可为负 | ✅ 可为负值(用于拉近元素) | ❌ 不能为负值 |
| 是否影响布局 | ✅ 影响元素在文档流中的位置 | ✅ 影响元素自身尺寸(除非用 box-sizing: border-box) |
二、典型使用场景
✅ 使用 padding 的场景 (控制内部空间)
-
让内容与边框保持距离
css.card { padding: 16px; /* 文字不会紧贴边框 */ border: 1px solid #ccc; } -
扩大可点击区域(无障碍友好)
cssa { padding: 12px; /* 比仅靠文字更容易点击 */ } -
配合背景色/边框实现视觉区块
- 按钮、卡片、标签等组件内部留白
- 表单输入框内容不贴边
-
保持内容"呼吸感"
- 段落、标题、列表项内部留白
💡 口诀 :"内容需要呼吸?用
padding!"
✅ 使用 margin 的场景 (控制外部间距)
-
控制元素之间的垂直/水平间距
cssp { margin-bottom: 1em; /* 段落之间留空 */ } .button + .button { margin-left: 8px; /* 按钮组横向间隔 */ } -
居中块级元素(水平)
css.box { width: 300px; margin: 0 auto; /* 水平居中 */ } -
推开相邻元素(布局分离)
- 导航项之间留空
- 卡片网格之间的间隙
-
创建"空白区域"而不影响背景
- 页头与内容之间的空白
- 模块之间的分隔
💡 口诀 :"元素之间要分开?用
margin!"
三、常见误区与最佳实践
| 场景 | 错误做法 | 正确做法 |
|---|---|---|
| 想让文字离边框远一点 | 用 margin |
✅ 用 padding |
| 想让两个段落之间有空隙 | 给 padding-bottom |
✅ 给 margin-bottom(更符合语义) |
| 做按钮点击区域 | 只设 line-height |
✅ 加 padding 扩大触控区 |
| 水平居中块元素 | 用 text-align: center 包裹 |
✅ 用 margin: 0 auto |
✅ 黄金法则:
padding是"我内部的空间",margin是"我和别人之间的距离"。
四、结合 box-sizing: border-box 更好用
css
* {
box-sizing: border-box;
}
- 此时
width= content + padding + border - 设置
padding不会撑大盒子,布局更可控 - 推荐全局设置,避免尺寸计算混乱
box-sizing
box-sizing 是 CSS 中一个极其重要但常被初学者忽略 的属性,它决定了元素的宽度(width)和高度(height)如何计算,直接影响布局的可预测性和开发效率。
一、核心作用
box-sizing控制:width/height到底包含哪些部分?
回忆盒模型的四个部分:
总尺寸 = margin + border + padding + content
而 box-sizing 决定的是:你写的 width: 100px 到底是指哪一块?
二、两个主要取值
1. content-box(默认值)
width/height仅指 content(内容区)- 总宽度 =
width+padding-left+padding-right+border-left+border-right
css
.box {
box-sizing: content-box; /* 默认,可省略 */
width: 100px;
padding: 10px;
border: 5px solid black;
}
/* 实际占据宽度 = 100 + 10 + 10 + 5 + 5 = 130px */
✅ 问题 :
想让一个元素宽 200px,加了 padding: 20px 后,实际变成 240px ------ 布局容易错乱。
2. border-box(推荐值)
width/height= content + padding + border- 总宽度 =
width(padding和border向内挤压内容区)
css
.box {
box-sizing: border-box;
width: 100px;
padding: 10px;
border: 5px solid black;
}
/* 实际占据宽度 = 100px(内容区只剩 70px) */
✅ 优势:
- 设置
width: 200px,无论加多少padding/border,总宽始终是 200px - 布局更直观、可控,符合大多数人的直觉
三、为什么 border-box 更好用?
🌰 场景:两列等宽布局
html
<div class="col">Left</div>
<div class="col">Right</div>
❌ 用 content-box(默认):
css
.col {
width: 50%;
padding: 20px; /* 问题来了! */
}
/* 实际宽度 = 50% + 40px > 50%,两列会换行! */
✅ 用 border-box:
css
* { box-sizing: border-box; } /* 全局重置 */
.col {
width: 50%;
padding: 20px; /* 安全!总宽仍是 50% */
}
四、如何全局启用 border-box?
推荐写法(兼容伪元素):
css
*, *::before, *::after {
box-sizing: border-box;
}
💡 这是现代前端项目的标准初始化代码(Bootstrap、Tailwind 等都默认包含)。
五、常见误区澄清
| 误区 | 正确理解 |
|---|---|
"border-box 让 padding 失效" |
❌ padding 依然存在,只是不撑大盒子 |
"border-box 影响 margin" |
❌ margin 始终在盒模型之外,不受影响 |
"所有元素都该用 border-box" |
✅ 几乎总是对的,极少数场景(如 canvas 尺寸控制)除外 |
🔑 记住 :
"用border-box,让width就是width。"
说说你对line-height的理解以及赋值方式
line-height 是 CSS 中控制行高 (行与行之间的垂直距离)的核心属性,直接影响文本的可读性、垂直对齐和布局高度。理解它对排版和 UI 开发至关重要。
一、line-height 是什么?
line-height= 一行文本所占的垂直高度它决定了基线(baseline)之间的距离,而非文字本身的高度。
📐 视觉模型:
↑
line-height(整行高度)
↓
┌──────────────────────┐ ← 顶线(top of line box)
│ │
│ 文字 (content) │ ← 文字实际高度(font-size)
│ │
└──────────────────────┘ ← 底线(bottom of line box)
- 文字在
line-height区域内垂直居中 - 多余空间 =
line-height - font-size,平均分配到文字上下
二、line-height 的赋值方式(5 种)
| 类型 | 示例 | 特点 | 使用场景 |
|---|---|---|---|
| 无单位数值(推荐) | line-height: 1.5; |
相对于当前 font-size 的倍数,会继承并重新计算 |
✅ 全局设置、响应式排版 |
| 百分比 | line-height: 150%; |
相对于当前 font-size,计算后继承固定值 |
⚠️ 少用(继承行为不如无单位灵活) |
| 长度单位 | line-height: 24px; |
固定像素值,直接继承固定值 | ✅ 精确控制(如按钮、固定高度组件) |
| 关键字 | line-height: normal; |
浏览器默认值(通常 ≈ 1.2) |
一般不显式使用 |
| 继承 | line-height: inherit; |
显式继承父元素值 | 特殊需求 |
三、关键特性详解
1. 无单位数值 vs 百分比/px(继承差异)
这是最容易出错的地方!
html
<div class="parent">
<span class="child">Text</span>
</div>
.parent {
font-size: 20px;
line-height: 1.5; /* = 30px */
}
.child {
font-size: 14px;
/* 无单位:line-height = 14px * 1.5 = 21px ✅ */
}
.parent {
font-size: 20px;
line-height: 150%; /* = 30px(计算后继承) */
}
.child {
font-size: 14px;
/* 百分比:继承的是 30px(固定值),不是 14px*1.5 ❌ */
/* → 行高过大,排版失衡 */
}
✅ 最佳实践 :全局用无单位数值 (如
body { line-height: 1.5; })
2. 垂直居中单行文本
css
.button {
height: 40px;
line-height: 40px; /* = height → 文字垂直居中 */
font-size: 16px;
}
⚠️ 仅适用于单行文本!多行会撑高容器。
3. 影响块级元素高度
- 块级元素(如
<p>、<div>)的最小高度 = line-height - 如果未设置
height,元素高度由line-height决定
css
.box {
font-size: 16px;
line-height: 2; /* = 32px */
/* .box 高度 = 32px(即使没内容) */
}
四、注意事项
- 不要设
line-height: 0- 会导致文字重叠(但可用于清除空格间隙技巧)
- 多行文本垂直居中 ≠
line-height = height- 应使用 Flexbox:
display: flex; align-items: center;
- 应使用 Flexbox:
line-height不是"行间距"- 行间距 =
line-height - font-size
- 行间距 =
- 不同字体的
line-height表现可能不同- 中文/英文、衬线/无衬线字体的默认行高有差异
css优化和提升性能的方法
CSS 优化不仅能提升页面渲染性能,还能改善用户体验、降低资源消耗。以下是 系统性、实用性强 的 CSS 优化与性能提升方法,涵盖编写、加载、渲染全流程:
一、减少和优化 CSS 文件本身
1. 删除无用 CSS(关键!)
- 使用工具检测未使用样式:
- PurgeCSS(配合构建工具)
- Chrome DevTools → Coverage(
Ctrl+Shift+P→ "Coverage")
- 移除过时组件、废弃类名
2. 压缩 CSS
-
构建时自动压缩(移除空格、注释、缩短颜色值):
bash# Webpack: css-minimizer-webpack-plugin # Vite: 内置压缩 # Gulp: gulp-clean-css
3. 避免过深嵌套(尤其 Sass/Less)
-
嵌套层级 ≤ 3 层,防止生成冗长低效选择器
scss// ❌ 反例 .page { .main { .content { .card { ... } } } } // ✅ 推荐:BEM 或扁平结构 .card { ... }
二、优化选择器性能
1. 避免低效选择器
- 最耗性能 :
*通配符、属性选择器[class*="btn"]、:nth-child复杂计算 - 推荐 :使用 类选择器(
.class),避免标签/ID 选择器过度使用
2. 选择器从右向左匹配
- 浏览器从最右边的选择器开始匹配
- ❌ 低效:
div > ul > li > a.button(先找所有.button,再逐级向上验证) - ✅ 高效:
.nav-link(直接匹配类)
💡 原则:右边选择器越具体,性能越好
三、减少重排(Reflow)与重绘(Repaint)
1. 避免频繁读写布局属性
- 读取
offsetWidth、clientHeight等会强制触发重排 - 批量操作:先读取所有值,再统一修改
2. 用 transform 和 opacity 做动画
-
这两个属性由 GPU 合成(Composite),不触发重排/重绘
css/* ✅ 高性能动画 */ .element { transition: transform 0.3s, opacity 0.3s; } .element:hover { transform: translateX(10px); opacity: 0.8; } /* ❌ 低性能(触发重排) */ .element:hover { left: 10px; /* position: relative/absolute */ width: 110px; }
3. 避免 table 布局
- 表格单元格尺寸需多次计算,重排成本极高
四、优化加载性能
1. 关键 CSS 内联(Critical CSS)
-
首屏渲染所需 CSS 直接写入
<style>标签 -
非关键 CSS 异步加载:
html<!-- 首屏关键样式 --> <style>/* 首屏按钮、导航等样式 */</style> <!-- 非关键样式异步加载 --> <link rel="preload" href="non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="non-critical.css"></noscript>
2. 拆分 CSS 文件
- 按页面/组件拆分,避免单文件过大
- 路由级按需加载(SPA 中配合代码分割)
3. 启用 Gzip/Brotli 压缩
- 服务器配置压缩,CSS 体积可减少 70%+
五、现代布局与特性优化
1. 优先使用 Flexbox / Grid
- 替代
float、inline-block,避免间隙问题和复杂清除 - 布局计算更高效
2. 慎用 CSS 滤镜(Filter)和阴影
filter: blur()、box-shadow大范围使用会显著降低渲染性能- 限制模糊半径、阴影扩散值
3. 使用 will-change 提示浏览器优化
-
提前告知将要变化的属性(慎用!):
css.animated-element { will-change: transform; /* 浏览器可提前分层 */ }⚠️ 过度使用会消耗内存,仅用于复杂动画元素
六、其他实用技巧
| 优化点 | 方法 |
|---|---|
| 减少 DOM 深度 | 扁平化 HTML 结构,降低样式匹配成本 |
避免 @import |
阻塞并行加载,改用 <link> |
| 使用 CSS 变量替代重复值 | 便于维护,但注意:过度使用可能轻微影响性能 |
| 媒体查询靠近规则 | 提高可维护性,不影响性能 |
| 字体优化 | 使用 font-display: swap 避免文字闪现 |
七、性能监控与工具
- Lighthouse:检测未使用 CSS、渲染性能
- Chrome Performance 面板:分析重排/重绘耗时
- WebPageTest:查看 CSS 加载瀑布流
💡 记住 :
"最小化 CSS 体积 + 最小化样式计算 + 最小化布局扰动" = 高性能 CSS
通过以上方法,可显著提升页面加载速度、交互流畅度和 SEO 表现。