CSS布局秘籍(1)-任督二脉BFC/IFC
01、CSS布局
1.1、正常布局流(Normal flow)
正常布局流 就是不做任何布局控制,按照HTML的顺序(从左到右,从上而下)进行布局排列。网页基于盒子模型进行正常的布局,主要特点:
- 盒子布局:单个内容的布局,把内容放入盒子,加上盒子三件套(padding、boder、margin)。
- 块盒子纵向布局:块级元素单独一行,按照顺序垂直排列,并按其margin分离。
- 内联盒子水平布局:内联元素会在一行水平排列,高度、宽度都取决于内容,直到空间不足另起一行(换行)。高矮不齐,底部对齐。
- 边距折叠:垂直相邻元素的垂直
margin
会保留最大的那一个,就是盒子的外边距折叠。 - 空白折叠:无论多少个连续空格、换行、tab,都会折叠为一个空格。
块元素 | 行内元素 | |
---|---|---|
是否换行 | 独占一行,从新的一行开始,其后也另起一行 | 和其他行内元素在同一行 |
大小设置 | 元素的高、宽、行高、边距、对齐都可调整,宽度默认100% | 元素高、宽、外边距不可设置,根据内容自适应 |
包含元素 | 一般可包含其他行内元素和块元素 | 一般可包含其他行内元素,不可包含块元素 |
常见元素 | div,form、table,h1-h6,p,pre,ul/ol/li,dt/dl,hr,br | span,font,input,textarea,label,img,a,button,select |
盒子 | 块级盒子 (block box):应用完整的盒子模型 | 内联盒子 (inline box):部分盒子模型有效 |
- 还有一种混合型“行内块元素”属于行内元素的一种,和其他元素在一行,但元素的高、宽、外边距都可以设置,如
button
、img
、input
。- 通过CSS样式的
display
属性可以更改元素的布局类型,如可设置为一个块元素布局
display: block;
标准布局总是这样从左到右、从上而下的顺序排列。但当我们要实现一些特殊的的布局效果时就没法了,这时的办法就是 —— ??脱离文档流。
??脱离文档流,就是从正常文档流中移除,文档流布局就不考虑他了,也就不会占用空间。基本上可以这样理解,当然也不是绝对就没人管了,他的父容器还是管的,至于怎么管看《格式化上下文》。
常用的脱离文档流的方式:float
、position
- float浮动,会使元素脱离文档流,移动到容器左/右边,后面元素会围绕浮动元素。
- position定位,绝对定位(absolute)、固定定位(fixed),会使元素脱离文档流,空出来的位置被后续元素代替,所以会出现和其他元素重叠的问题。
1.2、display布局属性
正常流中的所有元素都有一个display
的值,这个属性允许我们更改默认的显示方式。display
用来设置多种布局方式,可让不同元素类型(行、块元素)转换。
属性/值 | 描述 |
---|---|
display | 设置元素显示类型,包括下面这些枚举值 |
?none | 元素隐藏不显示,不占据空间、无交互,常用于隐藏元素 |
?block | 此元素将显示为块级元素 |
?inline | 内联,此元素会被显示为内联元素 |
?inline-block | 行内块元素(CSS2.1),介于内联和块之间,除了不换行,高宽、盒子三件套都有效。 常用
的
|
?flex IE11 | 弹性盒子布局(横向布局),inline-flex 内联的弹性盒子 |
?grid | 非常灵活的网格布局,有些属性IE不支持。inline-grid 内联的网格布局 |
?list-item | 此元素会作为列表,类似
,父元素显示为 block 盒,内部变为多个 list-item inline 盒 |
?table | 表格布局,同家族还有个inline-table 内联表格布局、table-row、table-cell |
?contents | 伪盒子,充当遮罩的元素,不会产生任何盒子(不会被渲染),但不影响其子元素的布局和渲染 |
?flow-root IE?? | 建立一个无副作用的BFC |
span元素2
div元素
02、什么是响应式布局?
2.1、响应式设计
响应式网页设计(responsive /r??sp?ns?v/ web design,RWD)指的是允许 Web 页面适应不同屏幕宽度等因素,进行布局和外观的调整的一系列实践。它涵盖了很多 CSS 和 HTML 的功能和技术,现在也基本是我们默认建设网站的方式。
如上图,基于媒体查询和现代布局,响应式设计成为当下的主流。通过媒体查询测试,针对不同的尺寸适配不同的CSS样式、图片,如调整字体大小、段落填充、菜单按钮布局、以及增大触摸按钮的大小等,让网页能够自适应各种设备尺寸、设备类型。
- 响应式图形,创建多种尺寸版本文件,基于
srcset
、sizes
,适配合适尺寸的文件。或者改用新的
元素。
- 响应式排版,传统方式可以结合vw单位(视口的1%)、固定尺寸rem、px单位,现在可以基于媒体查询设置不同样式规则。
.p1 {
font-size: calc(1rem + 2vw);
}
@media screen and (min-width:1440px) {
.p1 {
font-size: 150%;
}
}
- 视口元标签,明确视口的宽度为设备的宽度,并初始化缩放比例为1,建议添加如下元素申明。
2.2、@媒体查询
媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式,媒体查询的标准语法:
@media media-type and (media-feature-rule) { /* CSS规则 CSS rules go here */ } ??/* 注意关键字
and
后面的空格 */
属性 | 描述 | 值/备注 |
---|---|---|
@media | 媒体查询申明 | |
?media-type | 媒体类型 | - all:所有设备 - screen:屏幕,常用 - speech:语音合成器;print:打印,网页打印的时候 |
?逻辑操作符(and) | 连接多个媒体查询语句 | - and:查询条件都满足的时候才生效 - not:查询条件取反 - only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型 - 逗号或者 or:查询条件满足一项即可匹配; |
?media-feature-rule | 媒体特征规则,一些条件表达式,常用尺寸判断 | - min-width:>=最小宽度;max-width:<=最大宽度 - 更多媒体查询特征,如 orientation (屏幕方向) |
@import | 导入外部css样式,支持媒体查询 | @import url(example.css) screen and (width:800px) ; |
/* 媒体查询:在大尺寸模式启用flex布局,横向排列 */
@media screen and (min-width: 40em) {
.nav ul {
display: flex;
}
.nav li {
flex: 1;
}
}
响应式布局-代码示例(Codepen)
03、CSS的格式化上下文
所有元素都是一个盒子Box,盒子Box是页面布局的基本单位,盒子的不同类型决定了他的布局方式。一个页面由各种盒子的组合、嵌套形成。这些盒子各不相同,有些是横排,有些竖排,有些是弹性,有些是网格,那他们是如何布局的呢?这就必须要了解的一个概念——格式化上下文。
格式化上下文(Formatting Contexts),就是把页面内容分为多个不同的格式化上下文(区域),每个格式化上下文都是一个独立的渲染(布局)区域,存放同类型的盒子。根据盒子的不同,格式化上下文分为多种(四种)类型,每种类型有自己的渲染规则,决定了其内部子元素的定位、排列方式。
格式化上下文 | 简述 |
---|---|
BFC:块级格式化上下文 | Block fomatting context ,由块级盒子组成的上下文区域,纵向排列。需要重点了解的,浮动float 布局的各种坑就靠他来填了。 |
IFC:内联级格式上下文 | Inline formatting context,内联格式上下文,就是横向布局的内联盒子,由内联盒子构成 |
FFC:弹性盒格式化上下文 | Flexible Formatting Contex,就是flex 布局的弹性盒子,申明flex (或inline-flex )布局就是创建了一个FFC弹性盒子格式上下文。 |
GFC:网格格式化上下文 | Grids Formatting Context,就是grid (或inline-grid )布局的盒子,二维网格布局,使用很方便。不过由于兼容性问题(很多属性不支持IE),使用还不广泛,不过现代浏览器基本都支持了。 |
实际上这些格式上下文也是相互嵌套的,各自负责各自区域进行渲染(布局)。
上图仅为个人理解。
04、BFC-块级格式化上下文
Block fomatting context (= block-level box + Formatting Context),块级格式化上下文,简称 BFC。是一个独立的渲染(布局)区域,用于给块级盒子布局,包含的都是块级盒子。
??基本规则:
- 块级元素:首先BFC本身也是“块级盒子”(当然实际DOM中并没有这个盒子元素),其内部也都是块级元素盒子。
- 独立主权:该区域的内部无论有什么东西、如何排列、在干什么,都不影响其外部,反之亦然。
- 垂直排列:BFC内部的Box垂直排列,从上往下依次排列。
- 垂直 margin 重叠:垂直方向间距由
margin
决定,同一BFC内相邻的Box的margin
重叠,看谁的大就谁的。so,不是在同一个BFC则不会发生边距重叠。 - 左边距,BFC中每个盒子,都是从其父容器Box的左边界开始,包括浮动元素也是这样。
- 不会重叠:BFC区域不会与浮动盒子(float box)重叠,会向后找新的区域排列。注意?,这是解决浮动盒子重叠的关键。
- BFC高度:计算BFC高度时,会包含浮动元素(float box)。注意?,这是解决高度坍塌、清除浮动的关键。
??如何触发BFC?
html
根元素,最大的BFC。float
浮动:left、right,脱离了文档流,自成一派。自成一个独立BFC,它的内部是正常流布局。position
定位:absolute、fixed,脱离了文档流,自成一派,同float
浮动一样。overflow
溢出,属性值不为 visible,常用overflow: hidden
触发容器为BFC。display
值:一个块级盒子,为独立BFC区域:- 行内块级盒子:inline-block
- 表格类盒子:table、table-cell、table-caption、inline-table
- 弹性盒子:flex 、inline-flex
- 网格盒子:grid 、inline-grid
??注意:上面这些场景会触发创建块格式化上下文,而不是这些盒子本身。
??使用场景
BFC主要还是浏览器用来渲染布局用的,在实际开发中可以利用他的这些规则做哪些事情呢?—— 处理浮动float
布局的烂摊子!
① float导致的高度塌陷
? 问题:如果一个块级盒子如
float
,他们都脱离了文档流,会导致盒子高度塌陷,就是高度没了。这时就会影响后面元素的布局了,造成不想看到的情景,float
这个渣...
? 解决方法:触发这个容器的BFC
,因为BFC
在计算高度的时候会考虑内部的浮动元素,浮动元素本身也是一个独立BFC。
div1
div2
艰难的撑起了一点高度
? 父容器div
的高度坍塌,因为没有计算浮动元素。触发父容器BFC即可解决
② float导致的盒子重叠/环绕
? 问题:如下示例,父容器