CSS布局模型(Float、BFC)
2017-07-12 本文已影响135人
_空空
CSS布局模型
- 布局:将元素以正确的大小摆放在正确的位置上
- CSS包含3种基本的布局模型
- 流动模型(Flow)
- 浮动模型(Float)
- 层模型(Layer)
流动模型(Flow)
- 流动是默认的网页布局模式。也就是说在默认状态下的HTML网页元素都是根据流动模型来分布网页内容的
- 流动布局模型具有2个比较典型的特征:
- 块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素占据的宽度都为100%(不设置宽度)。实际上,块状元素都会以行的形式占据位置
- 在流动模型下,内联元素都会在所处的包含元素内自左到右水平分布显示
浮动模型(Float)
- 基本概念:浮动模型也是一种可视化格式模型,浮动的框可以左右移动(根据float属性值而定),直到它的外边缘碰到包含框或者另一个浮动元素的框的边缘。浮动元素不在文档的普通流中,文档的普通流中的元素变的就像浮动元素不存在一样
-
任何元素在默认情况下都是不能浮动的,但可以用CSS定义为浮动,如
div
、p
、table
、img
等元素都可以定义为浮动 - 如果包含块太窄无法容纳水平排列的浮动元素,那么其它浮动块向下移动,直到有足够的空间,如果浮动元素的高度不同,那么向下移动的时候可能被卡住
float: left | right | none(默认) | inherit;
// 应用于所有元素。无继承性
// 实例1:
<body>
<div style="border: solid 5px #0e0; width: 250px;">
<div style="height: 120px; width: 100px; background-color: Red; float: left;">
</div>
<div style="height: 100px; width: 100px; background-color: Green; float: left;">
</div>
<div style="height: 100px; width: 100px; background-color: Yellow; float: left;">
</div>
</div>
</body>
// 实例2:
<body>
<div style="border: solid 5px #0e0; width:300px;">
<div style="boder: 1px solid lightcoral;">
<div style="height: 50px; width: 100px; background-color: Red; float: left;">1</div>
<div style="height: 100px; background-color: Green; float: left;">2df空间空间就开发邓金快乐就啊风口浪尖分快乐就快乐发邓金快乐就浮动是快乐就快乐就放假啊看路径及看风景的快乐地方就是快乐就放假卡拉斯京访问空间看了大煞风景空间快乐</div>
</div>
<div style=" background-color: Yellow; ">3<br>dfff<br>dfff<br>dfff<br>dfff<br>dfff</div>
</div>
</body>
浮动元素的特征、影响
-
浮动元素的特征:
- 不占据普通文档流的空间。
- 浮动元素的左(右)外边界不能超过其包含块的左(右)内边界
- 浮动元素的左(右)外边界必须是源文档中之前出现的左浮动(右浮动)的元素的右(左)边界,除非后出现浮动元素的顶端在先出现浮动元素的底端下面
- 左浮动元素的右外边界不会在其右边浮动元素的左外边界的右边。一个右浮动元素的左外边界不会在其左边任何左浮动元素的右外边界的左边
- 一个浮动元素的顶端不能比其父元素的内顶端更高
- 浮动元素的顶端不能比之前所有浮动元素或块级元素的顶端更高
- 如果文档中一个浮动元素之前出现另一个元素,浮动元素的顶端不能比包含该元素所生成的框的任何行框的顶端更高。
- 如果浮动元素出现在另一个浮动元素的旁边,而因此可能导致超出包含块的话,这个浮动元素会向下浮动到之前浮动元素下面的某一点。
- 浮动元素必须尽可能高地放置。
- 左浮动元素必须向左尽可能远,右浮动元素必须向右尽可能远。
- inline 元素设置浮动,改变 inline 的 display 使得它像个 block-level。
- 在重叠上,浮动元素会遮盖 block-level 元素的背景,不会遮盖 inline 元素。
内边界:指盒模型中的 content 边界。外边界:指盒模型中的 margin 边界。
-
影响:
- 非BFC的正常文档流父元素会"感受"不到浮动元素的存在,从而产生"高度塌陷"。
- 其他浮动元素会“察觉”到浮动元素的存在按照从左到右的“正常文档流”排列。
- 普通元素(非 inline-level)会无视浮动元素的存在,从而占据浮动元素的“原来的位置”
- 文字(也既 inline-level)级的元素会环绕浮动元素,表现的像是察觉到浮动元素一样
-
在CSS中,浮动(
float
)和绝对定位(position: absolute;
)可以让元素脱离文档流 -
重叠:浮动元素超出父元素边界的方法有两种:
- 浮动元素的宽度大于父元素的宽度
- 设置负外边距。如果浮动元素存在负外边距,且浮动元素与正常流元素重叠:
- 行内框与一个浮动元素重叠时,其边框、背景和内容都在该浮动元素之上显示
- 块框与一个浮动元素重叠时,其边框和背景在该浮动元素之下显示,而内容在浮动元素之上显示
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box{
width: 200px;
height: 200px;
margin: 50px;
background-color: grey;
}
.box span{
background-color: lightsalmon;
}
.box1{
float: left;
width: 300px;
height: 100px;
margin: -10px 0;
background-color: lightblue;
}
.box2{
background-color: lightgreen;
}
</style>
</head>
<body>
<div class="box">
<span>行内元素行内元素行内元素行内元素行内元素行内元素</span>
<div class="box1">浮动元素</div>
<div class="box2">块状元素块状元素块状元素块状元素</div>
</div>
</body>
行框
- 浮动会让元素脱离普通流,如果浮动的元素后面有一个文档流中的元素,那么这个元素的框会表现得像浮动元素不存在,但是框的文本内容会受到浮动元素的影响,会移动以留出空间。用术语说就是浮动元素旁边的行框被缩短,从而给浮动元素留出空间,因而行框围绕浮动框
<body>
<div style="border: solid 5px #0e0; width: 250px;">
<div style="height: 50px; width: 50px; background-color: Red; float: left;"></div>
<div style="height: 100px; width: 100px; background-color: Green;">
abc def ghi
abc def ghi
abc def ghi
</div>
</div>
</body>
- 可以看到浮动后虽然绿色 div 布局不受浮动影响,正常布局,但是文字部分却被挤到了红色浮动 div 外边。要想阻止行框围绕在浮动元素外边,可以使用 clear 属性,属性的 left、right、both、none 表示框的哪些边不挨着浮动框
<body>
<div style="border: solid 5px #0e0; width: 250px;">
<div style="height: 50px; width: 50px; background-color: Red; float: left;"></div>
<div style="height: 100px; width: 100px; background-color: Green; clear:both;">
11111111111
11111111111
</div>
</div>
</body>
清除浮动指什么? 如何清除浮动?
- 清除浮动指元素的侧边不允许出现浮动元素,从而使浮动元素的不占据普通文档流空间而导致的父元素的高度塌陷问题得到解决,主要通过 clear 属性实现。
- 清除浮动的方法:
- 设置浮动包含块的父元素 height 值。
- 使包含块的父元素形成BFC(而对于IE7-浏览器,则用到其特有属性 haslayout )。
- 通过添加
:after
伪元素,然后在伪元素上设置 clear 属性来实现
// clear:指定一个元素是否可以在它之前的浮动元素旁边,或者必须向下移动(清除浮动)在它的下面
clear:left | right | both | none(默认) | inherit
// 可设置的属性值包括:left(在左侧不允许浮动元素)、right(在右侧不允许浮动元素)、both(在左右两侧均不允许浮动元素)、none(默认值。允许浮动元素出现在两侧)、inherit
// 应用于:块级元素(块级元素指 block元素,不包括 inline-block元素)。无继承性
// 注意:设置clear属性的元素并不能改变浮动元素,而只能改变自身
// CSS2.1引入了一个清除区域,清除区域是在元素上外边距之上增加的额外间隔,不允许任何浮动元素进入这个范围,这意味着元素设置 clear 属性时,它的外边距不改变
/*
clear 属性适用于浮动和非浮动元素
当应用于非浮动块时,它将非浮动块的边框边界移动到所有相关浮动元素外边界的下方。
这个行为作用时会导致 margin collapsing 不起作用
当应用于浮动元素时,它将元素的外边界移动到所有相关的浮动元素外边界的下方。
这会影响后面浮动元素的布局,后面的浮动元素的位置无法高于它之前的元素
*/
// 在所有浏览器中都兼容的清浮动方案如下:
/* 方法1 */
.clearfix {
*zoom: 1; /* IE7-浏览器:触发包含块的 haslayout */
}
.clearfix:after{
content:"";
display: block;
clear: both;
}
/* 方法2 */
/* 我们知道:触发 BFC 可以让包含块包含浮动元素,进而达到清除浮动的效果 */
.clearfix{
*zoom: 1;
}
.clearfix:after {
content: "";
display: table; /* 匿名的表格单元,它是可以触发 BFC 的 */
clear: both;
}
// 更进一步:
/*
.clearfix:before 对于清除浮动是没什么必要性,但是它可以防止浏览器顶部空白崩溃
也就是说,margin-top 和上一个盒子的 margin-bottom,它们两个会发生叠加,
通过设置 .clearfix:before 可以防止这个叠加
*/
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
BFC(块级格式化上下文)
- BFC:块格式化上下文(block formatting context)是Web页面的可视CSS渲染的一部分。它是块盒子的布局发生及浮动体彼此交互的区域。首先BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。
- 参考:
作用
- BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。它与普通的块框类似,但不同之处在于:
- 可以阻止元素被浮动元素覆盖(不会重叠浮动元素)
- 可以包含浮动元素
- 属于同一个BFC的两个相邻块级子元素的上下margin会发生重叠,(设置
writing-mode: tb-rl;
时,水平margin会发生重叠)。所以当两个相邻块级子元素分属于不同的BFC时可以阻止margin重叠- 按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直margin的重叠,这个包括相邻元素,嵌套元素,只要它们之间没有阻挡(例如边框、非空内容、padding等)就会发生margin重叠
- 因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为BFC就可以了。这样子元素的margin就不会和父元素的margin发生重叠
- 注意:浮动不会影响其它BFC中元素的布局,并且清除浮动只能清除同一BFC中在它前面的元素的浮动,在其之后的不行。
- 应用:
- 自适应的两栏布局。
- 清除元素内部浮动。
- 嵌套元素margin边距合并问题的解决。
形成条件
- 满足下列条件之一就可形成BFC:
- 根元素(即HTML元素)或其它包含它的元素
- 浮动(元素的 float 不是 none)
- 绝对定位的元素(元素具有 position 为 absolute 或 fixed)
- 内联块状元素 inline-blocks(元素具有 display: inline-block)
- 表格单元格(元素具有 display: table-cell,HTML表格单元格默认属性)
- 表格标题(元素具有 display: table-caption,HTML表格标题默认属性)
- 块元素具有 overflow ,且值不是 visible
- display: flow-root
- display: flex
<body>
<div style="border: solid 5px #0e0; width: 300px; overflow: hidden;">
<div style="height: 100px; width: 100px; background-color: Red; float: left;">
</div>
<div style="height: 100px; width: 100px; background-color: Green; float: left;">
</div>
<div style="height: 100px; width: 100px; background-color: Yellow; float: left;">
</div>
</div>
</body>
局限性
- 比如为了形成BFC使用float的时候,会使父容器长度缩短,而且还有个重要缺陷 —— 父容器float解决了其塌陷问题,那么父容器的父容器怎么办?overflow属性会影响滚动条和绝对定位的元素;position会改变元素的定位方式,这是我们不希望的,display这几种方式依然没有解决低版本IE问题
haslayout 详解(IE7-浏览器)
- haslayout是IE7-浏览器的特有属性。hasLayout是一种只读属性,有两种状态:true 或 false。当其为 true 时,代表该元素有自己的布局,会达到和BFC类似的效果,元素负责本身及其子元素的尺寸设置和定位;否则代表该元素的布局继承于父元素
- 通过
element.currentStyle.hasLayout
可以得出当前元素的hasLayout情况 - 默认触发hasLayout的标签:
【1】html,body
【2】table,tr,th,td
【3】img
【4】hr
【5】input,button,select,textarea,fieldset
【6】frameset,frame,iframe
- 触发hasLayout的CSS属性:
【1】display: inline-block
【2】height/width: 除了auto
【3】float: left/right
【4】position: absolute
【5】writing-mode(IE专有属性,设置文本的垂直显示): tb-rl
【6】zoom(IE专有属性,设置或检索对象的缩放比例): 除了normal外的任意值
【7】width: 除 “auto” 外的任意值
【8】height: 除 “auto” 外的任意值
- IE7专有的触发hasLayout的CSS属性:
【1】min-height/max-height/min-width/max-width: 除了none外的任意值
【2】overflow\overflow-x\overflow-y: 除了visible外的任意值
【3】position: fixed
- 用途:
- 解决IE7-浏览器下父级边框不阻止子级上下 margin 传递的bug
- 配合 display:inline 让块元素模拟 inline-block
- 解决在IE7-浏览器下LI4px空隙bug(IE7-浏览器下li有高度或宽度或 zoom:1,且仅包含内联元素,且内联元素被设置为 display:block,li下会多出3px的垂直间距)
- 触发浮动元素的父级的hasLayout,浮动元素会被layout元素自动包含,相当于IE7-浏览器下实现清浮动
层模型(Layer)
- 如何让html元素在网页中精确定位,就像图像软件Photoshop中的图层一样可以对每个图层能够精确定位操作。CSS定义了一组定位(positioning)属性来支持层布局模型