019-外边距合并

外边距合并(Margin Collapsing)现象及解决方案

外边距合并是CSS中一个重要的盒模型概念,指相邻元素的垂直外边距在某些情况下会合并成一个外边距的现象。

一、外边距合并的三种基本情况

1. 相邻兄弟元素合并

1
2
<div class="box1">上边元素</div>
<div class="box2">下边元素</div>
1
2
3
.box1 { margin-bottom: 20px; }
.box2 { margin-top: 30px; }
/* 实际间距为30px(取较大值),不是50px */

2. 父元素与第一个/最后一个子元素合并

1
2
3
<div class="parent">
<div class="child">子元素</div>
</div>
1
2
3
.parent { margin-top: 20px; }
.child { margin-top: 30px; }
/* 父元素实际margin-top为30px */

3. 空块级元素的上下边距合并

1
<div class="empty"></div>
1
2
3
4
5
6
.empty {
margin-top: 20px;
margin-bottom: 30px;
height: 0;
}
/* 实际占位高度为30px(取较大值) */

二、触发外边距合并的条件

  1. 垂直方向:只发生在垂直方向(上下margin),水平方向不会合并
  2. 块级元素:只针对块级元素的普通流布局(不包括浮动和绝对定位元素)
  3. 无间隔:元素之间没有被padding、border、clear或内容分隔

三、解决方案(阻止外边距合并)

1. 添加边框(border)或内边距(padding)

1
2
3
4
5
.parent {
border-top: 1px solid transparent; /* 任意颜色 */
/* 或 */
padding-top: 1px;
}

2. 创建BFC(块级格式化上下文)

1
2
3
4
5
6
7
8
9
10
.parent {
overflow: hidden; /* 或auto, scroll */
/* 其他创建BFC的方式:
display: flow-root;
float: left/right;
position: absolute/fixed;
display: inline-block;
contain: layout;
*/
}

3. 使用浮动或定位

1
2
3
4
5
.child {
float: left; /* 或right */
/* 或 */
position: absolute;
}

4. 使用Flexbox或Grid布局

1
2
3
4
5
.parent {
display: flex;
/* 或 */
display: grid;
}

5. 添加间隔内容

1
2
3
4
5
<div class="parent">
<!-- 添加任意间隔内容 -->
<div style="content: ''; display: block; height: 0.01px;"></div>
<div class="child">子元素</div>
</div>

四、实际应用建议

  1. 全局重置(推荐方案):
1
2
3
body {
display: flow-root; /* 创建BFC且无副作用 */
}
  1. 组件开发:在组件容器上使用overflow: hiddenpadding

  2. 布局系统:使用Flex/Grid布局可避免多数外边距合并问题

  3. 调试技巧:在浏览器开发者工具中,合并的外边距会显示为半透明区域

五、特殊注意事项

  1. 负边距合并:负边距合并时,计算规则为:

    • 同号取绝对值大的
    • 异号则相加(正+负)
  2. 多层嵌套合并:外边距可能跨多级父子元素合并

  3. 现代布局影响:Flex和Grid布局中的子项不会与容器发生外边距合并

理解外边距合并机制可以帮助开发者更精确地控制页面间距,避免意外的布局问题。在多数现代项目中,使用Flex/Grid布局或display: flow-root是最优雅的解决方案。

020-@Media与vh wh

响应式布局核心技术详解:媒体查询与视口单位

一、媒体查询(Media Queries)

1.1 基本语法结构

1
2
3
@media 媒体类型 and (媒体特性) {
/* 满足条件时应用的CSS规则 */
}

1.2 常用媒体类型

类型 描述
all 所有设备(默认)
screen 屏幕设备(电脑、手机等)
print 打印机/打印预览模式
speech 屏幕阅读器

1.3 核心媒体特性

视口相关

1
2
3
4
5
6
7
8
9
10
11
12
/* 最大宽度(移动优先常用) */
@media (max-width: 768px) { ... }

/* 最小宽度(桌面优先常用) */
@media (min-width: 992px) { ... }

