imooc(一)

页面布局

题目:假设高度已知,请写出三栏布局,其中左栏、右栏宽度各为300px,中间自适应。

float实现

基于纯float实现的三栏布局需要将中间的内容放在HTML结构的最后,否则右侧会沉在中间内容的下侧

原理:元素浮动后,脱离文档流,后面的元素受浮动影响,设置受影响元素的margin值即可。

两边固定宽度,中间宽度自适应。

利用中间元素的margin值控制两边的间距。

宽度小于左右部分宽度之和时,右侧部分会被挤下去。

1
2
3
4
5
6
7
8
9
10
<div class="left">左侧宽度固定</div>
<div class="right">右侧宽度固定</div>
<div class="main">中间内容自适应</div>

<style type="text/css">
div {height: 100px;}
.left {width: 300px;background: blue;float: left;}
.right {width: 300px;background: green;float: right;}
.main {background: gray;}
</style>

image

position实现

1
2
3
4
5
6
7
8
9
10
<div class="left">左侧宽度固定</div>
<div class="main">中间内容自适应</div>
<div class="right">右侧宽度固定</div>

<style type="text/css">
div {height: 100px;}
.left{position: absolute;left: 0;width: 300px;background: yellow;}
.right{position: absolute;right: 0;width: 300px;background: gray;}
.main{position: absolute;left: 300px;right: 300px;background: skyblue;}
</style>

flex布局

在外围包裹一层div,设置为display:flex;中间设置flex:1;但是盒模型默认紧紧挨着,可以使用margin控制外边距。

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="wrap">
<div class="left">左侧宽度固定</div>
<div class="main">中间内容自适应</div>
<div class="right">右侧宽度固定</div>
</div>

<style type="text/css">
div {height: 100px;}
#wrap {display: flex;}
.left {width: 300px;background: red;}
.right {width: 300px;background: blue;}
.main {flex: 1;background: pink;}
</style>

页面布局的变通

三栏布局

  • 左右宽度固定,中间自适应
  • 上下高度固定,中间自适应

两栏布局

  • 左宽度固定,右自适应
  • 右宽度固定,左自适应
  • 上高度固定,下自适应
  • 下高度固定,上自适应

CSS盒模型

谈谈你对CSS盒模型的认识

标准模型+IE模型 → 标准模型和IE模型的区别 → CSS如何设置这两种模型 → JS如何设置获取盒模型对应的宽和高 → 实例题(根据盒模型解释边距重叠)→ BFC(边距重叠解决方案)

标准模型+IE模型

两者的区别在于content的不同,IE(5.5及以前)盒模型的content包括border、padding

image

image

CSS如何设置这两种模型

1
2
3
4
5
6
box-sizing:border-box || content-box(default)


当使用border-box时,页面将采用怪异模式解析计算,怪异模式也称为IE模式。

当使用content-box时:页面将采用标准模式来解析计算,content-box也是默认模式

此特性在自适应的网页会非常好用,因为它不会破坏网页的结构

BFC浅析

什么是BFC(Block formatting contexts)

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。

在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。

BFC 的特性

BFC 对布局的影响主要体现在对 floatmargin 两个属性的处理。在我看来,BFC 让 floatmargin 这两个属性的表现更加符合我们的直觉。

根据 BFC 对其内部元素和外部元素的表现特性,我将 BFC 的特性总结为对内部元素的包裹性对外部元素的独立性

对内部元素的包裹性

BFC 对内部元素的包裹性主要体现在 BFC 可以包裹浮动元素,以及 BFC 可以包裹 margin

BFC 包裹浮动元素

BFC 的特性之一就是其高度的计算会包括所有浮动元素的高度,所以使用 BFC 可以包裹浮动元素,达到清除浮动的目的。

1
2
3
4
<div style="overflow: hidden; background: #AAA;">
<div style="float: left; width: 100px; height: 100px; background: #000;">
</div>
</div>

overflow: hidden 可以触发一个元素的 BFC 属性,使该元素成为一个 BFC 容器,从而使该元素对内部元素及外部元素表现出 BFC 的特性,更多可以触发 BFC 属性的条件会在后面总结。

运行代码可以看到,我们虽然没有进行任何清除浮动的工作,外层 div 还是包裹住了内层浮动的 div,没有造成高度塌陷的情况。

image

另外,将外层div 同时设为浮动来清除内层浮动的方法本质上也是应用了 BFC 的特性,因为将一个元素设为浮动也会触发该元素的 BFC 属性,使外层元素成为一个 BFC 容器。

