(注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:
是不是很眼熟,是的,如果你还记得box-sizing属性的话。
CSS3中提供了一个新的属性,box-sizing,来控制和模型的表现形式。box-sizing有三个取值,分别是content-box,border-box和inherit。
(注:其实还有一个padding-box,width和height属性包括内容和内边距,但是不包括边框和外边距。只有Firefox实现了这个值,它在Firefox 50中被删除。)
另外,一个盒子的content area的宽高取决于如下的因素:
而一个盒子的content area,padding area和border area的背景由生成元素的background属性指定,而margin area的背景总是透明的。
上面讨论了盒子的基本组成和在不同浏览器中的表现,这一节我们来看一下盒子的类型。这里所描述的是CSS2.2中可生成的盒类型。CSS 视觉格式化模型的一部分工作是从文档元素生成盒。生成的盒拥有不同类型,并对视觉格式化模型的处理产生影响。生成盒的类型取决于 CSS 属性 display。盒的类型会影响其在视觉格式化模型中的表现。
块级元素是指源文档中以块(如段落)的形式被格式化,生成主要块级盒(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)。
“块级盒”、“块容器盒”、“块盒”
有时需要添加补充性盒,这些盒称为匿名盒(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>
说明如果行内盒包含多个块盒,并且这些块盒之间没有夹杂内容,将在这些块盒前后创建匿名块盒,即使其前后内容为空。
行内级元素(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生成的行内盒区别开来。
任何直接包含在块容器元素中的文本(不在内联元素内)都必须作为匿名行内元素处理。
一个HTML文档如下:
<p>Some <em>emphasized</em> text</p>
p 产生一个块盒,其中包含了一些行内盒。 emphasized 的盒是一个由行内元素 em 生成的行内盒,但其他盒( some 和 text 的)是由块级元素 p 生成的行内盒。后面这种盒被称作匿名行内盒,因为它们没有相关的行内级元素,没法被选择。这些匿名行内盒继承所有可继承的属性,非继承的属性取初始值(initial value)。在上面例子中,匿名行内盒的 color 从 p 那里继承,但 background 为 transparent 。
空白内容,根据 white-space 属性,如果可被折叠则不会产生任何匿名行内盒。
注:
插入盒,由 display:run-in 定义,根据上下文来决定其为块盒还是行内盒。属性根据插入盒的最终状态(行内级还是块级)应用于其上。
看下表是CSS2.2的定义,CSS3的内容我们会在今后讲解。
display property
该属性与“float”和“position”相结合,共同确定了为元素生成的盒的类型(三者关系会在今后讲解)。其值如下:
请注意,尽管“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