前言
最近在改造之前项目的UI,发下自身对于css的许多知识掌握的还没有成体系化,乘着最近有时间就来看看我们熟悉又陌生的CSS,先说下学习路径:菜鸟教程(指的是看的人菜),MDN,掘金小册玩转CSS的艺术之美。结合着看,集百家之长,补己之短。
本章知识点:渲染流程 回流重绘 布局类型 盒模型 BFC
渲染方式
学习css我们必须先要了解css在浏览器中是如何渲染成我们看到的样子,本节主要介绍下整个大概流程,详细的渲染原理目前我也不是非常了解后期有空在去研究下。
解析文件流程
- HTML解析器:解析HTML为DOM树
- CSS解析器:解析CSS为CSS树
- 渲染引擎:合并CSS树和HTML树为渲染树
- 渲染器:绘制图层
- JS引擎:执行JavaScript :解析文件=》绘制图层=》合成图层
解析HTML/解析CSS
合并CSS/HTML树为渲染树
遍历渲染树绘制图层:回流/重绘
合并所有绘制的图层并且显示在屏幕
回流与重绘
- 回流:几何属性的修改会导致浏览器的重新渲染(浏览器会清空页面重新绘制图层合并图层,只是我们自己感受不到罢了)常见的以下属性会触发回流:display float margin padding ......。
- 重绘:更改DOM的外观属性却不影响几何属性的渲染,浏览器只会重新渲染更改的部分不会重新渲染,常见的以下属性会触发回流:background color mask outline....。
- 优化:尽量减少浏览器的回流与重绘的次数。
基础布局
记得我大学时接触的前端,那时候上课老师是教我们使用前端三剑客Dreamware/flash/ps,Dreamware印象尤为深刻,拖拖拽拽就能生成一个网页,刚开始学习的就是使用table布局,记得那时候流行的也是table结构化布局,页面布局这个能力应该可以说是我们前端入门的基础。目前常用的布局我觉可以分为三类:普通布局(block,table),脱离文档流布局(float,position),响应式布局(flex,grid,column,vm/vw/rem...)
盒模型
如果要想熟练掌握css的布局,那我们必须去了解下css的布局模型-盒模型,因为盒模型的概念是我们排版和布局的基础。在MDN中对于盒模型的说明:在 CSS 中,所有的元素都被一个个的“盒子(box)”包围着。
- 组成结构:margin(外边距) border(线)padding(内边距)content(内容)
- 类型(box-sizing):标准盒模型(content-box) 怪异盒模型(border-box)
- 怪异盒模型:margin content组成,
- margin塌陷(垂直上下的两个div):上面的设置margin-bottom,下面设置margin-top,最后他们的间距只会取最大的margin,而不是两者之和
- margin塌陷(父子元素):父元素中的子元素设置margin top会影响到父元素的位置。
网络异常,图片无法展示|
<p>塌陷问题兄弟元素</p> <div class="top">top </div> <div class="bottom">bottom </div> <p>塌陷问题父子元素</p> <div class="main"> <div class="child">子元素 </div> </div> <style> .main{ width:200px; height:200px; background:red; } .child{ width:100px; height:100px; margin-top:100px; background:yellow; } .top{ background:green; height:150px; width:150px; margin-bottom:50px; overflow:hidden; } .bottom{ background:green; height:150px; width:150px; margin-top:50px; } </style>
块格式化上下文
提到盒模型那就需要去了解下块格式化上下文了,在MDN中块格式化上下文:块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是盒子块的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
BFC的特性如下:
- 布局方向:内部的Box会在垂直方向,一个接一个地放置。
- margin距离:Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
- 每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- 区域不重叠:BFC的区域不会与float box重叠。
- 独立容器:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 高度计算:浮动元素也参与计算。
BFC的作用如下:
- 避免margin塌陷的问题
- 使 BFC 内部浮动元素不会到处乱跑;
- 和浮动元素产生边界。
<p>normal demo</p> <div style="border:solid 10px red;min-height:20px;"> <div class="float1"></div> </div> <p style="clear:both;">BFC DEMO</p> <div class="bfc"> <div class="float2"></div> </div> <p >BFC塌陷问题父子元素</p> <div class="main"> <div class="child">子元素 </div> </div> <style> .bfc{ display:inline-block; margin-top:50px; border:solid 10px red; min-height:30px; } .float1{ float:left; height:50px; width:100px; background:yellow; } .float2{ float:left; height:50px; width:100px; background:green; } .main{ width:200px; height:200px; display:inline-block; background:red; } .child{ width:100px; height:100px; margin-top:100px; background:yellow; } .top{ background:green; height:150px; width:150px; margin-bottom:50px; overflow:hidden; } .bottom{ background:green; height:150px; width:150px; margin-top:50px; } </style>
布局类型
下面简单的介绍下集中常见的布局
- table:table布局是前端早期布局常用的属性之一,他把页面看成一个表格,每一块内容是一个单元格。记得实现一些复杂的页面有可能需要单元格中再嵌套一个表格。
- block:普通布局(block)就是我们按正常的文档流进行布局,从左到右,从上到下。
//table <table border="1"> <tr> <th>姓名</th> <th>年龄</th> <th>身高</th> <th>体重</th> <th>备注</th> </tr> <tr> <td>name2</td> <td>24</td> <td>168cm</td> <td>57kg</td> <td>eeeee</td> </tr> <tr> <td>name3</td> <td>24</td> <td>168cm</td> <td>57kg</td> <td>eeeee</td> </tr> </table> // block <div>block</div>
// 脱离文档流
- float:浮动布局
- position(relative/fixed/absolute):定位布局是我们布局中比较常用的一种,例如固定导航栏,弹窗等等都需要用到定位布局的属性,其主要属性有position:relative/fixed/absolute left top right bottom....,如下所示:。
<style> div.parent { width:100vw; height:100vh; background:gray; } div.child{ width:200px; height:200px; background:blue; position:absolute; top:50%; left:50%; margin-top:-100px; margin-left:-100px; } </style> </head> <body> <div class="parent"> <div class="child"></div> </div> </body>
使用position和margin实现居中布局
// 响应式布局
- flex:flex布局,
<style> div.parent { width:100vw; height:100vh; display:flex; background:gray; justify-content:center; align-items:center; } div.child{ width:200px; height:200px; background:blue; } </style> </head> <body> <div class="parent"> <div class="child"></div> </div> </body>
使用flex可以轻松实现居中布局
- grid:栅格布局
div.parent { width:400px; background:gray; display:grid; grid-template-columns: repeat(4,100px); grid-template-rows:repeat(4,100px); justify-items:center; align-items:center; } div.child{ background:blue; border:solid 1px #ddd; font-size:18px; width:50px; height:50px; } </style> </head> <body> <div class="parent"> <div class="child">1</div> <div class="child">2</div> <div class="child">3</div> <div class="child">4</div> <div class="child">5</div> <div class="child">6</div> <div class="child">7</div> <div class="child">8</div> <div class="child">9</div> </div> </body>
- column:列布局
就我目前的开发来看,自身用的定位布局和响应式布局还是偏多的,另外基本上这两种布局就可以处理很多常见的问题了,另外一些布局的详细属性这里就不再叙述了,大家有空可以对着文档在codeopen上多写写。
总结
前端的工作无论你是刚开始接触的小白,还是工作多年的前辈,我们都应该不断的学习与温故。前端的知识广而杂时常不看就会生疏,走出自己的舒适圈,接受新技能方能不断进步,另外说下本篇是css系列的首篇,主要是关于布局相关的总结与理解,后续还会有样式和其他的一些知识总结,有兴趣的可以继续看看。 学而不厌,诲人不倦,何由于我哉!