目次
1.normal flow
2.containing block
3.BFC
1.normal flow
normal flow(正常流):正常流是默认的定位方式。任何没有详细指定{position:absolute}大概{position:fixed}属性以及没有被浮动的元素都将默认得到此属性。
在这种方式里,块级元素在它们的包含块里一个一个垂直延伸,行内元素在它们的包含块里从左至右的水平排布。
值得注意的是,在正常流里垂直边距(vertical margin)是重叠的。也就是说,上下两个块级盒之间的边距由它们之中边距较大的元素决定,而不是他们的和!
<style>
div
{
width: 100px;
height: 100px;
border: 1px solid #00A4CC;
background-color: #3e8f3e;
}
.div1
{
margin:20px 0;
}
.div2
{
margin:40px 0;
}
</style>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
</body> 复制代码
结果表现如下:
div1和div2的垂直间隔由大的margin决定,也就是div2的40px而不是二者之和60px。
其次,行内元素是会被折断的,当宽度受到限制的时候,它会自动移动到下一行。这可能会产生一些丢脸的结果如果行内块有边框的话。看下面的结果:<head>
<style>
div
{
width: 200px;
height: 100px;
border: 1px solid #00A4CC;
}
span
{
border: 2px solid #00ff00;
}
</style>
</head>
<body>
<div>
<span> 我会掉到下一行我会掉到下一行我会掉到下一行</span>
</div>
</body> 复制代码
结果表现如下:
2.containing block
containing block(包含块):是视觉格式化模子的一个告急概念,它与框模子类似,也可以明白为一个矩形,而这个矩形的作用是为它内里包含的元素提供一个参考,元素的尺寸和位置通常是由该元素所在的包含块决定的。也就是说一个元素盒子的位置和大小有时是通过相对于一个特定的长方形来计算的,这个长方形就被称之为元素的 containing block。
一个元素的containing block按照以下方式定义:
1.用户代理(比如浏览器)选择根元素作为 containing block(称之为初始 containing block)。
2.对于别的元素,除非元素利用的是绝对位置,containing block 由最近的块级先人元素盒子的内容边界构成。
3.如果元素有属性 'position:fixed',containing block 由视口创建。
4.如果元素有属性 'position:absolute',containing block 由最近的 position 不是 static 的先人创建,按下面的步骤:
如果先人是块级元素,containing block 由先人的padding edge形成。
如果先人是内联元素,containing block 取决于先人的 direction 属性。
如果 direction 是 ltr(左到右),先人产生的第一个盒子的上、左内容边界是 containing block 的上方和左方,先人的最后一个盒子的下、右内容边界是 containing block 的下方和右方。
如果 direction 是 rtl(右到左),先人产生的第一个盒子的上、右内容边界是 containing block 的上方和右方,先人的最后一个盒子的下、左内容边界是 containing block 的下方和左方。
5.如果没有先人,根元素盒子的内容边界确定为 containing block。
名词表明:
视口:通过解析文档,一连媒体(比如屏幕就是一连媒体,而打印机则是基于页的媒体)给用户产生一个视口(一个窗口或别的在屏幕上表现的区域)。
根元素:源文件中,每一个元素都有一个父元素,只有一个破例,它就是根元素。
padding edge:请拜见下图:
举个板栗:<html>
<head>
<title>Illustration of containing blocks</title>
</head>
<body id="body">
<div id="div1">
<p id="p1">This is text in the first paragraph...</P>
<p id="p2">This is text
<em id="em1"> in the
<strong id="strong1">second
</strong> paragraph.
</em>
</p>
</div>
</body>
</html> 复制代码
那么,在没有指定任何position的环境下,上方代码的containng block确定方式为:
如果我们设置div1的position为:#div1 { position: absolute;} 复制代码
此时,div1 的 containing block 就不再是 body,它变成了初始 containing block(因为这里还没有具有 position 的先人盒子)。
3.BFC
BFC(Block Formatting Context 块格式化上下文):是W3CCSS2.1规范中的一个概念,在CSS3中被修改为flowroot。格式化则表明确在这个环境中,元素处于此环境中应当被初始化,即元素在此环境中应当如何布局等。元素如果创建了BF么BFC决定了如何对其内容举行定位,以及它与其他元素的关系和相互作用。
普通明白:起首BFC是一个名词,是一个独立的布局环境,我们可以明白为一个箱子(实际上是看不见摸不着的),箱子内里物品的摆放是不受外界的影响的。转换为BFC的明白则是:BFC中的元素的布局是不受外界的影响(我们通常利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)而且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所构成)都会垂直的沿着其父元素的边框分列。
创建了BFC的元素会按照如下的方式对其子元素举行分列:
在BFC中,盒子从顶端开始垂直地一个接一个地分列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。便是在BFC中相邻的块级元素的垂直边距会折叠(collapse)。
在BFC中,每一个盒子的左外边沿(margin-left)会触遇到容器的左边沿(border-left)(对于从右到左的格式来说,则触遇到右边沿),即使存在浮动也是如此(尽管一个子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC,如它自身也是一个浮动。
名词表明:
边距折叠:在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是先人关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,而且因而所结合成的外边距称为折叠外边距。
折叠的结果:
1.两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
2.两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
3.两个外边距一正一负时,折叠结果是两者的相加的和。
产生折叠的必备条件:margin必须是连接的,且需要满足如下条件:
1.必须是处于通例文档流(非float和绝对定位)的块级盒子,而且处于同一个BFC当中。
2.没有线盒,没有空隙(clearance),没有padding和border将他们分隔开
3.都属于垂直方向上相邻的外边距,可以是下面任意一种环境
元素的margin-top与其第一个通例文档流的子元素的margin-top元素的
margin-bottom与其下一个通例文档流的兄弟元素的margin-top
height为auto的元素的margin-bottom与其最后一个通例文档流的子元素的margin-bottom
高度为0而且最小高度也为0,不包含通例文档流的子元素,而且自身没有创建新的BFC的元素的margin-top和margin-bottom
那么,什么环境下会创建BFC:
1.浮动元素(float:left|right)
2.绝对定位元素(position:absolute|fixed)
3.行内块元素(display:inline-block)
4.表格的单元格(display:table-cells,TD、TH)
5.表格的标题(display:table-captions,CAPTION)
6.'overflow'特性不为visible的元素
7.表格元素创建的"匿名框"
值得注意的是,"display:table" 本身并不产生 "block formatting contexts"。但是,它可以产生匿名框, 其中包含 "display:table-cell" 的框会产生块格式化上下文。
总之,对于 "display:table" 的元素,产生块格式化上下文的是匿名框而不是 "display:table"。
最后,是这些元素创建了块格式化上下文,它们本身不是块格式化上下文。
BFC的运用:消除浮动与多栏布局。
1.自顺应两栏布局<style>
body {
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body> 复制代码
结果如下:
根据BFC的规则:
每一个盒子的左外边沿(margin-left)会触遇到容器的左边沿(border-left)(对于从右到左的格式来说,则触遇到右边沿)
以是,虽然存在浮动的元素aslide,但main的左边依然会与包含块的左边相打仗。
因此,我们可以根据:
BFC的区域不会与float box重叠。
来通过触发main生成BFC,实现自顺应两栏布局。.main {
overflow: hidden;
} 复制代码
当触发main生成BFC后,这个新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄。结果如下:
2.清除内部浮动<head>
<title>Clear float</title>
<style>
.container{
margin: 30px auto;
width:600px;
height: 300px;
}
.wrapper{
border:solid 3px #a33;
}
.main{
width: 100px;
height: 100px;
background-color: #060;
margin: 10px;
float: left;
}
</style>
</head>
<body>
<div class="container">
<div class="wrapper">
<div class="main"></div>
<div class="main"></div>
<div class="main"></div>
</div>
</div>
</body> 复制代码
盼望的结果是:
但结果是:
父容器并没有把浮动的子元素困绕起来,俗称塌陷,为了消除这种现象,除了用传统的伪类方法。根据
计算BFC的高度时,浮动元素也加入计算
还可以使父容器形成BFC,来清除浮动,简单修改一下代码:<div class="wrapper" style="float:left;"> //添加一个float属性,形成BFC
<div class="main">1</div>
<div class="main">2</div>
<div class="main">3</div>
</div> 复制代码
可以得到如下结果:
总结来说,BFC就是页面上的一个隔离的独立容器,容器内里的子元素不会影响到外面的元素。反之也如此。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此,当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。克制margin重叠也是这样的一个原理。
以上就是浅谈由position属性引申的css进阶讨论的详细内容,更多关于由position属性引申的css进阶讨论的资料请关注脚本之家别的相干文章!