作者:陈大鱼头github:KRISACHAN盒模型CSS盒模型描述了为文档树中的元素生成的矩形框,并根据视觉格式化模型进行布局。矩形框生成的元素和对应的视觉格式化模型(visualformattingmodel)。基本盒模型(CSSbasicboxmodel)当浏览器渲染一棵渲染树时,浏览器的渲染引擎根据基本盒模型(CSSbasicboxmodel)将所有元素划分为矩形盒。盒子的外观和属性由CSS决定。我们在浏览器控制台输入以下代码可以看到页面的每个元素都被一个矩形包裹起来,这些都是盒子。$$('*').forEach(e=>{e.style.border='1pxsolid';})说明如下:视觉格式化模型CSS视觉格式化模型)是转换文档中元素的实际算法按照基本盒子模型(CSSbasicboxmodel)一个一个地放入盒子中。官方的说法是:它指定了用户代理如何处理介质中的文档树(documenttree)。每个盒子的布局由以下因素决定:盒子大小盒子类型:行内盒子(inline)、行内级盒子(inline-level)、原子级盒子(atomicinline-level)、块级盒子(block-level))Positioning:normalflow,floating,absolutepositioning当前框在文档树中的子元素或兄弟元素视口(viewport)的大小和位置框内图像的大小其他一些外部因素视觉格式化模型(visualformattingmodel)所有的计算都依赖于一个矩形的边界,称为包含块。通常,(元素的)生成框将扮演其后代元素的包含块的角色;我们称之为:(元素的)框架为其后代节点构建包含块。包含块是一个相对的概念。例子如下:
上面的代码是一个例子,div和table都包含块。div是table的包含块,table也是td的包含块,不是绝对的。插图:(图片来自w3help):boxgenerationboxgeneration是CSS可视化格式化模型的一部分,用于从文档元素生成box。框的类型取决于CSS显示属性。格式化上下文是定义盒子环境的规则,不同格式化上下文下的盒子表现不同。下面是框相关概念的定义:block-levelelement当一个元素的显示为block、list-item或table时,就是块级元素。Block-levelboxesBlock-levelboxes用于描述它与它的父元素和兄弟元素之间的关系。每个块级框都参与块格式化上下文的创建。每个块级元素都会生成至少一个块级框,即主块级框(principalblock-levelbox)。主块级框包含后代元素生成的框和内容,也会参与定位方案。块级盒同时也是块容器盒的称为块盒。匿名框在某些情况下需要可视化格式化时,需要添加一些辅助框。这些框不能被CSS选择器选中,即所有可继承的CSS属性值都是inherit,所有不可继承的CSS属性值都是initial。因此得名匿名盒。内联元素当元素显示为内联、内联块或内联表时,它就是内联级元素。显示时可以与其他内联级内容一起显示为多行。行内框行内级元素生成行内级框,它们也参与创建行内格式化上下文。匿名内联框类似于块框,CSS引擎有时会自动创建一些内联框。这些行内框不能被选择器选中,所以它们是匿名的。它们从父元素继承那些可继承的属性,其他属性保持初始默认值。行框行框由内联格式化上下文创建,用于显示一行文本。在块盒内,线盒总是从块盒的一侧延伸到另一侧。当有浮动元素时,行框从左浮动元素的右边缘延伸到右浮动元素的左边缘。run-inbox(CSS2.1标准中移除)run-inbox可以通过display:run-in设置,可以是blockbox也可以是inlinebox,具体取决于后面的box。类型。BFC(Blockformattingcontexts)BFC的概念来源于视觉格式化模型中的正常流程。定义浮动的、绝对定位的元素、块容器(如inline-blocks、table-cells和table-captions)以及溢出但不可见的元素(除非值已传播到视口)是为了建立BFC(块格式化上下文)的条件。在BFC(Blockformattingcontexts)中,一个框在包含块中垂直排列,不重叠,两个兄弟框之间的直接垂直距离由边距决定。float也是一样(虽然有可能两个box之间的距离会因为float而变小),除非box创建了一个新的BFC。鱼头注:简单来说,BFC就是一个独立的盒子,不与外界干扰,不受外界干扰(/ω\)。块级相对计算正常流中的块级和非替换元素'margin-left'+'border-left-width'+'padding-left'+'width'+'padding-right'+'border-right-width'+'margin-right'=containingblock的宽度上面的计算方式是基于writing-mode:ltr,如果是另外一个顺序写的,就按照这个顺序计算。如果宽度不是auto或者'border-left-width'+'padding-left'+'width'+'padding-right'+'border-right-width'的结果大于包含块的宽度,对于以下规则,它被认为是零。如果只有一个值被指定为“auto”,它会使用来自equals的值。如果宽度设置为auto,任何其他auto值变为0,宽度将跟随所有框。如果'margin-left'和'margin-right'都是auto,元素将相对于包含块的边距水平居中。浮动和非替换元素的'margin-left'和'margin-right'指定为0如果两者都是auto。如果宽度为auto,则使用shrink-to-fit宽度计算方式(CSS2.2没有定义精确算法)。那么shrink-to-fit的近似计算方法是:min(max(首选最小宽度,可用宽度),首选宽度)。非替换元素的绝对定位'left'+'margin-left'+'border-left-width'+'padding-left'+'width'+'padding-right'+'border-right-width'+'margin-right'+'right'=包含块的宽度如果'left','width'和'right'都是'auto',则设置'margin-left'和'margin-的'auto'值右'第一个是0。如果“left”、“width”和“right”不是“auto”,则将使用实际值。如果'margin-left'和'margin-right'都为0,则根据'left'、'width'和'right'是否为'auto'来计算。如果“宽度”的值对于一个方向值是“自动”而不是对于“另一个方向值”,则使用收缩以适合算法计算宽度。如果一个值是“auto”而另外两个不是,则该值是使用shrink-to-fit计算的。上面的计算方式是基于writing-mode:ltr,如果是按照另外的顺序写的,就按照那个顺序计算。鱼头注:这里有一个特别的点。在MDN中,flexbox和gridbox仍然算在BFC中,但在最新的规范中,它们已经从BFC中分离出来,成为一个独立的CSS模块。内容如下:CSSFlexibleBoxLayoutModuleLevel1CSSGridLayoutModuleLevel2如果你喜欢讨论技术,或者对本文有什么意见或建议,非常欢迎加鱼头微信好友一起讨论。当然,鱼头也希望和你聊聊生活。谈爱好,谈世界。鱼头微信公众号是:krisChans95,也可以扫描二维码加好友,备注“顺丰”即可