CSS进阶02-盒模型进阶

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)
(注2:更多内容请查看我的目录。)

1. 简介

前面在入门文章中讲到了盒模型还有块级元素和行内元素。现在我们来回顾并重新认识一下盒模型。

2. 再看盒模型

首先,要清楚一件事情。CSS框模型描述了为文档树中的元素生成的矩形框,并根据可视化格式模型进行布局。浏览器在解析和渲染页面时会生成DOMTree 和RenderTree(此处会在后面详细讲解)。CSS作用的是RenderTree,而盒模型就是RenderTree的节点。

每个盒子都有一个content area(例如文本,图像等)以及可选的padding area、border area盒margin area。每个区域的大小由下面定义的属性指定。

官方文档图片

margin、border、padding、content分别定义了元素四种边,然后每种类型的边的四条边定义了一个盒子,分别是content box、padding box、border box、margin box。如下图所示:


box

以下四个盒子组成了一个 box:

  1. content box:必备,由content area和4条content/inner edge组成;
  2. padding box:可选,由padding和4条padding edge组成。若padding宽度设置为0,则padding edge与content edage重叠;
  3. border box:可选,由border和4条border edge组成。若border宽度设置为0,则border edge与padding edage重叠;
  4. margin box:可选,由margin和4条margin/outer edge组成。若margin宽度设置为0,则margin edge与border edage重叠。

是不是很眼熟,是的,如果你还记得box-sizing属性的话。

CSS3中提供了一个新的属性,box-sizing,来控制和模型的表现形式。box-sizing有三个取值,分别是content-box,border-box和inherit。
(注:其实还有一个padding-box,width和height属性包括内容和内边距,但是不包括边框和外边距。只有Firefox实现了这个值,它在Firefox 50中被删除。)

  • content-box
    默认值,表现形式同W3C标准和模型。
  • border-box
    表现形式同IE盒模型,常用值,经常在css-reset中设置。
  • inherit
    规定应从父元素继承box-sizing属性的值。
    现在,我们终于明白了。所谓的W3C标准盒模型和IE盒模型只是在设置width和height时所指定的对象不同而已。W3C标准盒模型是content-box,而IE盒模型是
  • border-box。
    当然,如果没有特殊指定的情况下,我们默认是使用W3C标准盒模型。如果不想指定box-sizing,想让各浏览器都是用W3C标准盒模型,只要在html文件开头指定<!DOCTYPE html>即可。

另外,一个盒子的content area的宽高取决于如下的因素:

  1. 元素生成的盒子是否有“宽度”和“高度”属性集
  2. 盒子里是否包含文本或其他盒子
  3. 盒子是否是table
    etc...
    盒模型宽高我们会在今后详细讨论。

而一个盒子的content area,padding area和border area的背景由生成元素的background属性指定,而margin area的背景总是透明的。

3. 盒的生成与类型

上面讨论了盒子的基本组成和在不同浏览器中的表现,这一节我们来看一下盒子的类型。这里所描述的是CSS2.2中可生成的盒类型。CSS 视觉格式化模型的一部分工作是从文档元素生成盒。生成的盒拥有不同类型,并对视觉格式化模型的处理产生影响。生成盒的类型取决于 CSS 属性 display。盒的类型会影响其在视觉格式化模型中的表现。

3.1 块级元素Block-level Elements与块盒Block Boxes

块级元素是指源文档中以块(如段落)的形式被格式化,生成主要块级盒(principal block-level box)的元素。display 属性取以下值会让一个元素成为块级元素: block 、 list-item 以及 table 。
块级盒(Block-level Boxe)是参与块格式化上下文( Block Formatting Context )的盒。每个块级元素生成一个主要的块级盒( principal block-level box)。 一些元素,比如li和list-item,生成额外的盒来放置项目符号,这些额外的盒会相对于主要盒来摆放。不过多数元素只生成一个主要块级盒。
主要的块级盒( principal block-level box)将包含其后代盒和生成的内容,同时参与定位体系 (Positioning Scheme )。

在CSS 2.2中,块级盒(block-level box)也是一个块容器盒 (block container box),除非它是一个表盒(table box)或替换元素(replaced elemen)的主盒(principal box)。一个块容器盒 (block container box)要么只包含块级盒(block-level box),要么只建立一个内联的格式化上下文(Inline Formatting Context)并因此只包含行内级盒(Inline-level Boxes)。
一个主盒(principal box)是块容器盒 (block container box)的元素是一个块容器元素(block container element)。display取如下值时可以是一个非替换元素(non-replaced element)生成一个块容器(block container):'block', 'list-item' 和 'inline-block'。并非所有的块容器盒都是块级盒:非替换的行内块(non-replaced inline blocks) 和非替换的表格单元格 (non-replaced table cells) 也是块容器但不是块级的。

