盒模型相关汇总(分类、获取宽高、边距重叠、BFC)

框架

在这里插入图片描述

基本概念

CSS 框模型实质上是一个包围每个 HTML 元素的框
在这里插入图片描述
标准模型和ie模型的区别是计算宽width高height的不同。
标准模型width不计算padding和border;
ie模型width计算padding 和border;

标准盒模型(W3C)

设置的宽高是对实际内容content的宽高进行设置,内容周围的border和padding另外设置;

即元素实际的宽高为:
width【height】= 设置的content的宽【高】 + padding + border

IE盒模型(怪异)

设置的宽高是对实际内容content + 内边距(padding)+边框(border)之和的width和height进行设置的;

总之就是:
标准模型的宽高为content的宽高
IE模型的宽高包括border

标准模型:box-sizing:content-box
IE模型:box-sizing:border-box

相关规则

在这里插入图片描述

块级元素

在这里插入图片描述
在块级元素的水平七属性中,只有margin和width可以使用auto的值
也就是说,只有margin-left、width和margin-right这三个属性可以使用auto值。这正是此处要讨论的核心问题,即在上述三个属性分别取不同的auto值和长度值,形成不同组合的情况下,相应块级元素盒子中各部分的宽度是如何确定的?如图
在这里插入图片描述

总结:

在width属性的值设置成auto的情况下,块级元素内容区的宽度取决于左右外边距是否明确设置了值。如果左右外边距值都是auto,则左右外边距的值都会被重置为默认的值0;如果左右外边距中只有一个值是auto,则该值被重置为0,另一个值有效;如果左右外边距都设置了明确的值,两个值都将有效,此时元素内容区的宽度就是父元素的宽度减去左右外边距后的值。需要说明的是,左右外边距的默认值是0,这意味着如果没有在CSS规则中声明margin-left或者margin-right,它们就会使用默认值0。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
在width属性的值设置为大于0的值的情况下,块级元素内容区的宽度就是由width属性设置的值。此时,左右外边距的值如果都是auto,则会使块级元素在其父元素中居中;如果左右外边距中只有一个值是auto,则明确设置的值有效,auto值会自动适应剩余的宽度;如果左右外边距都设置了明确的值,那么在从左往右阅读的语言中,会把右外边距的值重置为auto。

行内元素

行内元素的例子有a、img、span、input等。对于行内元素,又可以进一步分为可替换行内元素和不可替换行内元素,两者的区别在于元素中所包含的内容是否直接显示在页面中。
不可替换的行内元素,如a元素中的链接文本会直接显示在网页中;而可替换的行内元素,如img,当它在网页中显示时会被其src属性指向的图像替代,还有input , textarea , select , object,。

行内元素设置width, height无效(对于行内非替换元素来说)。行内元素不能包含块级元素
对于大部分行内元素都是不可替换元素,因此针对这部分元素有以下特性:

对于padding和margin:
上下margin无效
在这里插入图片描述
上下padding不正常
上边说有也有 但是很明显有bug
下边框确实有,但是只是扩大的范围而为扩大盒子本身大小,可以看到把下边的元素覆盖了一部分。
在这里插入图片描述

行内可替换元素

有些资料也把这些元素称为行内块元素
他们可以设置宽高 padding margin也是正常的

JS如何设置/获取盒模型对应的宽高

dom.style.width/height:内联样式的宽高
dom.currentStyle.width/height:渲染后的最终宽高(IE)
window.getComputedStyle(dom).width/height:DOM标准,不支持IE
dom.getBoundingClientRect().width/height:计算元素的绝对位置(视窗左顶点为起点,含left/right/height/width)
dom.offsetWidth/offsetHeight【常用】

dom.style.width/height

通过style样式获取,只能取到行内样式的宽和高,style 标签中和 link 外链的样式取不到

element.style.xxx 这种只能取得内嵌样式的属性,获取样式能读能写

dom.currentStyle.width/height

取到的是最终渲染后的宽和高,如果有设置宽高,则不论哪种盒模型获取到的都是设置的宽高,只有IE兼容
element.currentStyle[xxx] 可以取得内部和外部样式,但是只兼容ie浏览器,获取的样式只能读

document.getComputedStyle(dom,null).width/height

取到的是最终渲染后的宽和高,如果有设置宽高,则不论哪种盒模型获取到的都是设置的宽高,和currentStyle相同,但是兼容性更好,IE9 以上支持。

getComputedStyle()方法,
第一个参数:取得计算样式的元素;
第二个参数:一个伪元素字符串(例如“:after”),如果不需要伪元素信息,默认为null;