BFC 包裹 margin

BFC 对内部元素的另一个特性就是可以取消margin 折叠(margin collapse)。这个特性我喜欢更形象的称之为包裹margin

1
2
3
4
<div style="background: #AAA;">
<div style="width: 100px; height: 100px; margin-top: 50px; background: #000;">
</div>
</div>

运行代码可以看到,内层 divmargin 并没有将内层div相对于外层 div 向下推移,而是将内外两层 div 整体向下推移:

image

而我们想要的结果是这样的:

image

内外两层div被整体向下推移的原因就是margin 折叠,关于margin 折叠的相关介绍可以参见这里。CSS 中父子元素的 margin 只要相邻,也会发生折叠,CSS 规范虽是如此,但很多时候这并不符合我们的预期:我们希望外部div能够包裹内部divmargin,避免形成折叠,这时我们就可以使用 BFC。

1
2
3
4
<div style="overflow:hidden; background:#AAA;">
<div style="width:100px; height:100px; margin-top:50px; background:#000;">
</div>
</div>

我们将外层 div设置为一个 BFC 容器,由于 margin折叠只会发生在同一个 BFC 中的元素之间,而不同 BFC 的元素之间以及元素及其所属的 BFC 之间不会发生 margin折叠,因此就可以实现对 margin 的包裹。

对外部元素的独立性

BFC 对外部元素的独立性在于 BFC元素不会与浮动元素叠加。例如:

1
2
3
4
<div style="float: left; width: 100px; height: 100px; background: #000;">
</div>
<div style="height: 200px; background: #AAA;">
</div>

image

可以看到,浮动的div 由于脱离了文档流,导致正常的 div 左上角被覆盖。为了避免这种情况,我们使第二个 div 成为 BFC 容器:

1
2
3
4
<div style="float: left; width: 100px; height: 100px; background: #000;">
</div>
<div style="overflow: hidden; height: 200px; background: #AAA;">
</div>

image

当第二个div 成为 BFC 容器后,其不会再受到浮动 div的影响,布局相对独立。这样的技巧经常用作两栏或三栏自适应布局。

触发 BFC

介绍 BFC 的时候我们就已经说过,BFC 可以被理解为元素的一个属性,但是这个属性无法被显式的设置,那么如何触发一个元素的 BFC 属性呢?上面的代码中使用的 overflow:hidden 就是触发 BFC 的一种方式,除了设置 overflow:hidden,下面的 CSS 属性设置都可以触发 BFC:

1
2
3
4
5
6
7
float 设置为除 none 外的取值;

overflow 设置为除 visible 之外的取值;

position 设置为除 static 及 relative 之外的取值;

display 设置为 table-cell、table-caption、inline-block 中的任一取值;

BFC 与 Layout

IE 作为浏览器中的奇葩,当然不可能按部就班的支持 BFC 标准,于是乎 IE 中有了 Layout 这个东西。Layout 和 BFC 基本是等价的,为了处理 IE 的兼容性,在需要触发 BFC 时,我们除了需要用上面的 CSS 属性来触发 BFC,还需要针对 IE 浏览器使用 zoom: 1来触发 IE 浏览器的 Layout。

BFC的作用

自适应的两栏布局

1
2
<div style="width: 300px;height: 100px;background: #000;float: left;"></div>
<div style="height: 200px;background: #AAA;overflow: hidden;"></div>

image

清除内部浮动

未触发BFC

1
2
3
4
<div style="width: 300px;background: blue;">
<div style="width: 100px;height: 100px;background: #AAA;float: left;"></div>
<span>这是里面的内容</span>
</div>

image

触发BFC

1
2
3
4
<div style="width: 300px;background: blue;overflow: hidden;">
<div style="width: 100px;height: 100px;background: #AAA;float: left;"></div>
<span>这是里面的内容</span>
</div>

image

防止margin重叠

1
2
3
4
5
6
7
8
9
<p>内容一</p>
<p>内容二</p>

p{
background: #AAA;
width: 200px;
height: 100px;
margin: 100px;
}

image

我们可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<p>内容一</p>
<div class="wrap">
<p>内容二</p>
</div>

p{
background: #AAA;
width: 200px;
height: 100px;
margin: 100px;
}
.wrap{
overflow: hidden;
}

image

浅析BFC:https://zjy.name/archives/bfc-introduction.html

------ 本文结束 ------
0%