普通视图
HTTP-深度拆解 UDP 与 TCP 的核心差异
前言
在网络传输层,TCP 像是一位严谨的“快递员”,确保包裹万无一失;而 UDP 更像是一位“投递员”,只管快速把信件投进邮筒。在 HTTP/3.0(QUIC)全面转向 UDP 的今天,重新理解这两个协议的底层逻辑显得尤为重要。
一、 UDP:为了速度而生的“轻骑兵”
1. 核心概念
UDP(User Datagram Protocol)提供的是无连接、不可靠的传输服务。它不关心对方是否收到,只负责把报文“推”出去。
2. UDP为什么轻量级?
TCP 的首部至少 20 字节,而 UDP 只有固定的 8 字节,它没有复杂的序列号和窗口调节,这意味着 CPU 处理 UDP 包的速度远高于 TCP。这 8 个字节被平分为四个字段,每个字段 2 字节:
- 源端口号 (Source Port) :发送端的端口,在不需要对方回信时可全为 0。
- 目的端口号 (Destination Port) :接收端的端口,必须指定。
- 长度 (Length) :UDP 报文段的长度(包含首部和数据),最小值为 8。
- 校验和 (Checksum) :检测 UDP 报文在传输中是否有错,有错就丢弃。
2. 核心特点
- 无连接时延:发送数据前不需要三次握手,拿起就发,响应极快。
- 无拥塞控制:即便网络环境恶劣,UDP 也会保持恒定的发送速率(所以直播才会有“卡顿”而不是“暂停”)。
- 面向报文:应用层给多少,它就传多少。不合并、不拆分,保留了报文的边界。
- 低开销首部:首部仅占 8 字节,相比 TCP 的 20 字节起步,传输效率极高。
- 灵活的多播性:天然支持一对一、一对多、多对多的交互通信。
3. 应用场景
- 实时性要求高:视频会议、语音通话、在线直播。
- 数据量小且频繁:DNS 查询(一次往返即结束)。
- 新兴协议基础:HTTP/3.0 (QUIC 协议)。
二、 TCP 与 UDP:全维度对比
为了方便记忆,我们可以通过下表快速对比两者的差异:
| 维度 | TCP (传输控制协议) | UDP (用户数据报协议) |
|---|---|---|
| 连接性 | 面向连接(需三次握手) | 无连接(即发即收) |
| 可靠性 | 可靠(保证不丢、不重、有序) | 不可靠(尽力而为,不保结果) |
| 传输效率 | 较慢(因各种控制机制) | 极快(协议简单,实时性强) |
| 资源消耗 | 较高 | 较低 |
| 通信模式 | 仅限点对点(1对1) | 支持单播、多播、广播 |
| 首部开销 | 20 ~ 60 字节 | 固定 8 字节 |
| 数据流控制 | 流量控制、拥塞控制 | 无 |
三、 如何选择?(深度思考)
-
选 TCP 的理由:
当你需要确保数据的完整性时。比如:发送一封邮件、下载一个安装包、或者是浏览网页。如果中间丢了一个字符,整个文件可能就失效了。
-
选 UDP 的理由:
当你的应用场景对延迟敏感,且能容忍少量数据丢失时。比如:直播里少了一帧画面,人眼几乎察觉不到,但如果为了等这一帧而导致视频卡住 2 秒,用户体验会极差。
HTTP-深入浅出 TCP 协议:从报文结构到三次握手与四次挥手
前言
在计算机网络中,TCP (Transmission Control Protocol) 就像是一位极其负责的“快递员”。它不追求极速(那是 UDP 的事),但它保证每一份数据都能不丢、不重、按序地送达目的地。
一、 TCP 核心特性:为什么它如此可靠?
- 面向连接:通信前必须“点对点”建立连接。
- 可靠传输:通过序列号、确认应答、超时重传机制实现无差错传输。
- 全双工通信:连接建立后,双方可以同时发送和接收数据。
- 面向字节流:数据被视为无结构的字节流,由 TCP 根据窗口大小进行分段。
二、 读懂 TCP 报文:那些关键的“信号灯”
在理解握手之前,必须先看懂报文首部中的核心字段:
1. 序列号与确认
- Sequence Number (seq) :报文段发送的第一个字节的序号,保证了数据的有序性。
- Acknowledgement Number (ack) :指期望收到对方下一个报文段的第一个字节序号,代表此前的序号已成功接收。
2. 控制位(标志符)
这些 1 bit 的标志位决定了报文的“性格”:
- SYN=1:请求建立连接。
- ACK=1:确认号有效。TCP 规定连接建立后所有报文 ACK 必须置 1。
- FIN=1:请求释放连接。
- RST=1:连接出现严重问题,强制重置。
- PSH=1:尽快交付应用层,不要等缓冲区满。
- URG=1:紧急数据优先处理。
三、 三次握手:如何安全地“握住”对方?
三次握手的核心目的:确认双方的收发能力均正常,并同步初始序列号。
-
第一次握手:客户端发送
SYN=1, seq=x。客户端进入SYN-SENT状态。 -
第二次握手:服务端返回
SYN=1, ACK=1, seq=y, ack=x+1。服务端进入SYN-RECEIVED状态。 -
第三次握手:客户端返回
ACK=1, seq=x+1, ack=y+1。-
关键点:双方此后均进入
ESTABLISHED(已建立连接)状态。
-
关键点:双方此后均进入
![]()
💡 深度思考:为什么不是两次?
为了防止“已失效的连接请求”突然到达服务端导致资源浪费。
想象一下:。客户端发送了⼀个连接请求 A,但是因为⽹络原因造成了超时,这时 TCP 会启动超时重传的机制再次发送⼀个连接请求 B。此时请求顺利到达服务端,服务端应答完就建⽴了请求。如果连接请求 A 在两端关闭后终于抵达了服务端,那么这时服务端会认为客户端⼜需要建⽴ TCP 连接,从⽽应答了该请求并进⼊ ESTABLISHED 状态。此时客户端其实是 CLOSED 状 态,那么就会导致服务端⼀直等待,造成资源的浪费。
四、 四次挥手:体面的“分手”流程
TCP 连接是双向的,因此断开连接时,每一端都要单独关闭。
-
第一次挥手:主动方发送
FIN=1,表示“我不再发数据了”。 -
第二次挥手:被动方返回
ACK=1。此时连接处于半关闭状态,被动方可能还有没发完的数据要继续传。 -
第三次挥手:被动方发送完数据后,发送
FIN=1,表示“我也可以关了”。 -
第四次挥手:主动方返回
ACK=1。经过2*MSL时间后,连接彻底关闭。
💡 深度思考:为什么挥手比握手多一次?
-
握手时:服务端可以把
SYN(连接请求)和ACK(确认)放在一个包里发回去。 -
挥手时:当服务端收到
FIN时,它可能还有数据没发完。所以它先回一个ACK表示收到了,等数据发完了才发自己的FIN。这就导致了ACK和FIN分开发送。
五、 总结:TCP 与流量控制
除了握手挥手,TCP 还通过 Window Size(窗口大小) 实现了流量控制:
- 接收端根据自己的处理能力告诉发送端:“我还能收多少”。
- 这样可以防止发送端发得太快,导致接收端缓冲区溢出。
HTTP-协议溯源:深度解析 HTTP/3.0 与 QUIC 协议的底层革命
前言
HTTP/2 开启了多路复用的时代,但它依然跑在 TCP 这条“老旧”的铁轨上。只要 TCP 的设计初衷(顺序传输、字节流可靠性)不改变,队头阻塞(HOL Blocking) 的幽灵就永远无法彻底散去。于是,Google 另辟蹊径,基于 UDP 打造了 QUIC,并最终成为了 HTTP/3 的核心。
一、 HTTP/2 的遗憾:TCP 层的队头阻塞
虽然 HTTP/2 过多路复用解决了 HTTP 在应用层 的队头阻塞,使应用层发生的请求不再需要排队等候,解决了 HTTP/1.1 的队头阻塞。,但由于它底层依然依赖 TCP,产生了一个新的瓶颈
-
传输层队头阻塞问题 :HTTP/2 建立在 TCP 之上。TCP 要求字节必须按顺序交付。如果网络发生丢包,TCP 无法分辨哪些字节属于哪个请求,只能暂停整个连接等待重传。
-
弱网环境下的尴尬:在丢包率较高的移动网络下,HTTP/2 的表现有时甚至不如开启 6 个连接的 HTTP/1.1,因为“一荣俱荣,一损俱损”。
- 连接建立的开销:TCP 三次握手 + TLS 握手,在弱网环境下 RTT(往返时延)非常高。
![]()
![]()
二、 HTTP/3 的逆袭:基于 UDP 的 QUIC 协议
由于 TCP 协议深植于操作系统内核和路由器固件中,修改极其困难。HTTP/3 索性“推倒重来”,在 UDP 之上实现了可靠传输,这便是 QUIC(Quick UDP Internet Connections) 。
1. QUIC 的四大核心魔法
① 彻底解决队头阻塞
QUIC 在传输层实现了多路复用。每个流(Stream)之间是相互独立的。
- 效果:如果 Stream A 丢包,只会阻塞 Stream A 的重组,Stream B 和 Stream C 可以继续不受影响地传输数据。
② 极速握手(0-RTT / 1-RTT)
TCP 需要先建立连接再建立加密通道。
- 效果:QUIC 将传输握手与加密握手合并。初次连接只需 1 个 RTT,再次连接甚至可以实现 0-RTT 极速启动。
③ 连接迁移 (Connection Migration)
TCP 依靠“四元组”(源IP、源端口、目标IP、目标端口)识别连接。
- 痛点:当你从 Wi-Fi 切换到 4G,IP 变了,TCP 连接必断。
- 改进:QUIC 使用 Connection ID 识别连接。即便 IP 切换,只要 ID 不变,连接就能无缝延续。
④ 改进的头部压缩:QPACK
HTTP/2 使用的 HPACK 在乱序传输时会产生队头阻塞,HTTP/3 升级为 QPACK,专门优化了多流并发下的压缩效率。
三、 总结:从“排队”到“并发”
| 特性 | HTTP/2 (TCP) | HTTP/3 (UDP/QUIC) |
|---|---|---|
| 传输层阻塞 | 存在 TCP 队头阻塞 | 不存在(流与流独立) |
| 握手时延 | 2~3 RTT (TCP+TLS) | 0~1 RTT |
| 网络切换 | 连接断开,需重新握手 | 无缝迁移 |
| 可靠性 | 操作系统内核实现 | QUIC 在应用层实现 |
四、 HTTP3.0现状
目前HTTP3.0并没有普及,你可以随便打开网站查看请求相应的HTTP版本,会发现大多数请求都是HTTP2.0的!
CSS-如何在 Chrome 中实现小于 12px 的字体?
JS-原生实战:手把手带你封装一个高性能模态框(Modal)组件
前言
在网页开发中,弹框(Modal)是最常见的交互组件之一。一个合格的弹框不仅要能“跳出来”,还需要处理好遮罩层、层级关系(z-index)、防滚动穿透以及用户便捷退出的体验。本文将从零开始带你实现一个具备丝滑动画效果的模态框。
一、 核心设计思路
实现弹框主要分为三个部分,它们的层级关系如下:
-
遮罩层 (Overlay) :铺满全屏的半透明背景,用于阻断用户对背景页面的操作,并突出弹框,初始
diasplay为none,并使用position: fixed使其铺满屏幕。 -
内容盒 (Content) :位于遮罩层之上,水平垂直居中,承载具体信息,初始
diasplay为none。 -
控制逻辑:
- 打开:显示遮罩与弹框,同时锁定背景滚动,将遮罩层与内容盒的display属性均设置为block,并设置弹框内容盒子的z-index让其比遮罩层高。
- 关闭:隐藏元素,恢复背景滚动。支持点击“关闭按钮”、点击“遮罩层”以及按下 “Esc 键”退出。
二、 关键技术点解析
1. 为什么使用 position: fixed 而非 absolute?
在遮罩层和弹框的样式中,我们优先选择 fixed。
-
absolute是相对于最近的已定位祖先元素,如果页面很长,滚动后弹框可能会“飞走”。 -
fixed是相对于浏览器视口(Viewport)定位,无论页面如何滚动,弹框始终保持在屏幕中央。
2. 完美的水平垂直居中
利用 top: 50% 和 left: 50% 将左上角定位到中心,再配合 transform: translate(-50%, -50%) 将盒子向左和向上平移自身宽高的 50%,实现真正的精准居中。
3. 防止“滚动穿透”
当弹框打开时,用户依然可以滚动背景页面,这在用户体验上是不好的。
-
解决方案:打开弹框时设置
document.body.style.overflow = "hidden"。
三、 完整代码实现
以下是优化后的代码,加入了细腻的淡入(FadeIn)和滑入(SlideIn)动画。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>弹框组件演示</title>
<style>
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 背景遮罩层 */
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 999;
animation: fadeIn 0.3s ease-out;
}
/* 弹框样式 */
.modal {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
max-width: 500px;
background-color: white;
border-radius: 16px;
z-index: 1000;
padding: 32px;
animation: slideIn 0.4s ease-out;
overflow: hidden;
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 淡入动画 */
@keyframes slideIn {
from {
opacity: 0;
transform: translate(-50%, -60%);
}
to {
opacity: 1;
transform: translate(-50%, -50%);
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>弹框组件演示</h1>
</header>
<section class="content-section">
<button class="open-btn" id="openModalBtn">打开弹框</button>
</section>
<section style="height: 1000px;"></section>
</div>
<!-- 灰色背景遮罩层 -->
<div class="modal-overlay" id="modalOverlay"></div>
<!-- 弹框 -->
<div class="modal" id="modal">
<h2>欢迎使用弹框组件</h2>
<button id="closeModalBtn">关闭弹框</button>
</div>
<script>
// 获取DOM元素
const openModalBtn = document.getElementById("openModalBtn"); //打开按钮
const modalOverlay = document.getElementById("modalOverlay"); //遮罩层
const modal = document.getElementById("modal"); //弹框
const closeModalBtn = document.getElementById("closeModalBtn"); //关闭按钮
// 打开弹框
function openModal() {
modalOverlay.style.display = "block";
modal.style.display = "block";
document.body.style.overflow = "hidden"; // 防止背景滚动
}
// 关闭弹框
function closeModal() {
modalOverlay.style.display = "none";
modal.style.display = "none";
document.body.style.overflow = "auto"; // 恢复滚动
}
// 给打开按钮绑定打开弹框操作
openModalBtn.addEventListener("click", openModal);
// 点击背景遮罩层关闭弹框
modalOverlay.addEventListener("click", closeModal);
// 按ESC键关闭弹框
document.addEventListener("keydown", function (event) {
if (event.key === "Escape" && modal.style.display === "block") {
closeModal();
}
});
</script>
</body>
</html>
CSS -实战技巧:彻底搞定单行、多行文本溢出省略号显示
前言
在 UI 布局中,为了保证页面的整洁,我们经常需要对超出容器范围的文本进行截断并显示省略号(...)。针对不同的布局需求和浏览器兼容性,通常有三种主要的实现方案。
一、 单行文本溢出省略
这是最常用、兼容性最好的方案,适用于标题、标签等场景。
核心代码:
.overflow-text {
width: 200px; /* 必须设置宽度 */
white-space: nowrap; /* 1. 强制文字不换行 */
overflow: hidden; /* 2. 隐藏超出部分 */
text-overflow: ellipsis; /* 3. 使用省略号代替被截断文字 */
}
二、 多行文本溢出省略(WebKit 内核方案)
这是目前移动端和现代浏览器(Chrome, Safari, Edge)最常用的方案。它利用了 WebKit 的私有属性,实现简单且效果精准。
核心代码:
.multi-overflow {
display: -webkit-box; /* 1. 必须结合 box 模型使用 */
-webkit-box-orient: vertical; /* 2. 设置伸缩盒子的子元素排列方式 */
-webkit-line-clamp: 2; /* 3. 限制显示的行数 */
overflow: hidden; /* 4. 隐藏超出范围的内容 */
}
注意:该属性虽然是 WebKit 私有,但目前主流浏览器支持度已经非常高,是实际开发的首选。
三、 自定义多行省略(伪元素方案)
如果你需要兼容一些不支持 line-clamp 的旧版浏览器,或者需要更灵活的自定义样式,可以使用伪元素模拟。
核心代码:
.demo {
position: relative; /* 为伪元素提供定位参照 */
line-height: 20px; /* 行高 */
height: 40px; /* 高度必须是行高的整数倍(此处为2行) */
overflow: hidden; /* 隐藏多余内容 */
word-break: break-all;
}
.demo::after {
content: "..."; /* 插入省略号 */
position: absolute;
bottom: 0;
right: 0;
padding-left: 10px;
background: white; /* 关键:背景色需与容器背景一致,遮盖末尾文字 */
}
方案优缺点:
- 优点:兼容性极佳。
- 缺点:即使文字没超出行数,省略号也会一直显示(可通过 JS 判断高度动态添加类名来解决)。
四、 总结与最佳实践
| 需求场景 | 推荐方案 | 关键词 |
|---|---|---|
| 单行文本 | 标准 CSS 方案 |
nowrap + ellipsis
|
| 移动端/现代浏览器 | WebKit 方案 | -webkit-line-clamp |
| 极端兼容性要求 | 伪元素方案 |
::after + 绝对定位 |
CSS-动画进阶:从 @keyframes 到 Animation 属性全解析
前言
相比传统的 transition(过渡),animation(动画)提供了更强大的控制能力。它不需要触发条件,可以自动播放,并且通过“关键帧”能够实现极其复杂的视觉效果。
一、 动画的“两步走”战略
实现一个 CSS 动画通常分为两步:
-
定义动画:使用
@keyframes规定不同时间点的样式状态。 -
调用动画:在目标元素上使用
animation属性。
二、 Animation 属性详解(简写语法)
为了提高效率,我们通常使用简写方式:
animation: name duration timing-function delay iteration-count direction fill-mode;
1. 核心属性表
| 属性 | 描述 | 默认值 |
|---|---|---|
animation-name |
关键帧动画的名称 | 无 |
animation-duration |
动画周期时长(必须带单位,如 2s) |
0 |
animation-timing-function |
速度曲线(平滑度控制) | ease |
animation-delay |
动画延迟启动时间 | 0 |
animation-iteration-count |
播放次数(数字或 infinite) |
1 |
animation-direction |
是否反向播放(如 alternate) |
normal |
animation-fill-mode |
动画结束后的状态(如 forwards 停在终点) |
none |
2. 关键属性深度解析
-
animation-timing-function(速度曲线) :-
ease:默认值,先慢后快再慢。 -
linear:匀速运动,适合背景滚动或旋转。 -
steps(n):逐帧动画,适合做像素画或 Loading 效果。
-
-
animation-iteration-count(循环次数) :-
n:播放 次。 -
infinite:无限循环播放。
-
三、 实战案例:方块平移旋转
需求:方块在 3s 内匀速向右平移400px并旋转360°,无限循环。
.card {
width: 100px;
height: 100px;
background: #ff4757;
/* 针对 width 和 transform 设置过渡 */
animation: moves 3s ease infinite;
}
@keyframes moves {
0% {
transform: translate(0,0) rotate(0deg);
}
100% {
transform: translate(400px,0px) rotate(360deg);
}
}
四、 进阶技巧与避坑指南
-
性能优化(优先使用 Transform) :
在动画中修改
margin-left或left会触发浏览器的重排 (Reflow) ,消耗大量性能。推荐使用transform: translateX(),它通过 GPU 加速,动画更加丝滑。 -
动画状态保持:
如果你想让动画播完后停留在最后一帧,请加上
forwards(animation-fill-mode)。 -
单位不能省:
animation-duration即使是 0 秒也必须带单位0s,否则部分浏览器会判定为语法错误导致动画不生效。
CSS-深度解析 Transition 过渡与 Transform 变换
CSS-深度解析 Position 五大定位模式
前言
在 CSS 布局中,position 属性是控制元素“脱离常规”的关键。无论是想要悬浮的导航栏,还是精准重叠的图层,都离不开对定位属性的深入理解。本文将带你搞懂 relative、absolute、fixed 与 sticky 的底层逻辑。
一、 Position 核心参数详解
| 属性值 | 含义 | 布局表现 | 参考物 |
|---|---|---|---|
static |
默认值 | 正常文档流布局。 | 无(Top/Left 等属性无效)。 |
relative |
相对定位 | 不脱离文档流,占据原始空间。 | 元素在文档流中的原始位置。 |
absolute |
绝对定位 | 完全脱离文档流,不占位。 | 最近的 非 static 祖先元素。 |
fixed |
固定定位 | 完全脱离文档流,不占位。 | 浏览器窗口 (Viewport) 。 |
sticky |
粘性定位 | 混合模式,特定条件下生效。 | 最近的滚动祖先元素。 |
二、 偏移属性:Left、Right、Top、Bottom
1. 生效前提
这些偏移属性仅在 position 不为 static 时生效。它们定义了元素边缘相对于参考物的距离。
2. 不同定位下的偏移逻辑
-
Relative (相对自身) :
设置
left: 20px,元素会相对于它原本在文档流中的位置向右移动 20px。它原来的位置依然被保留,不会被后续元素顶替。 -
Absolute (相对祖先) :
设置
left: 0,元素会紧贴最近的已定位(非 static)祖先元素的左内边缘。 -
Fixed (相对窗口) :
设置
right: 10px; bottom: 10px;,元素将永久停留在浏览器窗口的右下角,不随页面滚动而移动。
三、 现代布局黑科技:Sticky (粘性定位)
-
表现:它是
relative和fixed的结合体。 -
示例:
top: 0; position: sticky;当页面未滚动到该元素时,它是
relative(随内容滚动);当元素滚动到视口顶部时,它会像fixed一样“粘”在顶部,直到其父容器消失在视口中。 -
常用场景:表格标题行固定、侧边栏跟随。
四、 核心面试考点:Absolute 的参考物
误区修正:很多人认为绝对定位是相对于“父元素”。
准确定义:是相对于最近的、非 static 定位的祖先元素。如果向上找遍了所有祖先元素都没有定位,则相对于 初始包含块(通常是
<html>) 定位。
五、 总结与最佳实践
-
子绝父相:这是最经典的用法。父元素设为
relative(仅为了提供参考坐标),子元素设为absolute实现精准定位。 - 避免滥用 Fixed:固定定位会脱离文档流,过多的固定元素会遮挡用户视线,且在移动端可能存在兼容性坑位。
-
层级管理:配合
z-index使用,数值越大,图层越靠上(仅在已定位元素上生效)。
CSS-布局基石:深度解析四大定位方式与文档流机制
前言
在 CSS 的世界里,页面布局的本质就是控制元素在“流”中的位置。理解普通流、浮动、绝对定位与固定定位,是掌握复杂页面结构的钥匙。本文将带你理清它们的底层逻辑与相互影响。
一、 普通流 (Normal Flow)
普通流(也叫文档流)是页面最默认的布局方式。
-
布局逻辑:元素按照其在 HTML 中出现的先后顺序,自上而下、自左而右排列。
-
元素表现:
- 块级元素 (Block) :独占一行,垂直排列。
- 行内元素 (Inline) :水平排列,遇到边缘自动换行。
-
地位:它是所有布局的基础,除非显式更改,否则元素都在流中。
二、 浮动 (Float)
浮动最初是为了实现“文字环绕图片”的效果,但后来演变成了主流的列布局工具。
- 布局逻辑:元素首先处于普通流位置,然后向左或向右偏移,直到碰到包含框或另一个浮动元素的边缘。
- 脱离文档流:浮动元素会部分脱离文档流。它不再占据普通流的空间,但依然会影响文档流中文字的排列(形成环绕)。
- 注意:使用浮动后务必记得清除浮动 (Clearfix) ,否则会导致父元素高度坍塌。
三、 绝对定位 (Absolute Positioning)
绝对定位让元素拥有了“自由移动”的能力。
-
布局逻辑:元素完全脱离文档流,不再占据物理空间,兄弟元素会像它不存在一样向上位移。
-
定位参考(包含块) :
- 相对于其最近的非 static 定位的祖先元素进行定位。
- 如果找不到,则相对于初始包含块(通常是
<html>)定位。
-
常用技巧:父级
relative,子级absolute。
四、 固定定位 (Fixed Positioning)
固定定位是特殊的绝对定位,它让元素在屏幕上“静止”。
- 布局逻辑:元素完全脱离文档流。
- 定位参考:相对于浏览器视口 (Viewport) 进行定位。
- 特点:无论页面如何滚动,元素始终保持在屏幕的固定位置。常用于导航栏、回到顶部按钮或侧边广告。
五、 核心对比:脱离文档流情况
这是面试中最常被问到的对比点:
| 布局方式 | 是否脱离文档流 | 占据空间 | 相对参考物 |
|---|---|---|---|
| 普通流 | 否 | 是 | 兄弟元素与父元素 |
| 浮动 | 部分脱离 | 否(仅对文本有影响) | 父元素边缘 |
| 绝对定位 | 完全脱离 | 否 | 最近的非 static 祖先元素 |
| 固定定位 | 完全脱离 | 否 | 浏览器视口 |
💡 总结建议
- 普通流是常态;
- 浮动处理简单的横向排列(虽然现代开发更多使用 Flex);
- 绝对定位处理元素重叠和局部精准定位;
- 固定定位处理与窗口挂钩的悬浮组件。
CSS-玩转背景控制与文字排版艺术
前言
在前端开发中,细节决定质感。如何让背景图只在内容区域显示?如何优雅地处理文字溢出?本文将带你深入探索 CSS 中关于 background 与 Text 的进阶属性,让你的页面更加精致。
一、 背景属性的高级控制
1. background-clip(背景裁剪)
决定背景延伸到什么位置。
-
border-box(默认):背景延伸至边框外沿(但在边框下层)。 -
padding-box:背景延伸至内边距外沿,不会显示在边框下。 -
content-box:背景只在内容区域显示。 -
text(特殊):将背景裁剪为文字的前景色(常用于制作渐变文字)。
2. background-origin(背景原点)
决定背景图片的绘制起点(即 background-position: 0 0 的位置)。
-
padding-box(默认):图片左上角对齐 padding 边缘。 -
border-box:图片左上角对齐 border 边缘。 -
content-box:图片左上角对齐内容区域边缘。
3. background-size(背景尺寸)
-
contain:保持比例缩放,确保图片完整显示在容器内(可能会有留白)。 -
cover:保持比例缩放,确保图片完全覆盖容器(可能会被裁剪)。 -
具体数值:如
100px 50%,手动指定宽高。
4. box-decoration-break(元素断裂处的修饰)
当元素被分为几个独立的盒子(如使内联元素span跨越多行),background-break属性用来控制背景怎样在这些不同的盒子中显示,取值如下:
-
slice(默认):背景像是在一个整体上绘制后被切开,断裂处没有边框/内边距。 -
clone:每个断裂的盒子都拥有独立的背景、边框和内边距。
二、 文字排版与换行控制
1. 换行与溢出
-
word-wrap/overflow-wrap:-
normal:浏览器默认。 -
break-word:如果单词太长无法在一行显示,允许在单词内换行(更常用)。
-
-
word-break: break-all:强制在单词内任何字符间断行,适合处理超长连续字符。
2. text-overflow(文本溢出处理)
常用于处理单行文本超出容器:
-
clip:简单裁剪,不显示省略号。 -
ellipsis:显示省略号...(需配合overflow: hidden和white-space: nowrap使用)。
三、 text-decoration:文字装饰的简写艺术
现代 CSS 支持更精细的文字装饰控制: text-decoration: <line> <color> <style>
1. 线型 (Line)
-
none:去除装饰(最常用于<a>标签)。 -
underline:下划线。 -
overline:上划线。 -
line-through:删除线。
2. 样式 (Style)
-
solid:实线(默认)。 -
double:双线。 -
dotted:点线。 -
dashed:虚线。 -
wavy:波浪线。
四、 实战 tips:渐变文字效果
利用 background-clip: text,你可以轻松实现绚丽的渐变文字:
.gradient-text {
background: linear-gradient(to right, red, blue);
-webkit-background-clip: text; /* 必须加前缀 */
color: transparent; /* 文字设为透明,露出背景 */
font-size: 40px;
}