css布局详解(⼆)——标准流布局(Nomalflow)
css标准流布局(Nomal flow)
⼀、正常流
这是指西⽅语⾔中⽂本从左向右,从上向下显⽰,这也是我们熟悉的传统的HTML⽂档中的⽂本布局。注意,在⾮西⽅的语⾔中,流⽅向可能不同。⼤多数元素都在正常流中,要让⼀个元素不在正常流中,唯⼀的⽅法就是使之成为浮动元素或定位元素。
标准流中,块级元素独占⼀⾏,垂直放置。⾏级元素在⽔平⽅向上⼀个接⼀个的排列。
⼆、垂直外边距的合并问题(margin collapse)
在标准流布局中垂直外边距的合并有两种情况。
1、在标准流中上下两个盒⼦的外边距回合,即上盒⼦的margin-bottom会与下盒⼦的margin-top合并为两者之间的最⼤值。
css代码:
div{
width: 100px; height: 100px; }
.top{
margin-bottom: 50px; background: purple; }
.bottom{
margin-top: 20px; background: pink; }
html代码:
<div class="top"></div>
<div class="bottom"></div>
2、⼀个盒⼦包裹另⼀个盒⼦,当包裹盒⼦没有设置border和padding时,⾥边盒⼦的设置的上边距不会起作⽤。
css代码:
.father{width: 400px; height: 400px; background: pink; }
.son{width: 200px; height: 200px; background: purple; margin-left: 100px; margin-top: 50px; }
html代码:
<div class="father">
<div class="son">
</div>
设置边框后
解释:
对于⽗块DIV内含⼦块DIV的情况,就会按另⼀条CSS惯例来解释了,那就是:对于有块级⼦元素的元素计算⾼度的⽅式,如果元素没有垂直边框和填充,那其⾼度就是其⼦元素顶部和底部边框边缘之间的距离。
解决⽅法:
解决⽗⼦DIV中顶部margin cllapse的问题,需要给⽗div设置:
(1)、边框,当然可以设置边框为透明;
border:1px solid transparent
border-top:1px solid transparent
(2)、为⽗DIV添加padding,或者⾄少添加padding-top;
此外,还可以通过over-flow来解决,给⽗DIV写⼊:
over-flow:hidden;
三、BFC
1、BFC是什么?
在解释 BFC 是什么之前,需要先介绍Box、Formatting Context的概念。
Box 是 CSS 布局的对象和基本单位,直观点来说,就是⼀个页⾯是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。不同类型的 Box,会参与不同的 Formatting Context(⼀个决定如何渲染⽂档的容器),因此Box内的元素会以不同的⽅式渲染。让我们看看有哪些盒⼦:
block-level box:display 属性为 block, list-item, table 的元素,会⽣成 block-level box。并且参与 block fomatting context;
inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会⽣成 inline-level box。并且参与 inline formatting context;
Formatting context
Formatting context 是 W3C CSS2.1 规范中的⼀个概念。它是页⾯中的⼀块渲染区域,并且有⼀套渲
染规则,它决定了其⼦元素将如何定位,以及和其他元素的关系和相互作⽤。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC。
BFC 定义
BFC(Block formatting context)直译为"块级格式化上下⽂"。它是⼀个独⽴的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相⼲。
BFC布局规则:
内部的Box会在垂直⽅向,⼀个接⼀个地放置。
Box垂直⽅向的距离由margin决定。属于同⼀个BFC的两个相邻Box的margin会发⽣重叠
每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠。
BFC就是页⾯上的⼀个隔离的独⽴容器,容器⾥⾯的⼦元素不会影响到外⾯的元素。反之也如此。
计算BFC的⾼度时,浮动元素也参与计算
2、哪些元素会⽣成BFC?
根元素
float属性不为none
position为absolute或fixed
display为inline-block, table-cell, table-caption, flex, inline-flex
overflow不为visible
3、BFC的作⽤及原理
1. ⾃适应两栏布局
<body> <div class="aside"></div> <div class="main"></div> </body>
根据BFC布局规则第3条:
每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如
此。
  因此,虽然存在浮动的元素aslide,但main的左边依然会与包含块的左边相接触。
  根据BFC布局规则第四条:
