本文推荐 PC 端阅读~
本文版权归 “公众号 | 前端一万小时” 全部,未经受权,请勿转载!
复制代码
css_07
复制代码
1. 块级元素和行内元素分别有哪些? 空(void)元素有那些?块级元素和行内元素有什么区别?
2. IE 盒模型和 W3C 盒模型有什么区别?
3. 在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例?
4. 关于 .item { width: 100%; },如下说法正确的是:
❌ .item 的宽度(包括左右 margin、左右边框、左右 padding、content)等于它父亲的宽度(包括左右 margin、左右边框、左右 padding、content)。
❌ .item 的宽度(包括左右边框、左右 padding、content)等于它父亲的宽度(左右边框、左右 padding、content)。
❌ .item 的宽度(左右 padding、content)等于它父亲的宽度(左右 padding、content)。
✅ .item 的宽度(content)等于它父亲的宽度(content)。
❌ 若是设置了 * {box-sizing:border-box},.item 的宽度(包括左右边框、左右 padding、content)等于它父亲的宽度(左右边框、左右 padding、content)。
复制代码
前言: 接下来的几篇系列文章咱们讲一个东西:盒子(BOX)。
“盒模型”(box model)做为 CSS 看待元素的一种方式,CSS 将每一个元素都看做由一个盒子表示。从某方面来讲,对于初级、中级学习者的咱们,大可将 CSS 的学习看做是对“盒子”的学习。
为何这么说?请看下图我我的的 CSS 学习流程:css
图中咱们能够看到,几乎全部的内容都是围绕着“盒子”这个东西在展开。
本篇咱们将阐述最基本的理论知识,将“盒子”的方方面面一步步带到咱们跟前。html
“盒子 box”由 CSS 引擎根据文档中的内容所建立,主要用于文档元素的格式化、定位和布局等。前端
盒子与元素并非一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。面试
一个完整的“盒子”中心有一个内容区(content area)。这个内容区周围有可选的 padding、边框和 margin。这些项之因此被认为是可选的,是由于它们的宽度能够设置为 0,实际上就是从“盒子”上去除这些项。浏览器
CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。bash
通俗的讲就是:页面(文档树)能够想象成是由一个个 box 组合而成的,而“视觉格式化模型(Visual formatting model)” 是一套规则,将这些 box “布局”成访问者看到的样子。ide
每一个盒子的“布局”由如下因素决定(本篇文章和下一篇文章主要讲解第①、②点,其属于“最基本的视觉格式化”,而对于剩下的要点,咱们在接下来的系列文章中会挨个讨论):布局
① 盒子的尺寸:精确指定、由约束条件指定或没有指定;
② 盒子的类型:行内盒子(inline box)、行内级盒子(inline-level box)、原子行内级盒子(atomic inline-level box)、块盒子(block box);学习
③ 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位;
④ 文档树中的其它元素:即当前盒子的子元素或兄弟元素;
⑤ 视口尺寸与位置;
⑥ 所包含的图片的尺寸;
⑦ 其余的某些外部因素。atom
💡如上图所示,视觉格式化模型会根据盒子的“包含块”(containing block)——(包含其余盒子的块称为“包含块”)的边界来渲染盒子。一般,盒子会建立一个包含其后代元素的“包含块”,可是盒子并不禁“包含块”所限制,当盒子的布局跑到”包含块“的外面时称为溢出(overflow)。
上图中,section 的包含块是 body ,header、article、footer 的包含块是 section。
⚠️区别:
盒子的生成是 CSS “视觉格式化模型”的一部分,用于从文档元素生成盒子。
盒子有不一样的类型,盒子的类型取决于 CSS 的 display 属性——元素“角色”的改变。
设置元素的 display 属性为 block、list-item 或 table 时,该元素将成为“块级元素”。
这些元素在正常流中时,会在其框以前和以后生成“换行”,因此处于正常流中的块级元素会“垂直”摆放。
选择器 {
display: block、list-item 或 table;
}
复制代码
💡(“正常流”是指:西方语言文本从左向右、从上向下显示的方向,这也是咱们熟悉的传统 HTML 文档的文本布局方向。注意,在非西方语言中,流方向可能不一样。)
但,元素是不是“块级元素”仅是元素自己的属性,并不直接用于格式化上下文的建立或布局。
一个“块级元素”会被格式化成一个块(例如文章的一个段落),且默认按照垂直方向依次排列。
💡一个“块级元素”都会至少生成一个“块级盒子”,也有可能生成多个(例如列表项元素)。而“块级盒子”才会参与“块格式化上下文(block formatting context)”的建立。
当元素的 display 属性为 inline、inline-block 或 inline-table 时,该元素将成为“行内级元素”。
选择器 {
display: inline、inline-block 或 inline-table;
}
复制代码
这些元素不会在以前或以后生成“行分隔符”,因此处于正常流中的块级元素会 “水平” 摆放,它们是块级元素的后代。
显示时,它不会生成内容块,可是能够与其余行内级内容一块儿显示为多行。
💡同理,“行内级元素”会生成“行内级盒子”,该盒子同时会参与“行内格式化上下文(inline formatting context)”的建立。
🏆小总结: 相对更详细的“盒子”细分:
⚠️注意: 必定要记得的是,display 之因此得名,是由于它影响的是元素如何“显示”,而不影响他本质上是何种元素,也就不能乱玩“嵌套关系”!
一个极端的反例就是:你不能让一个“连接”来包围一个“段落”。
<a href="http://…" style="display: block;">
<p style="display: inline;">这是一个错误的示例</p>
</a>
复制代码
(对于生成不一样类型“盒子”在实际项目中的运用,咱们将在后续文章详细讨论。例如:怎样给“连接”加样式——生成导航栏、怎样给“表单”加样式等。)
本篇咱们主要探讨 “块盒子”格式化,下篇文章讨论“行内盒子”格式化。
正常流中,“块盒子”的水平部分 = 其父元素的 width = 7 个属性之和——(margin-left ➕ margin-right) ➕ (padding-left ➕padding-right)➕(border-left➕border-right)➕内容区自身 width 。
在这 7 个属性中只有 3 个属性的值能够设置为 auto:width、margin-left、margin-right。其他的要没必要须是肯定的值,要不就是默认值 0。
🚀可详细分为如下 5 种组合:
⚠️注意:因为水平 margin 不会合并,父元素的 padding 、边框、margin 可能会对子元素带来“偏移”的影响。
正常流中,“块盒子”的垂直部分 = 其父元素的 height = 7 个属性之和——(margin-top ➕margin-bottom) ➕ (padding-top ➕padding-bottom)➕(border-top ➕border-bottom)➕内容区自身 height 。
同理,在这 7 个属性中只有 3 个的值能够设置为 auto:height、margin-top、margin-bottom。其他的要没必要须是肯定的值,要不就是默认值 0。
⚠️不过,margin-top 和 margin-bottom 设置为 auto 也没有什么用,由于会被重置为 0。因此,想利用上下 margin 都是 auto 来垂直居中是不可能的。
垂直格式化的另外一个重要方面是垂直相邻 margin 的合并。
这种合并行为只应用于 margin,若是元素有 padding 和边框,padding 和边框是不会合并的。当两个或更多垂直 margin 相遇时,他们将造成惟一一个 margin,这个 margin 的高度等于两个发生叠加的 margin 的高度中的较大者。
⚠️注意:当一个元素包含在另外一个元素中时,彼此相邻的 margin-bottom 和 magin-top 也会发生叠加,取较大者。
🤔提问:水平或垂直方向各自 7 大属性相加要等于父元素的 width 或 height,那 margin 为负值会形成什么结果?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<p class="wide">How are you?</p>
<p>Fine,thank you,and you?</p>
</div>
</body>
</html>
复制代码
(1)类型①
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: 20px;
width: auto;
margin-right: -50px;
background-color: yellow;
}
复制代码
(2)类型②
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: 20px;
width: 500px;
margin-right: auto;
background-color: yellow;
}
复制代码
(3)类型③
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: -50px;
width: auto;
margin-right: 10px;
background-color: yellow;
}
复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<p class="wide1">How are you?</p>
<p class="wide2">Fine,thank you,and you?</p>
</div>
</body>
</html>
复制代码
div {
width: 400px;
border: 3px solid black;
}
p.wide1 {
border: 1px dashed black;
margin-top: -20px; /*修改这里的值来观察效果*/
margin-right: 20px;
margin-bottom: 30px;
margin-left: 20px;
width: auto;
background-color: yellow;
}
p.wide2 {
border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: ;
margin-left: 20px;
width: auto;
background-color: grey;
}
复制代码
(2)类型 ②:负 margin-bottom
🔗效果及源码连接
div {
width: 400px;
border: 3px solid black;
}
p.wide1 {
border: 1px dashed black;
margin-top: px;
margin-right: 20px;
margin-bottom: -50px; /*修改这里的值来观察效果*/
margin-left: 20px;
width: auto;
background-color: yellow;
}
p.wide2 {border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: ;
margin-left: 20px;
width: auto;
background-color: grey;
}
复制代码
(3)类型 ③:正负 margin 合并
“块盒子”重叠的时候,若是垂直 margin 都为负值,浏览器会取两个 margin 绝对值的最大值;若是一个正 margin 与一个负 margin 合并,则会从正 margin 减去这个负 margin 的绝对值。
🔗效果及源码连接
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<ul>
<li>Fine</li>
<li>thank you</li>
<li>and you?</li>
</ul>
<p>回答 How are you? 的方式!</p>
</div>
</body>
</html>
复制代码
div {
width: 400px;
border: 3px solid black;
}
ul {
border: 1px dashed black;
margin-top: px;
margin-right: 20px;
margin-bottom: -15px; /*①修改这里的值来观察效果*/
margin-left: 20px;
width: auto;
background-color: yellow;
}
li {
border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: 20px; /*②修改这里的值来观察效果*/
margin-left: 20px;
width: auto;
background-color: grey;
}
p {
border: 1px dashed black;
margin-top: -18px; /*①修改这里的值来观察效果*/
margin-right: 20px;
margin-bottom: px;
margin-left: 20px;
width: auto;
background-color: yellow;
}
复制代码
后记: 这篇咱们学习了“块盒子”的格式化方式,下一篇咱们接着这篇继续探讨“行内盒子”的格式化方式。在“行内盒子”格式化方式中,咱们会谈到不少细小的基础知识,和本篇的学习方式同样,让咱们尽量的用代码、用图片来攻克它们。
祝好,qdywxs ♥ you!