CSS 布局模型
流动模型(Flow)
- 含义:流动(Flow)是默认的网页布局模式。也就是说网页在默认状态下的 HTML 网页元素都是根据流动模型来分布网页内容的;
- 特征:
- 行内元素/内联元素(display:inline):a、span、strong、u、em;不独占一行,左右结构;设置宽高不起作用,需要转化 display:block / inline-block / float(自动加上display:block);受换行符的影响会产生默认的间距 => 父容器 font-size:0 (去间距);
- 块级元素(display:block): div、p、h1-h6、ol-li、ul-li、dl、dt、dd、header、footer;独占一行 上下结构;设置宽高起作用;
- 行内块元素(display:inline-block):i、img、input、textarea;设置宽高起作用;不独占一行 左右结构;
浮动模型(Float)
- 含义:
- 通过 css 的 float 属性可以将元素设置为浮动元素,元素浮动之后不再占据原来的位置,它们会尽可能的往包裹它们的父元素的左边框或右边框靠,并会在它们元素所处位置的下面产生浮动流,影响下面的元素定位;
- 浮动元素并没有完全脱离文档流,它只是从包裹它的盒子中浮动起来并尽可能远的往左侧或者右侧进行移动;
- 浮动设计的初衷是为了实现文字在图片周围的环绕效果;
- 清浮动方法:
- 方法一:手动添加 height;缺点: 高度固定死;
- 方法二:overflow:hidden;BFC 元素会把浮动元素的高度计算进来;缺点: 溢出隐藏 - 下拉框;
- 方法三:clear:left/right/both;块的特点(div) + clear:both + 空内容;缺点: 添加无意义空标签;
- 方法四:伪元素选择器 after;缺点: 代码量大
/* 公用的代码片段 clearfix + clear reset.min.css*/ .clearfix::after { content: ''; display: block; clear : both; /* 让元素消失:封装成公共样式的时候加上*/ width : 0; height : 0; font-size : 0; overflow : hidden; visibility: hidden; }
层模型(Layer)
- 含义:层布局模型就像是图像软件 PhotoShop 中非常流行的图层编辑功能一样,每个图层能够精确定位操作,但在网页设计领域,由于网页大小的活动性,层布局没能受到热捧。但是在网页上局部使用层布局还是有其方便之处的;
- 层模型有三种形式:
- 相对定位(position: relative);
- 绝对定位(position: absolute);
- 固定定位(position: fixed);
BFC 的原理和功能
BFC 的含义
- BFC(block formatting context)块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则,它决定了元素如何对齐内容进行布局,以及与其他元素的关系和相互作用,当涉及到可视化布局的时候,BFC提供了一个环境,HTML 元素在这个环境中按照一定规则进行布局;
- 具有 BFC 特性的元素可以看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的的一些特性;
- BFC 是一个独立的布局环境,BFC 内部的元素布局与外部互不影响;
BFC 的布局规则:
- 内部的盒子会在垂直方向,一个个地放置;
- 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的上下 margin 会发生重叠;
- 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;
- BFC 的区域不会与 float box 重叠;
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
- 计算 BFC的 高度时,浮动元素也参与计算;
触发 BFC 的条件
- 浮动元素(元素的 float 不是 none)
- overflow 为 auto、scroll、hidden
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值)
- 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- overflow 计算值(Computed)不为 visible 的块元素
- 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
- 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width (en-US) 不为 auto,包括 column-count 为 1)
- column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中
BFC的用处
案例一: 让浮动内容和周围的内容等高
- overflow:auto 创建一个会包含这个浮动的 BFC,通常的做法是设置父元素 overflow: auto 或者设 置其他的非默认的 overflow: visible 的值.
- 使用display: flow-root; 一个新的 display 属性的值,它可以创建无副作用的 BFC。在父级块中使 用 display: flow-root 可以创建新的 BFC.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>让浮动内容和周围的内容等高</title> <style> .box1 { background-color: rgb(224, 206, 247); border: 5px solid rebeccapurple; /* * BFC的区域不会与float box重叠; * 计算BFC的高度时,浮动元素也参与计算; */ overflow: hidden; } .float1 { width: 200px; height: 150px; background-color: white; border: 1px solid black; padding: 10px; float: left; } </style> </head> <body> <div class="box1"> <div class="float1">I am a floated box!</div> <p>I am content inside the container.</p> </div> </body> </html>
让浮动内容和周围的内容等高 I am a floated box!I am content inside the container.
案例二: 外边距折叠
- 原因: Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠;
- 解决方法: 给上 box 或者下 box 任意一个包裹新的 box 并开启 BFC;
- 原理: BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>外边距折叠</title> <style> .p1,.p2 { color: #f55 !important; background: #fcc !important; width: 200px !important; line-height: 100px !important; text-align: center !important; } .p1 { margin-bottom: 20px !important; } .p2 { margin-top: 30px !important; } .box { /* * 盒子垂直方向的距离由 margin 决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠; * 使用box 将同处在同一个bfc下的两个 p标签 分开,破坏原来的bfc */ overflow: hidden !important; } </style> </head> <body> <p class="p1">你好</p> <div class="box"> <p class="p2">你好</p> </div> </body> </html>
外边距折叠 你好
你好
案例三: 清除浮动
- 解决方法: 给父元素开启 BFC
- 原理: 计算 BFC 的高度时,浮动子元素也参与计算
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>清除浮动</title> <style> .container33 { width: 300px; border: 5px solid #fcc; overflow: hidden; } .box33 { width: 100px; height: 100px; float: left; border: 5px solid #f66; } .test{ padding: 10px 0; background: #eee; } </style> </head> <body> <div class="container33"> <div class="box33"></div> <div class="box33"></div> </div> <div class="test">用来测试是否清除了浮动</div> </ul> </body> </html>
清除浮动 用来测试是否清除了浮动案例四: 自适应的两列布局(左图右文)
- 解决方法: 给父元素开启 BFC
- 原理: BFC 的区域不会与 float box 重叠;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>自适应两栏布局</title> <style> /* * 两大css原理: * 1.层叠上下文 - 层叠顺序 浮动 > 块状 * 2.BFC - 元素不会与浮动元素产生重叠 */ .aside11 { float: left; width: 100px; height: 150px; background: #f66; } .main11 { overflow: auto; height: 200px; background: #fcc; } </style> </head> <body> <div class="aside11"></div> <div class="main11"></div> </body> </html>
自适应两栏布局
IFC 的原理和功能
IFC 的含义
- IFC(inline Formatting Context)叫做 “内联格式化上下文”
- 内部的元素从包含块的顶部开始,从左至右(默认)排列成一行形成的一个矩形盒子叫做 line box;
IFC 的布局规则
- 盒子是水平一个接一个的排列,水平 的 margin,内边距,边框是可以有的;
- 垂直方向的对齐,可能是底部对齐,顶部对齐,也可能是基线对齐(这个是默认的);
- 行框中的内联盒子的高度小于行框的高度时,内联盒子的垂直方向的对齐方式取决于 vertical-align 属性;
- 当一个行框水平不能容纳内联盒子时,他们将会在垂直方向上产生多个行框,他们上下一个挨着一个,但是不会重叠;
- 多个内联盒子的宽度小于包含他们的行框时,他们在水平方向的分布取决于 text-align 属性;
IFC 的作用
水平居中:当一个块要在环境中水平居中时候,设置其为 inline-block 则会在外层产生 IFC,通过 text-align:center 则可以使其水平居中;
<style> .box_0 { width: 500px; height: 100px; background-color: rosybrown; text-align: center; } .child_0 { display: inline-block; width: 80px; height: 50px; background-color: seagreen; } </style> <div class="box_0"> <div class="child_0"></div> <div class="child_0"></div> </div>
垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中;
<style> .box_1 { width: 500px; background-color: rosybrown; display: inline-block; } .child_1 { display: inline-block; width: 80px; height: 50px; background-color: seagreen; vertical-align: middle; } </style> <div class="box_1"> <div class="child_1"></div> <div class="child_1" style="height: 100px;"></div> </div>
CSS 渲染和解析原理
- 浏览器渲染原理
- 浏览器在接收到服务器返回的 html页面后;
- 浏览器开始构建 DOM 树 DOM TREE,遇到 CSS 样式会构建 CSS 规则树 CSS RULE TREE;
- 遇到 javascript 会通过 DOM API 和 CSSDOM API 来操作 DOM Tree 和 CSS Rule Tree,解析完后;
- 浏览器引擎会通过 DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree(渲染树);
- 最后,渲染树构建完成后就是 “布局” 处理,也就是确定每个节点在屏幕上的确切显示位置;
- 下个步骤(渲染之后),开始 “绘制” ,遍历渲染树,将每一个节点绘制出来;
- CSS 渲染规则
- CSS 的渲染规则,是从上到下,从右到左渲染的;
.main h4 a { font-size: 14px; }
- 渲染过程是这样的:
- 首先找到所有的 a,沿着 a 的父元素查找 h4,然后再沿着 h4,查找 .main;
- 中途找到了符合匹配规则的节点就加入结果集;
- 如果找到根元素的 html 都没有匹配,则这条路径不再遍历;
- 下一个 a 开始重复这个查找匹配,直至没有 a 继续查找;
- 浏览器的这种查找规则是为了尽早过滤掉一些无关的样式规则和元素;
- CSS 的渲染规则,是从上到下,从右到左渲染的;
CSS 性能优化
- 尽量避免类似 .a.b{}、.list a{}以及其他一些复杂选择器,以提高整站整体CSS渲染;
- 避免某些 expression 表达式;
- 图片设定不响应重绘的尺寸,如果 <img> 不设定尺寸、同时外部容器没有定死高宽,则图片在首次载入时候,占据空间会从 0 到完全出现,左右上下都可能位移,发生大规模的重绘,可以使用 width/height 控制,或者在 CSS 中设置;
- <textarea> 或者使用 <script type=”text/html”> 存储动态载入 HTML 或模板 HTML,降低首屏加载的渲染时间;
- 具有复杂动画的元素 绝对定位-脱离文档流,避免强烈的回流,现代浏览器可以渐进使用 CSS3 transition 实现动画效果,比改变像素值来的高性能;
- 不使用 iframe,据说开销最大的 DOM 元素;
- 不要使用类选择器和 ID 选择器修饰元素标签, 例如: p#id1 {color:red;};
- 保持简单,不要使用嵌套过多过于复杂的选择器, 避免深层次,嵌套层级不要超过三级;
- 通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用;
- 通常将浏览器前缀置于前面,将标准样式属性置于最后,例如: -moz-border-radius: 5px; border-radius: 5px;
- 减少 CSS 文件体积: 移除空的 CSS 规则、值为 0 不需要单位,复合属性使用缩写、属性值为浮动小数 0.*,可以省略小数点之前的 0、不给 h1-h6 元素定义过多的样式;
- 把 Stylesheets 放在 HTML 页面头部, 不要使用 @import;
- 减少使用昂贵的属性,如 box-shadow/border-radius/filter/ 透明度 /:nth-child 等;
- 优化重排与重绘:减少重排、避免不必要的重绘;
- 小图标的处理方案: cssSprite、字体图标 font-face、base64 编码;
CSS 高级✍️ icon 全解析
上一篇