CSS盒模型 - 官方文档总结

简介: CSS盒模型 - 官方文档总结


原文链接: segmentfault.com

一直对盒模型的了解很零碎,学习都来源于各个文章的只言片语,这样学来的既不完善,也不持久。最近通读了w3的官方文档,对其中的内容进行一点归纳吧。


盒子的概念

盒子模型指的是浏览器将文档流从视觉上渲染为不同矩形框的组合。

浏览器将文档流中的每个元素都渲染为一个矩形框,其包含内容区域(如文本、图片)和可选的margin/border/padding三个区域,中文名为外边距、边框和填充。如下图所示:

这四个区域每一个都可以划分为上下左右4个部分的边界,如上边距、下边距,上边框、下边框等。

 

内容边界:包裹着元素宽度和高度确定的盒子的四个线段组成。
填充边界:包裹着元素填充区域的四个线段组成,如果填充宽度为0,则等于内容边界。
边框边界:包裹着元素边框区域的四个线段组成,如果边框宽度为0,则等于填充边界。
外边距边界:包裹着元素外边距区域的四个线段组成,如果外边距宽度为0,则等于外边距边界。

其中内容区域的盒子的宽度和高度由几个因素来进行确定,是否设置了宽度和高度值,是否包含文本内容或者其他的盒子,盒子类型是否为table相关等等。

内容和填充区域的颜色由background属性来设置,边框区域的颜色由border-color || color其中一个属性来设置,外边距区域的颜色为transparent透明色。


实例

下面的插图展示了margin/border/padding如何被渲染(图二是更为详细的切分):

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Examples of margins, padding, and borders</TITLE>
    <STYLE type="text/css">
      UL { 
        background: yellow; 
        margin: 12px 12px 12px 12px;
        padding: 3px 3px 3px 3px;
                                     /* No borders set */
      }
      LI { 
        color: white;                /* text color is white */ 
        background: blue;            /* Content, padding will be blue */
        margin: 12px 12px 12px 12px;
        padding: 12px 0px 12px 12px; /* Note 0px padding right */
        list-style: none             /* no glyphs before a list item */
                                     /* No borders set */
      }
      LI.withborder {
        border-style: dashed;
        border-width: medium;        /* sets border width on all sides */
        border-color: lime;
      }
    </STYLE>
  </HEAD>
  <BODY>
    <UL>
      <LI>First element of list
      <LI class="withborder">Second element of list is
           a bit longer to illustrate wrapping.
    </UL>
  </BODY>
</HTML>

需要注意的是:

  1. 内容区域的计算是自上而下的,所有的li元素的内容区域计算都基于ul父元素。
  2. margin盒子包含了content/padding/border/margin四部分的总和,在纵向上会出现margin的合并。
  3. margin的颜色总是透明的,所以颜色会是父元素的透射颜色。


margin属性

margin属性包括margin-top/margin-right/margin-bottom/margin-left 和 margin

 

margin-top/margin-right/margin-bottom/margin-left
值:<margin-width> || inherit
初始值: 0
适用于:除了table展示类型的所有元素,table类型里依然适用的有`table-caption/table/inline-table`
继承: 否
百分比:根据父包裹容器的宽度
计算值:指定的百分比或固定值

需要注意:margin-top/margin-bottom属性对行间元素不起作用。

margin是以上四种属性的简写,如果只有一个值,则设置所有边界;两个值则第一个值为top/bottom值,第二个值为left/right值;三个值则第一个值为top值,第二个值为left/right值,第三个为bottom值;四个值则分别对应top/right/bottom/left四个边界。

 

body { margin: 2em }         /* all margins set to 2em */
body { margin: 1em 2em }     /* top & bottom = 1em, right & left = 2em */
body { margin: 1em 2em 3em } /* top=1em, right=2em, bottom=3em, left=2em */


margin的边界合并

在CSS里,两个相邻元素(并不一定是兄弟元素)的外边距将会发生合并为一个外边距,这个过程我们成为collapse。这个过程只会发生在垂直方向上的margin,合并结果是所有外边距的最大值。

边界合并的设置是为了元素布局的合理展示,如段落间的距离不会成为顶部的两倍。

边界的合并适用于margin-top/margin-bottom,不仅仅包括兄弟元素的合并,还有父子元素甚至自身的上下边距合并。

注意:只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。

下图展示margin合并的效果图(来源于 w3school文档):

兄弟元素外边距合并:

父子元素外边距合并:

自身元素外边距合并:

另外官方文档里关于合并还有很多的特殊情况,不再一一说明,粘贴源文档:

 

Adjoining vertical margins collapse, except:
Margins of the root element's box do not collapse.
If the top and bottom margins of an element with clearance are adjoining, its margins collapse with the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block.
Horizontal margins never collapse.
Two margins are adjoining if and only if:
both belong to in-flow block-level boxes that participate in the same block formatting context
no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
 - top margin of a box and top margin of its first in-flow child
 - bottom margin of box and top margin of its next in-flow following sibling
 - bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
 - top and bottom margins of a box that does not establish a new block formatting context and that has zero computed 'min-height', zero or 'auto' computed 'height', and no in-flow children
A collapsed margin is considered adjoining to another margin if any of its component margins is adjoining to that margin.
Note. Adjoining margins can be generated by elements that are not related as siblings or ancestors.
Note the above rules imply that:
 - Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
 - Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
 - Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
 - Margins of inline-block boxes do not collapse (not even with their in-flow children).
 - The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
 - The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
 - The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.
 - A box's own margins collapse if the 'min-height' property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a 'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.
When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins' widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.
If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it. In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.
If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as the parent's.
Otherwise, either the element's parent is not taking part in the margin collapsing, or only the parent's bottom margin is involved. The position of the element's top border edge is the same as it would have been if the element had a non-zero bottom border.
Note that the positions of elements that have been collapsed through have no effect on the positions of the other elements with whose margins they are being collapsed; the top border edge position is only required for laying out descendants of these elements.

顺便讲一个常见的bug:垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距。其原因为父元素和第一个子元素的外边距进行合并,并选取其最大值,即第一个元素的上边距,导致撑开父元素上边距。解决方案为:设置父元素的border或padding将子元素控制在父元素content内部,防止发生margin合并,即给外部div设置一个透明的1像素的border-top即可。

 

.outer-box{
  border-top:1px solid transparent;
}


Padding属性

padding属性包括padding-top/padding-right/padding-bottom/padding-left 和 padding

 

padding-top/padding-right/padding-bottom/padding-left
值:<padding-width> || inherit
初始值: 0
适用于:除了`table-row-group/table-header/group/table-footer-group/table-row/table-column-group/table-column`的所有元素
继承: 否
百分比:根据父包裹容器的宽度
计算值:指定的百分比或固定值

需要注意:margin-top/margin-bottom属性对行间元素不起作用,且值不能为负。

margin是以上四种属性的简写,设置的内容和上面一致,元素的个数和含义与margin相同。


border属性

border属性包括border-width/border-color/border-style,而其中每一个都可以切分为4块,如border-left-width/border-top-color。对于不同的用户代理(浏览器)会对部分的元素渲染出特定的样式来,如button,menus等。

 

border-top-width等
值:<border-width> || inherit || thin || medium || thick
初始值: medium
适用于:所有元素
继承: 否
百分比:N/A,无法设置
计算值:绝对值,如果为none/hidden则转换为0

需要注意:thin/medium/thick由不同的浏览器实现,具体的值不尽相同。

 

border-top-color等
值:<color> || transparent || inherit
初始值: color的值(字体颜色)
适用于:所有元素
继承: 否
百分比:N/A,无法设置
计算值:指定的值或者字体颜色color的值

 

border-top-style等
值:none || hidden || dotted || dashed || solid || double || groove || ridge || inset || outset || inherit
初始值: none
适用于:所有元素
继承: 否
百分比:N/A,无法设置
计算值:指定的值

需要注意:边框会绘制在所有盒子背景色的上方,在groove/ridge/inset/outset值时,具体的颜色可能会被浏览器强制修改,而不仅限于border-color属性。初始值为none,所以一定要进行设置样式,否则看不到。

 

border属性:    [ <border-width> || <border-style> || <'border-top-color'> ] || inherit

需要注意:border属性不能像其中三个子属性一样分别设置,如果设置其中一个值,则会应用到所有四条边界上。

margin是以上四种属性的简写,设置的内容和上面一致,元素的个数和含义与margin相同。

下面的两段样式只是出现的顺序不同会显示出不同的效果来,原因是设置的顺序影响到值的覆盖:

 

// 左边框为双细线和黑色
blockquote {
  border: solid red;
  border-left: double;
  color: black;
}
// 边框全部为实线和红色
blockquote {
  border-left: double;
  color: black;
  border: solid red;
}


双向上下文的行间元素的盒模型

在每一个行间元素中,浏览器需要产生每一个盒子按照视觉顺序而非逻辑顺序(也就是direction设置的方向)进行渲染。下面的两句话我实在是看不懂在讲什么,贴出原文:

 

When the element's 'direction' property is 'ltr', the left-most generated box of the first line box in which the element appears has the left margin, left border and left padding, and the right-most generated box of the last line box in which the element appears has the right padding, right border and right margin.
When the element's 'direction' property is 'rtl', the right-most generated box of the first line box in which the element appears has the right padding, right border and right margin, and the left-most generated box of the last line box in which the element appears has the left margin, left border and left padding.

   

盒模型相关的周边问题

  1. inline-block元素之间的小空白

 

 <STYLE type="text/css">
   div {background: red;}
   span {background: lightblue;}
 </STYLE>
 <BODY>
  <div>
   <span>aa</span>
   <span>bb</span>
  </div>
 </BODY>

效果入图:

原因为:HTML 中的换行符、空格符、制表符等合并为空白符, 字体大小不为 0 的情况下, 空白符自然占据一定的宽度, 因此产生了元素间的空隙.

解决方案:可以为inline-block元素设置为负的margin-left; 或父元素font-size设置为0, 子元素再重新设置回来等方法。

推荐方案:直接在HTML文档里改变文本排列,使行间元素尾标签和下一个头便签间不留任何空格,如

 

<span>
    <label>第一个元素</label>
</span><span>
    <label>第二个元素</label>
</span>

因为这样影响范围最小,不需任何额外代码。


参考文献

  1. w3c官网文档 - 盒子模型:www.w3.org/TR/CSS2/bo.…
  2. 你不知道的margin属性:louiszhai.github.io/20...元素之间空白Bug
  3. w3school - CSS外边距合并:www.w3school.com.cn/cs...


目录
相关文章
|
7月前
|
前端开发
CSS语言的盒模型
CSS语言的盒模型
|
28天前
|
存储 移动开发 前端开发
高效的 HTML 与 CSS 编写技巧,涵盖语义化标签、文档结构优化、CSS 预处理、模块化设计、选择器优化、CSS 变量、媒体查询等内容
本文深入探讨了高效的 HTML 与 CSS 编写技巧,涵盖语义化标签、文档结构优化、CSS 预处理、模块化设计、选择器优化、CSS 变量、媒体查询等内容,旨在提升开发效率、网站性能和用户体验。
41 5
|
2月前
|
前端开发 UED
CSS 盒模型
CSS盒模型是网页设计中一个重要的概念,它定义了HTML元素如何在页面上呈现及其相互关系。每个HTML元素都被视为一个矩形框,此模型涉及内容区、内边距、边框和外边距四个部分,通过控制这些部分的样式和布局,设计师可以实现多样化的页面效果。
|
4月前
|
前端开发 容器
【CSS Flexbox 探秘】弹性盒模型:揭秘网页布局的终极神器!
【8月更文挑战第25天】Flexbox 是 CSS3 中的关键特性,为网页设计提供了强大的布局能力。本文通过问答形式全面解析 Flexbox 的核心概念与属性,包括容器与项目属性,并通过示例演示如何使用 Flexbox 实现水平与垂直居中、等间距布局及响应式设计。相较于传统布局方法,Flexbox 更加灵活且简化了样式设置,同时在现代浏览器中拥有良好的支持度。掌握 Flexbox 对于提升网页布局效率至关重要。
83 1
|
4月前
|
容器 C# 开发者
XAML语言大揭秘:WPF标记的魅力所在,让你轻松实现界面与逻辑分离,告别复杂代码!
【8月更文挑战第31天】XAML提供了一种直观且易于维护的界面设计方式,使得开发者可以专注于逻辑和业务代码的编写,而无需关心界面细节。通过数据绑定、布局管理和动画效果等特性,XAML可以实现丰富的界面交互和视觉效果。在实际开发过程中,开发者应根据具体需求选择合适的技术方案,以确保应用程序能够满足用户的需求。希望本文的内容能够帮助您在WPF应用程序开发中更好地利用XAML语言。
51 0
|
4月前
|
前端开发
CSS盒模型揭秘:打造精美网页的不二法门
CSS盒模型揭秘:打造精美网页的不二法门
|
4月前
|
前端开发 开发者
几种常见的 CSS 文档应用,快看看你会几种?
几种常见的 CSS 文档应用,快看看你会几种?
|
5月前
|
前端开发 C++
CSS【详解】 标准盒模型 VS IE 盒模型
CSS【详解】 标准盒模型 VS IE 盒模型
65 0
|
6月前
|
Web App开发 前端开发 编译器
CSS3私有前缀+新增盒模型相关属性(如果想知道CSS3私有前缀、新增盒模型相关属性的知识点,那么只看这一篇就足够了!)
CSS3私有前缀+新增盒模型相关属性(如果想知道CSS3私有前缀、新增盒模型相关属性的知识点,那么只看这一篇就足够了!)
|
6月前
|
前端开发
CSS基础-盒模型:边框、内边距、外边距
【6月更文挑战第8天】Web设计中的盒模型由内容区域、内边距、边框和外边距组成,是理解页面布局的关键。内容区域包含实际内容,内边距提供间隔,边框定义元素边界,外边距控制元素间距。常见易错点包括边框宽度计算、外边距折叠和盒模型理解不透彻。通过实践和媒体查询可解决响应式设计挑战,`border-radius`可能导致圆角问题。理解盒模型并灵活应用能创建多样化布局。
111 6

热门文章

最新文章