BFC的区域不会与float box重叠。
我们可以通过通过触发main⽣成BFC,来实现⾃适应两栏布局。
.main {
overflow: hidden;
}
  当触发main⽣成BFC后,这个新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,⾃动变窄。
2. 清除内部浮动
代码
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
页⾯
根据BFC布局规则第六条:
计算BFC的⾼度时,浮动元素也参与计算
  为达到清除内部浮动,我们可以触发par⽣成BFC,那么par在计算⾼度时,par内部的浮动元素child也会参与计算。
  代码:
.par {
overflow: hidden;
}
  效果如下:
3. 防⽌垂直 margin 重叠
代码
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
padding是外边距还是内边距
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
页⾯
两个p之间的距离为100px,发送了margin重叠。
  根据BFC布局规则第⼆条:
Box垂直⽅向的距离由margin决定。属于同⼀个BFC的两个相邻Box的margin会发⽣重叠
  我们可以在p外⾯包裹⼀层容器,并触发该容器⽣成⼀个BFC。那么两个P便不属于同⼀个BFC,就不会发⽣margin重叠了。  代码:
<style>
.wrap {
overflow: hidden;
}
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
页⾯
总结
其实以上的⼏个例⼦都体现了BFC布局规则第五条:
BFC就是页⾯上的⼀个隔离的独⽴容器,容器⾥⾯的⼦元素不会影响到外⾯的元素。反之也如此。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此,当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,⽽不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算⾼度时会包括浮动的⾼度。避免margin重叠也是这样的⼀个道理。
IFC
IFC(Inline Formatting Contexts)直译为"内联格式化上下⽂",IFC的line box(线框)⾼度由其包含⾏内元素中最⾼的实际⾼度计算⽽来(不受到竖直⽅向的padding/margin影响)
IFC中的line box⼀般左右都贴紧整个IFC,但是会因为float元素⽽扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。同个ifc下的多个line box⾼度会不同。 IFC中时不可能有块级元素的,当插⼊块级元素时(如p中插⼊div)会产⽣两个匿名块与div分隔开,即产⽣两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
那么IFC⼀般有什么⽤呢?
⽔平居中:当⼀个块要在环境中⽔平居中时,设置其为inline-block则会在外层产⽣IFC,通过text-align则可以使其⽔平居中。
垂直居中:创建⼀个IFC,⽤其中⼀个元素撑开⽗元素的⾼度,然后设置其vertical-align:middle,其他⾏内元素则可以在此⽗元素下垂直居中
GFC
GFC(GridLayout Formatting Contexts)直译为"⽹格布局格式化上下⽂",当为⼀个元素设置display值为grid的时候,此元素将会获得⼀个独⽴的渲染区域,我们可以通过在⽹格容器(grid container)上定义⽹格定义⾏(grid definition rows)和⽹格定义列(grid definition columns)属性各在⽹格项⽬(grid item)上定义⽹格⾏(grid row)和⽹格列(grid columns)为每⼀个⽹格项⽬(grid item)定义位置和空间。
那么GFC有什么⽤呢,和table⼜有什么区别呢?⾸先同样是⼀个⼆维的表格,但GridLayout会有更加丰富的属性来控制⾏列,控制对齐以及更为精细的渲染语义和控制。
FFC
FFC(Flex Formatting Contexts)直译为"⾃适应格式化上下⽂",display值为flex或者inline-flex的元素将
会⽣成⾃适应容器(flex container),可惜这个⽜逼的属性只有⾕歌和⽕狐⽀持,不过在移动端也⾜够了,⾄少safari和chrome还是OK的,毕竟这俩在移动端才是王道。
Flex Box 由伸缩容器和伸缩项⽬组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到⼀个伸缩容器。设置为 flex 的容器被渲染为⼀个块级元素,⽽设置为 inline-flex 的容器则渲染为⼀个⾏内元素。
伸缩容器中的每⼀个⼦元素都是⼀个伸缩项⽬。伸缩项⽬可以是任意数量的。伸缩容器外和伸缩项⽬内的⼀切元素都不受影响。简单地
说,Flexbox 定义了伸缩容器内伸缩项⽬该如何布局。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。