既是块级盒(block-level box)同时也是块容器盒 (block container box)的盒称作块盒(block box) 。

这三个术语,“块级盒”、“块容器盒”、“块盒”在意义明确时可简称为“块”(block)。

“块级盒”、“块容器盒”、“块盒”

3.2 匿名块盒(Anonymous block boxes)

有时需要添加补充性盒,这些盒称为匿名盒(anonymous boxes), 它们没有名字,不能被 CSS 选择符选中。

不能被 CSS 选择符选中意味着不能用样式表添加样式。这意味着所有继承的 CSS 属性值为 inherit ,所有非继承的 CSS 属性值为 initial 。

块容器盒要么只包含行内级盒,要么只包含块级盒。但通常文档会同时包含两者。在这种情况下,将创建匿名块盒来包含毗邻的行内级盒。

<div>
Some inline text 
<p>followed by a paragraph</p> 
followed by more inline text.
</div>

该段代码将创建两个匿名块盒,一个包含 <p> 前面的文本 (Some inline text), 一个包含 <p> 后面的文本(followed by more inline text), 结构如下:



结果如下所示:



和 <p>元素不同, 开发者不能控制这两个匿名盒。对于可继承属性, 它们将取 <div> 的属性值, 比如 font-size。对于非继承属性,值为初始值 ,比如没有指定 background-color, 值为初始值即 transparent,于是 <div> 背景可见。而 <p> 可以指定 background-color 。类似的,这两个匿名盒文本是一样的颜色。如下:
    <style>
        div {
            background-color: green;
            font-size: 30px;
        }
        p {
            background-color: red;
        }
    </style>

另一种将创建匿名块盒的情况是,一个行内盒包含了一个或几个块盒。当一个行内盒 inline box 包含一个文档流内 In-flow 的块级盒,这个行内盒(及在同一行盒的 Line Box 它的行内祖先)会在该块级盒(及其连续的或者中间只被可折叠空白、脱离文档流元素分隔的块级同胞)的周围打断,把行内盒分离成两个盒(甚至一边为空也如此),各在块级盒一边。在打断之前和打断之后的行盒 Line Box 都被匿名块盒包含,并且该块级盒成为匿名块盒的同胞。当这样的行内盒受到相对定位影响,任何产生的移动同样影响到包含在其中的块级盒。如下:

<body>
    <p>
        This is anonymous text before the SPAN。
        <span>This is the content of SPAN.</span>
        This is anonymous text after the SPAN。
    </p>
</body>

p 元素包含一段匿名文本 C1 ,接着是一个块级元素,随后又是另一段匿名文本 C2 。结果是一个代表 body 的块盒,它包含了围绕 C1 一个匿名块盒、 span 的块盒,和围绕 C2 的另一个匿名块盒。原来的行内盒p被分割消失了。
当一个元素导致了匿名块盒的生成,则该元素上设置的属性一样能应用于该元素生成的盒和该元素的内容。例如,在上面例子中,如果在 p 元素上设置了边框,则这个边框将画在 C1 (在行的结尾开)和 C2 (在行的结尾闭)周围。

<style>
        p {
            display: inline;
            border: 1px solid red;
        }
        span {
            display: block;
        }
    </style>

style保持不变,再来看一下两种情况:

<body>
    <p>
        This is anonymous text before the SPAN。
        <span>This is the content of SPAN.</span>
        This is anonymous text after the SPAN。
        <span>This is the content of SPAN.</span>
        <span>This is the content of SPAN.</span>
        This is anonymous text after the SPAN。
    </p>
</body>
image.png

以及

<body>
    <p>
        This is anonymous text before the SPAN。
        <span>This is the content of SPAN.</span>
    </p>
</body>

<body>
    <p>
        <span>This is the content of SPAN.</span>
    </p>
</body>

说明如果行内盒包含多个块盒,并且这些块盒之间没有夹杂内容,将在这些块盒前后创建匿名块盒,即使其前后内容为空。

3.3 行内级元素Inline-level Elements和行内盒Inline Boxes

