分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

CSS外边距合并&块格式上下文

发布时间:2023-09-06 01:32责任编辑:董明明关键词:CSS
前言
问题
Margin Collapsing 外边距合并
Block Formatting Context 块格式化上下文
解决方案
参考

前言

之前在前端开发的过程中,都没有遇到外边距合并的问题(其实是因为大多时候都直接用前端样式库(〃‘▽‘〃)),这一次需要动手排一个页面,也挺简单,但是遇到了一个奇怪的问题,所以学习记录一下。

问题

测试代码如下:

<!doctype html><html class="no-js" lang=""><head> ???<meta charset="utf-8"> ???<meta http-equiv="x-ua-compatible" content="ie=edge"> ???<title>test</title> ???<meta name="description" content=""> ???<meta name="viewport" content="width=device-width, initial-scale=1"></head><style>* { ???margin: 0; ???padding: 0;}body { ???max-width: 750px; ???margin: 0 auto;}.div1 { ???background: yellow; ???height: 200px;}.div2 { ???background: blue; ???height: 200px;}.div2Child { ???background: red; ???height: 100px;}</style><body> ???<div class="div1">我是吃瓜群众</div> ???<div class="div2"> ???????<div class="div2Child" style="margin-top: 50px">我是子div</div> ???????<p style="color: white">我是父div</p> ???</div></body></html>


子div设置了margin-top之后,父div也跟着一起margin-top了。

原因如下:

Margin Collapsing 外边距合并

?

块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,其大小是组合到其中的最大外边距,这种行为称为外边距塌陷(margin collapsing),或外边距合并。

外边距合并的3中基本原因:
1、相邻的元素
毗邻的两个兄弟元素之间的外边距会合并

2、块级父元素与其第一个/最后一个子元素

  • 如果块级父元素中,不存在border, padding, inline part, block formatting context created, or clearance 来隔离第一个子元素的上边距,就会发送外边距合并现象。
  • 如果块级父元素,不存在border, padding, inline content, height, min-height, ?max-height来隔离下边距,则会和最后一个子元素合并。

3、空块元素
如果存在一个空的块级元素,不存在 border、padding、inline content、height、min-height来隔离上下外边距,那么它的上下外边距将会合并。

  • 当都为正数时,取两者中较大者。
  • 当都为负数时,取绝对值较大者。
  • 当一正一负时,取相加之和。
  • 外边距设为0时,这些规则也仍旧生效。

BFC(Block Formatting Context 块格式化上下文)与元素外边距合并 :

  • 当两个元素属于不同的BFC时,这两个元素的外边距不会合并
  • 但在同一个BFC内,两个相邻元素的外边距仍会合并。

Block Formatting Context 块格式化上下文

?

一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染出的一部分。它是块级盒模型出现的区域,也是浮动元素与其他元素进行交互的区域。

一个块格式化上下文由以下之一创建:

  • 根元素或一些包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素的 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • display隐式创建的匿名表格列,包括table, table-row, table-row-group, table-header-group, table-footer-group (这些都是html的默认样式), or inline-table
  • 具有overflow 且值不是 visible 的块元素,
  • display: flow-root
  • flex 项目
  • grid 项目
  • 多列容器(column-count 和 column-width 不是 auto, 包括 column-count: 1的元素)
  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

解决方案

知道了问题原因所在,以及了解了相关原理,就很好办了。
1、给div2设置border
为了不改变div2的大小,还需将设置 box-sizing为border-box将padding和border包含在定义的width和height之内

.div2 { ???background: blue; ???height: 200px; ???border-top: 1px solid transparent; ???box-sizing: border-box;}

2、去掉div2Child的margin,改为设置div2的padding

.div2 { ???background: blue; ???height: 200px; ???padding-top:50px; ???box-sizing: border-box;}

3、div2设置为内联元素

.div2 { ???background: blue; ???height: 200px; ???display: inline-block; ???width: 100%;}

4、清除浮动
所有浮动元素包含在div2内,增加样式clearfix

.clearfix::before, .clearfix::after{ ???overflow: hidden; ???display: table; ???visibility: hidden; ???content: ‘‘; ???clear: both;}

或者创建一个新的BFC,使其在不同的上下文中,不合并外边距。
5、给div2设置Position

.div2 { ???background: blue; ???height: 200px; ???position: absolute; ???width: 100%; ???max-width: 750px;}

6、给div2设置float,注意后面的元素需要clear浮动

.div2 { ???background: blue; ???height: 200px; ???float: left; ???width: 100%;}

7、给div2设置display

.div2 { ???background: blue; ???height: 200px; ???display: inline-block; ???/*display: table;*/ ???width: 100%;}

8、给div2设置flex

.div2 { ???background: blue; ???height: 200px; ???display: flex; ???flex-direction: column;}

万变不离其宗

参考

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context

CSS外边距合并&块格式上下文

原文地址:http://www.cnblogs.com/leestar54/p/8087679.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved