页面布局
题目:假设高度已知,请写出三栏布局,其中左栏、右栏宽度各为300px,中间自适应。
float
实现
基于纯float
实现的三栏布局需要将中间的内容放在HTML结构的最后,否则右侧会沉在中间内容的下侧。
原理:元素浮动后,脱离文档流,后面的元素受浮动影响,设置受影响元素的margin
值即可。
两边固定宽度,中间宽度自适应。
利用中间元素的margin
值控制两边的间距。
宽度小于左右部分宽度之和时,右侧部分会被挤下去。
1 | <div class="left">左侧宽度固定</div> |
position
实现
1 | <div class="left">左侧宽度固定</div> |
flex
布局
在外围包裹一层div
,设置为display:flex
;中间设置flex:1
;但是盒模型默认紧紧挨着,可以使用margin
控制外边距。
1 | <div id="wrap"> |
页面布局的变通
三栏布局
- 左右宽度固定,中间自适应
- 上下高度固定,中间自适应
两栏布局
- 左宽度固定,右自适应
- 右宽度固定,左自适应
- 上高度固定,下自适应
- 下高度固定,上自适应
CSS盒模型
谈谈你对CSS盒模型的认识
标准模型+IE模型 → 标准模型和IE模型的区别 → CSS如何设置这两种模型 → JS如何设置获取盒模型对应的宽和高 → 实例题(根据盒模型解释边距重叠)→ BFC(边距重叠解决方案)
标准模型+IE模型
两者的区别在于content
的不同,IE(5.5及以前)盒模型的content
包括border、padding
CSS如何设置这两种模型
1 | box-sizing:border-box || content-box(default) |
此特性在自适应的网页会非常好用,因为它不会破坏网页的结构
BFC浅析
什么是BFC(Block formatting contexts)
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions
),以及overflow
值不为“visiable
”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。
在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin
值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。
在BFC中,每一个盒子的左外边缘(margin-left
)会触碰到容器的左边缘(border-left
)(对于从右到左的格式来说,则触碰到右边缘)。
BFC 的特性
BFC 对布局的影响主要体现在对 float
和 margin
两个属性的处理。在我看来,BFC 让 float
和 margin
这两个属性的表现更加符合我们的直觉。
根据 BFC 对其内部元素和外部元素的表现特性,我将 BFC 的特性总结为对内部元素的包裹性及对外部元素的独立性。
对内部元素的包裹性
BFC 对内部元素的包裹性主要体现在 BFC 可以包裹浮动元素,以及 BFC 可以包裹 margin
。
BFC 包裹浮动元素
BFC 的特性之一就是其高度的计算会包括所有浮动元素的高度,所以使用 BFC 可以包裹浮动元素,达到清除浮动的目的。
1 | <div style="overflow: hidden; background: #AAA;"> |
overflow: hidden
可以触发一个元素的 BFC 属性,使该元素成为一个 BFC 容器,从而使该元素对内部元素及外部元素表现出 BFC 的特性,更多可以触发 BFC 属性的条件会在后面总结。
运行代码可以看到,我们虽然没有进行任何清除浮动的工作,外层 div
还是包裹住了内层浮动的 div
,没有造成高度塌陷的情况。
另外,将外层div
同时设为浮动来清除内层浮动的方法本质上也是应用了 BFC 的特性,因为将一个元素设为浮动也会触发该元素的 BFC 属性,使外层元素成为一个 BFC 容器。
BFC 包裹 margin
BFC 对内部元素的另一个特性就是可以取消margin
折叠(margin collapse)。这个特性我喜欢更形象的称之为包裹margin
。
1 | <div style="background: #AAA;"> |
运行代码可以看到,内层 div
的 margin
并没有将内层div
相对于外层 div
向下推移,而是将内外两层 div
整体向下推移:
而我们想要的结果是这样的:
内外两层div
被整体向下推移的原因就是margin
折叠,关于margin
折叠的相关介绍可以参见这里。CSS 中父子元素的 margin
只要相邻,也会发生折叠,CSS 规范虽是如此,但很多时候这并不符合我们的预期:我们希望外部div
能够包裹内部div
的 margin
,避免形成折叠,这时我们就可以使用 BFC。
1 | <div style="overflow:hidden; background:#AAA;"> |
我们将外层 div
设置为一个 BFC 容器,由于 margin
折叠只会发生在同一个 BFC 中的元素之间,而不同 BFC 的元素之间以及元素及其所属的 BFC 之间不会发生 margin
折叠,因此就可以实现对 margin
的包裹。
对外部元素的独立性
BFC 对外部元素的独立性在于 BFC元素不会与浮动元素叠加。例如:
1 | <div style="float: left; width: 100px; height: 100px; background: #000;"> |
可以看到,浮动的div
由于脱离了文档流,导致正常的 div
左上角被覆盖。为了避免这种情况,我们使第二个 div
成为 BFC 容器:
1 | <div style="float: left; width: 100px; height: 100px; background: #000;"> |
当第二个div
成为 BFC 容器后,其不会再受到浮动 div
的影响,布局相对独立。这样的技巧经常用作两栏或三栏自适应布局。
触发 BFC
介绍 BFC 的时候我们就已经说过,BFC 可以被理解为元素的一个属性,但是这个属性无法被显式的设置,那么如何触发一个元素的 BFC 属性呢?上面的代码中使用的 overflow:hidden
就是触发 BFC 的一种方式,除了设置 overflow:hidden
,下面的 CSS 属性设置都可以触发 BFC:
1 | float 设置为除 none 外的取值; |
BFC 与 Layout
IE 作为浏览器中的奇葩,当然不可能按部就班的支持 BFC 标准,于是乎 IE 中有了 Layout 这个东西。Layout 和 BFC 基本是等价的,为了处理 IE 的兼容性,在需要触发 BFC 时,我们除了需要用上面的 CSS 属性来触发 BFC,还需要针对 IE 浏览器使用 zoom: 1
来触发 IE 浏览器的 Layout。
BFC的作用
自适应的两栏布局
1 | <div style="width: 300px;height: 100px;background: #000;float: left;"></div> |
清除内部浮动
未触发BFC1
2
3
4<div style="width: 300px;background: blue;">
<div style="width: 100px;height: 100px;background: #AAA;float: left;"></div>
<span>这是里面的内容</span>
</div>
触发BFC
1 | <div style="width: 300px;background: blue;overflow: hidden;"> |
防止margin重叠
1 | <p>内容一</p> |
我们可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin
重叠了。
1 | <p>内容一</p> |