eg:

let targetDom = document.querySelector('.box');
let width =  window.getComputedStyle(targetDom).width
let height = window.getComputedStyle(targetDom).height

console.log("width",width)
console.log("height",height)

如果没有设置宽高而是由内容自动撑开,那么获取到的宽高是其设置宽高的实际意义
则标准盒模型通过getComputedStyle获取到的宽高是content的值;
IE盒模型通过getComputedStyle获取到的宽高 = border + padding + content,不包括外边距;

dom.getBoundingClientRect().width/height

得到渲染后的宽和高,大多浏览器支持。IE9以上支持。
获取的都是content +padding+border的值

这个方法还可以获取到相对于视窗的位置集合

在这里插入图片描述

dom.offsetWidth/offsetHeight(常用)

同前一个API,获取到的都content +padding+border的值,兼容性最好

关于边距重叠

外边距重叠是指两个【垂直】 【相邻】的块级元素,当上下两个边距相遇时,其外边距会产生重叠现象,且重叠后的外边距,等于其中较大者。(水平方向不会发生)
在这里插入图片描述

解决边距重叠

嵌套带来的外边距合并

对于两个嵌套关系的块元素,如果父元素没有padding-top及border,则父元素的margin-top会与子元素的margin-top发生合并,合并后的外边距为两者中的较大者,父级与外面的间隔变成了该数据
在这里插入图片描述
法1,2,3
在这里插入图片描述
法4:

.parent-box::before {
    content : "";
    display :table;
}

在这里插入图片描述

兄弟元素垂直外边距坍塌

margin-bottom与margin-top之和,而是两者中的较大者

下面的BFC解决

两个inline-block并排造成的边距影响

input没加margin或者margin不够大:
在这里插入图片描述
但是当margin足够大时就会携带者img一起走
在这里插入图片描述
原因:
内联元素的默认垂真对齐方式是和基线对齐并不是和底部对齐,即默认vertical-align:baseline。

解决:
vertical-align的值设置为top(当然会改变布局 所以margin需要重新计算)
在这里插入图片描述
ps:水平方向上两个行内元素之间有空隙是因为html标签之间有空格,解决办法:
html不换行(不太行)
设置父元素的font-size为0,然后再单独设置需要写文字元素的font-size

BFC

块级格式化上下文

如何开启

  1. float不为none
  2. overflow的值不为visible
  3. display的值为inline-block、table-cell、table-caption
  4. position不为static/relative
  5. 根元素

布局规则

(黄色标记的用于下方的应用)

  1. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  2. BFC的区域不会与float box重叠
  3. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此
  4. 计算BFC的高度时,浮动元素也参与计算

应用

自适应两栏布局

<style>
    body {
        width: 300px;
        position: relative;
    }
 
    .aside {
        width: 100px;
        height: 150px;
        float: left;
        background: #f66;
    }
 
    .main {
        height: 200px;
        background: #fcc;
    }
</style>
<body>
    <div class="aside"></div>
    <div class="main"></div>
</body>
.main {
    overflow: hidden;
}

根据 BFC的区域不会与float box重叠 ,所以可以触发main生成BFC实现自适应两栏布局

原本:
在这里插入图片描述

开启BFC后:
在这里插入图片描述
新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄

防止垂直margin重叠

由于属于同一个BFC的两个相邻Box的margin会发生重叠

因此只要两个元素不属于同一个BFC即可

那么就可以在其中一个盒子的外面再包裹一个父盒子,在父盒子上开启BFC。这里容易直接在原本的盒子上开启BFC,但我是这样理解的,根据

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素

原本的元素不过是变成了这个容器而已,它本身仍和另外一个元素处于同一个BFC容器里,所以要清除margin带来的影响,还是需要使两个元素不属于同一个BFC

清除内部浮动

清除内部浮动,则把装浮动元素的容器开启BFC即可

因为计算BFC的高度时,浮动元素也参与计算

最后 关于DOCTYPE

我们在编写页面代码时应尽量使用标准的W3C模型(需在页面中声明DOCTYPE类型),这样可以避免多个浏览器对同一页面的不兼容。
因为若不声明DOCTYPE类型,IE浏览器会将盒子模型解释为IE盒子模型,FireFox等会将其解释为W3C盒子模型;若在页面中声明了DOCTYPE类型,所有的浏览器都会把盒模型解释为W3C盒模型。
参考:
W3C规范
CSS盒模型的面试六问你能答出几个?
前端面试2:CSS盒模型
CSS盒模型详解
透彻理解块级元素的宽度
简要剖析CSS之vertical-align

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值