行内级元素(Inline-level Elements)是在源文档中那些不为其内容形成新的块的元素,其内容以行形式分布(如,段落内强调文本,行内图片等等)。“display”属性取以下值时产生一个行内级元素(inline-level element): 'inline'、'inline-table'和'inline-block'。行内级元素(inline-level element)生成行内级盒 (Inline-level Boxes) ,而这些盒会参与行内格式化上下文 (Inline Formatting Context) 。

一个行内盒是行内级盒,且其内容参与了该行内盒的行内格式化上下文。一个 display 值是 inline 的不可替换元素会生成一个行内盒。那些不是行内盒的行内级盒(例如可替换的行内级元素 Replaced Inline-level Elements 、行内块元素 inline-block 、行内表格元素 inline-table )被称为原子行内级盒 Atomic Inline-level Boxes ,因为它们以单一不透明盒的形式来参与它们的行内格式化上下文。


行内级盒,行内盒,原子行内级盒

我们用下面的例子来看一下它们的区别:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        em {
            display: inline;
        }
    </style>
</head>
<body>
<div style="width:6em;">
    <span>em之前的行内盒</span>
    <em>em形成的行内盒</em>
    <span>em之后的行内盒</span>
</div>
</body>
</html>

结果如下:



发现em的内容参与了em生成行内盒的行内格式化上下文。
再看以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        em {
            display: inline-block;
        }
    </style>
</head>
<body>
<div style="width:6em;">
    <span>em之前的行内盒</span>
    <em>em形成的原子行内级盒</em>
    <span>em之后的行内盒</span>
</div>
</body>
</html>

em生成的原子行内级盒作为一个单一不透明盒与span生成的行内盒区别开来。

3.4 匿名行内盒 Anonymous Inline Boxes

任何直接包含在块容器元素中的文本(不在内联元素内)都必须作为匿名行内元素处理。
一个HTML文档如下:

<p>Some <em>emphasized</em> text</p>

p 产生一个块盒,其中包含了一些行内盒。 emphasized 的盒是一个由行内元素 em 生成的行内盒,但其他盒( some 和 text 的)是由块级元素 p 生成的行内盒。后面这种盒被称作匿名行内盒,因为它们没有相关的行内级元素,没法被选择。这些匿名行内盒继承所有可继承的属性,非继承的属性取初始值(initial value)。在上面例子中,匿名行内盒的 color 从 p 那里继承,但 background 为 transparent 。

空白内容,根据 white-space 属性,如果可被折叠则不会产生任何匿名行内盒。

注:

  1. 如果可根据上下文来清晰界定一个匿名盒的类型,则匿名行内盒和匿名块盒都可被简称为匿名盒。
  2. 在格式化表格时,还会有更多类型的匿名盒出现。

3.5 插入盒Run-in boxes

插入盒,由 display:run-in 定义,根据上下文来决定其为块盒还是行内盒。属性根据插入盒的最终状态(行内级还是块级)应用于其上。

4. 影响盒子类型的display属性

看下表是CSS2.2的定义,CSS3的内容我们会在今后讲解。


display property

该属性与“float”和“position”相结合,共同确定了为元素生成的盒的类型(三者关系会在今后讲解)。其值如下:

  • block
    元素会生成一个块盒(block box)
  • inline-block
    元素会生成一个行内级块容器(inline-level block container),其本身作为一个独立的原子行内级盒参与流布局,就像一个替换元素一样。而其内部内容则按照块盒进行格式化。
  • inline
    生成行内盒
  • list-item
    这个值会导致一个元素(例如,HTML中的LI)生成一个主块盒(principal block box)和一个标记盒(marker box)。
  • none
    元素不出现在格式化结构中(也就是说,在视觉媒体中元素既不产生盒也不影响布局)。其后代元素也不产生任何盒:该元素及其内容会被从格式化结构中完全移除。对后代元素设定 display 属性不能覆盖这个表现。
  • table, inline-table, table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, table-caption
    使元素表现像一个表格元素一样。

请注意,尽管“display”的初始值是“inline”,但用户代理的默认样式表中的规则可能会覆盖这个值。

参考

https://www.w3.org/TR/css3-box/
https://www.w3.org/TR/CSS22/box.html
https://www.w3.org/TR/CSS22/visuren.html
http://www.w3.org/TR/CSS2/visuren.html
什么是BFC
CSS规范 > 9 视觉格式化模型 Visual Formatting Model
MDN-视觉格式化模型
CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容