资讯专栏INFORMATION COLUMN

【前端芝士树】详解CSS盒模型、BFC、OffsetWidth&ClientWidth&am

binta / 1403人阅读

摘要:提供了糟糕的支持,而虽然接近标准,但依旧未能完全正确的支持标准。尽管修复了许多的问题,但是依然延续实现中的其它故障主要是盒模型问题。因此大部分的声明将触发严格模式即依据标准的规则渲染网页。

深入理解CSS盒模型、BFC、OffsetWidth&ClientWidth&ScrollWidth
本文将从盒模型开始,一步步涉及一些常见的前端笔试和面试点
主要参考自第一篇文章,然而笔者在读的时候未觉详尽,便又去网上查阅了一番,扩充了其内容,希望也能给同学们提供一些参考。

下面本文章将会从以下几个方面谈谈盒模型。

基本概念:标准模式和怪异模式,标准模型和IE模型

CSS如何设置这两种模型

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

实例题(根据盒模型解释边距重叠)

BFC(边距重叠解决方案)

1.盒模型是什么

2018搜狐前端笔试题
盒模型本质上是用以封装HTML元素的概念盒子,它包含了边距,边框,填充以及实际内容。
即由外向里是 margin, border, padding, content

2.为什么会有两种不同的盒模型(标准模式和怪异模式)

在了解两种不同的盒模型之前,需要先了解一下为什么会产生两种不同的盒模型。

当年,Netscape4(译注:网景公司早期的浏览器)和IE4(微软公司早期的浏览器)实现CSS机制时,并没有遵循W3C提出的标准。Netscape4 提供了糟糕的支持,而IE4 虽然接近标准,但依旧未能完全正确的支持标准。尽管IE 5 修复了IE4 许多的问题(bugs),但是依然延续CSS实现中的其它故障(主要是盒模型(box model)问题)。

然而随着标准一致性变得越来越重要,浏览器开发商不得不面临一个艰难的抉择:逐渐遵循W3C的标准是前进的方向。但是改变现有CSS的实现,完整去遵循标准,会使许多网站或多或少受到破坏。如果浏览器突然以正确的方式解析现存的CSS,陈旧的网站显示必然受到影响。

于是,所有的浏览器开始提供两种模式:怪异模式(即兼容模式 Quirks Mode/Compalibility Mode)服务于旧式规则,严格模式(即标准模式 Standard Mode/Strict Mode)服务于标准规则。Mac平台的IE浏览器最先实现这两种模式,Mozilla, Safari、Opera和Windows平台的IE6也相继实现了这两种模式。Windows平台的IE5和Netscape4则只提供了怪异模式。

选择使用哪种模式需要一个触发器,而 “DOCTYP切换” 则用于此目的。依照标准,任何一个(X)HTML文档必须拥有一个DOCTYPE(译注:DTD(文档类型定义)是一组机器可读的规则,它们指示(X)HTML文档中允许有什么,不允许有什么,DOCTYPE正是用来告诉浏览器使用哪种DTD,一般放在(X)HTML文档开头声明)用以告诉其他人这个文档的类型风格

产生于标准化浪潮以前的网页并没有DOCTYPE声明。因此"没有DOCTYPE"意味着触发怪异模式:既依据旧式的CSS规则渲染网页。

相反,如果开发者明确知道包含DOCTYPE,他们应该明白他们想要怎么做。因此大部分的DOCTYPE声明将触发严格模式:即依据标准的CSS规则渲染网页。

任何新的或未知的DOCTYPE将触发严格模式。

一些页面依据怪异模式而写,但是却包含DOCTYPE。这种情况下各个浏览器依据自己的DOCTYPE规则列表来触发怪异模式。

所有IE的触发 —— 在DTD声明前加上HTML注释
只要在DTD声明前加注释或者任何标签即可
xml

对于以上两种不同的网页模式,产生了两种不同的盒模型,一个是标准模型,一个是IE模型

标准模型的宽高 = 内容(content)的宽高,

IE盒模型的宽高 = 内容(content) + 填充(padding) + 边框(border)的总宽高。

3.通过CSS3设置两种模型

这里用到了 CSS3 的属性 box-sizing

标准模型
box-sizing:content-box;

IE模型
box-sizing:border-box;

4.通过JavaScript获取宽高

通过JS获取盒模型对应的宽和高,有以下几种方法:
为了方便书写,以下用dom来表示获取的HTML的节点。

var body = document.getElementsByClassName("container"); var dom = document.getElementById("contentBox");
1.dom.style.width/height

  这种方式只能取到dom元素内联样式所设置的宽高,也就是说如果该节点的样式是在style标签中或外联的CSS文件中设置的话,通过这种方法是获取不到dom的宽高的。

console.log("Dom.style.width:" + dom.style.width); //100px
2.dom.currentStyle.width/height

  这种方式获取的是在页面渲染完成后的结果,就是说不管是哪种方式设置的样式,都能获取到,但这种方式只有IE浏览器支持。

console.log("Dom.currentStyle.width:" +  dom.currentStyle.width); //Cannot read property "width" of undefined
3.window.getComputedStyle(dom).width/height

  这种方式的原理和2是一样的,这个可以兼容更多的浏览器,通用性好一些。

console.log("Window.getComputedStyle(dom).width" + window.getComputedStyle(dom).width); //100px
4.dom.getBoundingClientRect().width/height