/* 范围查询(推荐写法) */
@media (min-width: 576px) and (max-width: 1199px) { ... }

/* 设备方向 */
@media (orientation: portrait) { ... } /* 竖屏 */
@media (orientation: landscape) { ... } /* 横屏 */

显示特性

1
2
3
4
5
/* 像素比(视网膜屏检测) */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { ... }

/* 首选配色方案 */
@media (prefers-color-scheme: dark) { ... } /* 深色模式 */

1.4 实用代码示例

移动优先断点设置

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 超小设备 (<576px) - 默认样式无需媒体查询 */

/* 小设备 (≥576px) */
@media (min-width: 576px) { ... }

/* 中等设备 (≥768px) */
@media (min-width: 768px) { ... }

/* 大设备 (≥992px) */
@media (min-width: 992px) { ... }

/* 超大设备 (≥1200px) */
@media (min-width: 1200px) { ... }

打印样式优化

1
2
3
4
5
@media print {
body { font-size: 12pt; }
.no-print { display: none; }
a::after { content: " (" attr(href) ")"; }
}

二、视口单位(Viewport Units)

2.1 单位定义

单位 描述 计算基准
vw viewport width(视口宽度) 1vw = 视口宽度的1%
vh viewport height(视口高度) 1vh = 视口高度的1%
vmin viewport minimum(最小尺寸) 取vw和vh中的较小值
vmax viewport maximum(最大尺寸) 取vw和vh中的较大值

2.2 实际应用场景

全屏布局

1
2
3
4
5
6
7
.header {
height: 10vh; /* 始终占视口高度的10% */
}

.main-content {
height: 80vh; /* 占视口高度的80% */
}

响应式字体

1
2
3
4
5
6
7
h1 {
font-size: calc(16px + 1vw); /* 基础16px + 视口宽度1% */
}

p {
font-size: max(14px, 1.2vmin); /* 不小于14px */
}

等比例缩放元素

1
2
3
4
.square {
width: 50vmin;
height: 50vmin; /* 始终保持正方形 */
}

2.3 解决移动端视口问题

1
2
<!-- 必须设置viewport meta标签 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

三、组合应用技巧

3.1 响应式网格系统

1
2
3
4
5
6
7
8
9
10
.grid-item {
width: 100%;
}

@media (min-width: 768px) {
.grid-item {
width: 50vw;
max-width: 400px;
}
}

3.2 自适应间距

1
2
3
4
5
6
7
8
9
.container {
padding: 5vmin; /* 在小设备上减少间距 */
}

@media (min-width: 1200px) {
.container {
padding: 3rem; /* 大屏幕上使用固定单位 */
}
}

3.3 视差滚动效果

1
2
3
4
.parallax-section {
height: 100vh;
background-attachment: fixed;
}

四、常见问题解决方案

4.1 移动端vh单位问题

1
2
3
4
5
6
7
8
9
10
// 先通过JS设置CSS变量
document.documentElement.style.setProperty(
'--vh',
`${window.innerHeight * 0.01}px`
);

// CSS中使用
.element {
height: calc(var(--vh) * 100);
}

4.2 媒体查询与单位组合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 基础字体使用vw单位 */
body {
font-size: 2vw;
}

/* 在大屏幕上限制最大尺寸 */
@media (min-width: 1200px) {
body {
font-size: 24px; /* 2vw of 1200px = 24px */
}
}

/* 在超小屏幕上保证可读性 */
@media (max-width: 480px) {
body {
font-size: 16px;
}
}

五、现代响应式设计最佳实践

  1. 移动优先原则:先写移动端样式,再通过媒体查询增强
  2. 相对单位优先:多用vw/vh/%/em/rem,少用px
  3. 断点基于内容:根据内容布局需要设置断点,而非特定设备尺寸
  4. 组合使用技术
    • 媒体查询处理整体布局变化
    • 视口单位实现弹性尺寸
    • Flexbox/Grid处理微观布局