getBoundingClientRect 用于获取某个元素相对于视窗的位置集合
通过计算元素的位置,来获取对应的宽高

console.log("Dom.getBoundingClientRect().width: " + dom.getBoundingClientRect().width); //160
5.dom.offsetWidth/offsetHeight

对象所在元素的实际宽度

console.log("Dom.offsetWidth: " + dom.offsetWidth); //160

具体情况如图所示
其中,盒模型为标准模型,元素内容宽度为100px, padding宽度为10px,border宽度为20px, margin宽度为30px

5.DOM属性之 OffsetWidth / ClientWidth / ScrollWidth

OffsetWidth 对象所在元素的实际宽度

dom.offsetWidth = dom_content + padding + border(包含滚动条)+ margin

ClientWidth 对象内容的可视区域的宽度

dom.clientWidth = dom_content + padding(不包含滚动条)

ScrollWidth 对象的实际内容的宽度(包含滚动区域中未显示完全的部分)

dom.scrollWidth = real_content + padding

6.边距重叠

什么是边距重叠

如下图,父元素没有设置margin-top,而子元素设置了margin-top:20px;可以看出,父元素也一起有了边距。




    
    Document
    


    

此部分是能更容易看出让下面的块的margin-top。

子元素

margin-top:20px;

父元素

没有设置margin-top
7.边距重叠解决方案(BFC)

首先要明确BFC是什么意思,其全英文拼写为 Block Formatting Context 直译为“块级格式化上下文”

BFC的原理

内部的box会在垂直方向,一个接一个的放置 每个元素的margin box的左边,与包含块border

box的左边相接触(对于从做往右的格式化,否则相反)

box垂直方向的距离由margin决定,属于同一个bfc的两个相邻box的margin会发生重叠 bfc的区域不会与浮动区域的box重叠

bfc是一个页面上的独立的容器,外面的元素不会影响bfc里的元素,反过来,里面的也不会影响外面的

计算bfc高度的时候,浮动元素也会参与计算

怎么去创建BFC

float属性不为none(脱离文档流)

position为absolute或fixed

display为inline-block,table-cell,table-caption,flex,inine-flex

overflow设置为scroll/hidden/overlay/auto

根元素

应用场景

自适应两栏布局

清除内部浮动

防止垂直margin重叠

看一个垂直margin重叠例子
 Top margin-bottom: 30px
 Bottom margin-top: 50px
.top{ margin-bottom:30px; } .bottom{ margin-top: 50px; } .top, .bottom{ width: 100%; height: 100px; line-height: 100px; background: cornflowerblue; }

效果图

用BFC可以解决垂直margin重叠的问题

方法一 采用float或者position设置为absolute/fixed 脱离文档流
float: left;
position: absolute;// 或者fixed
方法二 设置display为inline-block,table-cell,table-caption,flex,inine-flex
display: inline-block;

方法三 添加一个父元素包裹,并设置overflow为scroll/hidden/overlay/auto
 Top margin-bottom: 30px
 Bottom margin-top: 50px

参考链接

《深入理解CSS盒模型》 https://www.cnblogs.com/cheng...

《怪异模式和严格模式》 http://blog.sina.com.cn/s/blo...

《标准模式与怪异模式的共存缘由及其使用》 https://blog.csdn.net/liyuans...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/113609.html

相关文章

  • 芝士整理】CSS基础图谱

    摘要:为了实现文字环绕效果,规范规定的措施是使父容器塌陷,元素脱离文档流浮动产生,元素周围的内容转换为围绕元素排列。 选择器注意点 属性选择器 [attr^=value] - 开头或全等 [attr$=value] - 结尾或全等 [attr*=value] - 包含值 [attr~=value] - 字符串包含 选择器组 A > B - 直接子节点 A + B - 下一个兄弟节点 A...

    iOS122 评论0 收藏0
  • 知识解读:JS属性scrollTop clientHeight scrollHeight

      现在关于讲述scrollTop、clientHeight、 scrollHeight 的内容讲的都不深,这篇文章就深入了解下。这篇文章主要给大家讲述下这些概念的理解,并总结了这些概念彼此之间的数量关系和应用场景。  1.clientWidth、clientHeight、clientLeft、clientTop  1.1 clientWidth  (1)含义:只读属性,表示元素的内部宽度,单位为...

    3403771864 评论0 收藏0
  • 前端芝士】纯CSS实现多行文本溢出显示省略号

    摘要:前端芝士树纯实现多行文本溢出显示省略号使用来控制行数由于用来限制在一个块元素显示的文本的行数这是一个不规范的属性,它没有出现在规范草案中,为了实现该效果,它需要组合其他外来的属性。 【前端芝士树】纯CSS实现多行文本溢出显示省略号 使用-webkit-line-clamp来控制行数 由于-webkit-line-clamp 用来限制在一个块元素显示的文本的行数,这是一个不规范的属性(u...

    CNZPH 评论0 收藏0
  • DOM模型

    摘要:中的盒模型传统盒模型在传统盒子模型中我们说的宽度和高度是指该块元素内容的宽度和高度。在这个基础上我们在修改或者块元素的宽度讲不会发生变化。 showImg(https://segmentfault.com/img/bVbnygm?w=320&h=292); CSS中的盒模型 传统盒模型 在传统盒子模型中我们说的宽度和高度是指该块元素内容的宽度和高度。 而一个块元素的宽度是 ...

    djfml 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<