BFC块级格式化上下文
1、BFC的概念
BFC的全称是 Block Formatting Contexts
Formatting Contexts是页面中的一块渲染区域,它拥有一套渲染规则,决定其子元素将如何定位,以及和其它元素的关系和相互作用。说白了就是一个决定如何渲染元素的容器。
2、BFC的渲染规则
那么BFC就是一个决定如何渲染元素的容器。我们要了解就是它的渲染规则。
- 1、内部的块级元素会在垂直方向,一个接一个地放置。
- 2、块级元素垂直方向的距离由margin决定。属于同一个BFC的两个相邻块级元素的margin会发生重叠。
- 3、对于从左往右的格式化,每个元素(块级元素与行内元素)的左边缘,与包含块的左边缘相接触,(对于从右往左的格式化则相反)。即使包含块中的元素存在浮动也是如此,除非其中元素再生成一个BFC。
- 4、BFC的区域不会与浮动元素重叠。
- 5、BFC是一个隔离的独立容器,容器里面的子元素和外面的元素互不影响。
- 6、计算BFC容器的高度时,浮动元素也参与计算。
3、BFC的触发条件
- 根元素
html float的值不是none。position的值不是static或者relative。display的值是inline-block、inline-flex、flex、flow-root、table-caption、table-cell。overflow的值不是visible。
4、BFC的应用
- 1、清除浮动
在文章最初,提到用clear:both来清除浮动,我们也可以根据BFC的渲染规则第6点(计算BFC容器的高度时,浮动元素也参与计算)来清除浮动,解决高度坍塌的问题。
- 2、解决上下margin边距问题
我们利用BFC渲染规则第2点(属于同一个BFC的两个相邻块级元素的margin会发生重叠),那么不属于同一个BFC的两个相邻块级元素的margin就不会发生重叠。那么我们在第二个div元素用一个div元素包裹起来,并用overflow:auto触发其BFC。再看一下效果是不是不重叠了。
弹性布局
浏览器渲染与重绘回流
浏览器渲染过程
- 解析HTML,生成DOM树
- 解析CSS,生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
- Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
- Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上。
何时触发回流和重绘
何时发生回流:
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
何时发生重绘(回流一定会触发重绘):
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。现代浏览器会对频繁的回流或重绘操作进行优化,浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。你访问以下属性或方法时,浏览器会立刻清空队列:
clientWidth、clientHeight、clientTop、clientLeftoffsetWidth、offsetHeight、offsetTop、offsetLeftscrollWidth、scrollHeight、scrollTop、scrollLeftwidth、heightgetComputedStyle()getBoundingClientRect()
以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,我们在修改样式的时候,**最好避免使用上面列出的属性,他们都会刷新渲染队列。**如果要使用它们,最好将值缓存起来。
如何避免触发回流和重绘
CSS:
- 避免使用table布局。
- 尽可能在DOM树的最末端改变class。
- 避免设置多层内联样式。
- 将动画效果应用到
position属性为absolute或fixed的元素上 - 避免使用CSS表达式(例如:
calc()) - CSS3硬件加速(GPU加速)
JavaScript:
- 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
- 避免频繁操作DOM,创建一个
documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中 - 也可以先为元素设置
display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘 - 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来
- 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流
src和href的区别
src和href都是用来引用外部的资源,它们的区别如下:
- src: 表示对资源的引用,它指向的内容会嵌入到当前标签所在的位置。src会将其指向的资源下载并应⽤到⽂档内,如请求js脚本。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执⾏完毕,所以⼀般js脚本会放在页面底部。
- href: 表示超文本引用,它指向一些网络资源,建立和当前元素或本文档的链接关系。当浏览器识别到它他指向的⽂件时,就会并⾏下载资源,不会停⽌对当前⽂档的处理。 常用在a、link等标签上。
script标签中defer和async的区别
如果没有defer或async属性,浏览器会立即加载并执行相应的脚本。它不会等待后续加载的文档元素,读取到就会开始加载和执行,这样就阻塞了后续文档的加载。 defer 和 async属性都是去异步加载外部的JS脚本文件,它们都不会阻塞页面的解析,其区别如下:
- 执行顺序: 多个带async属性的标签,不能保证加载的顺序;多个带defer属性的标签,按照加载顺序执行
对HTML语义化的理解
见名知意,用正确的标签做正确的事情。语义化的优点如下:
- 对机器友好,更适合搜索引擎的爬虫爬取有效信息,有利于SEO,还支持读屏软件。
- 对开发者友好,使用语义类标签增强了可读性,结构更加清晰,便于团队的开发与维护。
<header><nav><section><main><article><aside><footer>
iframe 有那些优点和缺点
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。
优点:
- 用来加载速度较慢的内容(如广告)
- 可以使脚本可以并行下载
- 可以实现跨子域通信
缺点:
- iframe 会阻塞主页面的 onload 事件
- 无法被一些搜索引擎索识别
- 会产生很多页面,不容易管理
label 的作用是什么?如何使用?
label标签来定义表单控件的关系:当用户选择label标签时,浏览器会自动将焦点转到和label标签相关的表单控件上。
<label for="mobile">Number:</label>
<input type="text" id="mobile"/>
Canvas和SVG的区别
(1)SVG: SVG可缩放矢量图形(Scalable Vector Graphics),在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。
其特点如下:
- 不依赖分辨率
- 支持事件处理器
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
- 不适合游戏应用
(2)Canvas: Canvas是画布,通过Javascript来绘制2D图形,是逐像素进行渲染的。其位置发生改变,就会重新进行绘制。
其特点如下:
- 依赖分辨率
- 不支持事件处理器
- 弱的文本渲染能力
- 能够以 .png 或 .jpg 格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
文档声明(Doctype)和<!Doctype html>有何作用? 严格模式与混杂模式如何区分?它们有何意义
文档声明的作用: 文档声明是为了告诉浏览器,当前HTML文档使用什么版本的HTML来写的,这样浏览器才能按照声明的版本来正确的解析。
严格模式与混杂模式的区分:
- 严格模式: 又称为标准模式,指浏览器按照
W3C标准解析代码; - 混杂模式: 又称怪异模式、兼容模式,是指浏览器用自己的方式解析代码。混杂模式通常模拟老式浏览器的行为,以防止老站点无法工作;
浏览器乱码的原因是什么?如何解决?
产生乱码的原因:
- 网页源代码是
gbk的编码,而内容中的中文字是utf-8编码的,这样浏览器打开即会出现html乱码,反之也会出现乱码; html网页编码是gbk,而程序从数据库中调出呈现是utf-8编码的内容也会造成编码乱码;- 浏览器不能自动检测网页编码,造成网页乱码。
解决办法:
- 使用软件编辑HTML网页内容;
- 如果网页设置编码是
gbk,而数据库储存数据编码格式是UTF-8,此时需要程序查询数据库数据显示数据前进程序转码; - 如果浏览器浏览时候出现网页乱码,在浏览器中找到转换编码的菜单进行转换。
渐进增强和优雅降级之间的区别
- (1)渐进增强(progressive enhancement)** :主要是针对低版本的浏览器进行页面重构,保证基本的功能情况下,再针对高级浏览器进行效果、交互等方面的改进和追加功能,以达到更好的用户体验。
- (2)优雅降级 graceful degradation**: 一开始就构建完整的功能,然后再针对低版本的浏览器进行兼容。
HTML5 drag API
- dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发。
- darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
- dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
- dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
- dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
- drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
- dragend:事件主体是被拖放元素,在整个拖放操作结束时触发。
vertical-align
vertical-align属性值:
- 线类:
baseline、top、middle、bottom - 文本类:
text-top、text-bottom - 上标下标类:
sub、super - 数值百分比类:20px、2em、20%等(对于基线往上或往下偏移)
温馨提示:负值相对于基线往下偏移,正值往上偏移,事实上
vertical-align:base-line等同于vertical-align:0。这个负值真的是 CSS 神器!
vertical-align生效前提:
- 内联元素
span、strong、em、img、button、input等 display值为inline、inline-block、inline-table或table-cell的元素- 需要注意浮动和绝对定位会让元素块状化,因此此元素绝对不会生效
CSS3的新特性
- word-wrap 文字换行
- text-overflow 超过指定容器的边界时如何显示
- text-decoration 文字渲染
- text-shadow文字阴影
- gradient渐变效果
- transition过渡效果 transition-duration:过渡的持续时间
- transform拉伸,压缩,旋转,偏移等变换
- animation动画
transition和animation的区别
Animation和transition大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是transition需要触发一个事件才能改变属性,而animation不需要触发任何事件的情况下才会随时间改变属性值,并且transition为2帧,从from .... to,而animation可以一帧一帧的。
移动端1px
一般来说,在PC端浏览器中,设备像素比(dpr)等于1,1个css像素就代表1个物理像素;但是在retina屏幕中,dpr普遍是2或3,1个css像素不再等于1个物理像素,因此比实际设计稿看起来粗不少。
解决方案:伪元素+scale
<style>
.box{
width: 100%;
height: 1px;
margin: 20px 0;
position: relative;
}
.box::after{
content: '';
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
transform: scaleY(0.5);
transform-origin: 0 0;
background: red;
}
</style>
<div class="box"></div>
CSS选择器及其优先级
- !important
- 内联样式style=""
- ID选择器#id
- 类选择器/属性选择器/伪类选择器.class.active[href=""]
- 元素选择器/关系选择器/伪元素选择器html+div>span::after
- 通配符选择器*
盒模型
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距margin,边框border,填充padding,和实际内容content。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
box-sizing: content-box(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。 box-sizing: border-box(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。
让元素消失
visibility:hidden、display:none、z-index=-1、opacity:0
- opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
- visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
- display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
- z-index=-1置于其他元素下面
关于index
绝对定位
- 一旦给元素加上
absolute或float就相当于给元素加上了display:block absolute元素覆盖正常文档流内元素(不用设z-index,自然覆盖)- 可以减少重绘和回流的开销(如
absolute+ top:-9999em,或absolute + visibility:hidden,将动画效果放到absolute元素中)
属性介绍
static,默认值。位置设置为static的元素,它始终会处于文档流给予的位置。inherit,规定应该从父元素继承 position 属性的值。但是任何的版本的 Internet Explorer (包括 IE8)都不支持属性值 “inherit”。fixed,生成绝对定位的元素。默认情况下,可定位于相对于浏览器窗口的指定坐标。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。不论窗口滚动与否,元素都会留在那个位置。但当祖先元素具有transform属性且不为none时,就会相对于祖先元素指定坐标,而不是浏览器窗口。absolute,生成绝对定位的元素,相对于距该元素最近的已定位的祖先元素进行定位。此元素的位置可通过 “left”、”top”、”right” 以及 “bottom” 属性来规定。relative,生成相对定位的元素,相对于该元素在文档中的初始位置进行定位。通过 “left”、”top”、”right” 以及 “bottom” 属性来设置此元素相对于自身位置的偏移。
浮动、绝对定位和固定定位会脱离文档流,相对定位不会脱离文档流,绝对定位相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body层。
如何实现居中
1.水平居中
- 若是行内元素,给其父元素设置
text-align:center即可实现行内元素水平居中 - 若是块级元素,该元素设置
margin:0 auto即可(元素需要定宽) - 若是块级元素,设置父元素为flex布局,子元素设置
margin:0 auto即可(子元素不需要定宽) - 使用flex 2012年版本布局,可以轻松的实现水平居中,子元素设置如下:
// flex容器
<div class="box">
// flex项目
<div class="box-center">
</div>
</div>
.box {
width: 200px;
height: 200px;
display: flex;
// 使内部的flex项目水平居中
justify-content: center;
background-color: pink;
}
/* .box-center {
width: 50%;
background-color: greenyellow;
} */
复制代码
- 使用绝对定位和CSS3新增的属性
transform(这个属性还和GPU硬件加速、固定定位相关)
.box {
width: 200px;
height: 200px;
position: relative;
background-color: pink;
}
.box-center {
position: absolute;
left:50%;
// width: 50%;
height: 100%;
// 通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数:
// translate(x,y) 定义 2D 转换。
// translateX(x) 定义转换,只是用 X 轴的值。
// translateY(y) 定义转换,只是用 Y 轴的值。
// left: 50% 先整体向父容器的左侧偏移50%,此时是不能居中的,因为元素本身有大小
// 接着使用transform使用百分比向左偏移本身的宽度的一半实现水平居中(这里的百分比以元素本身的宽高为基准)
transform:translate(-50%,0);
background-color: greenyellow;
}
复制代码
- 使用绝对定位和
margin-left(元素定宽)
.box {
width: 200px;
height: 200px;
position: relative;
background-color: pink;
}
.box-center {
position: absolute;
left:50%;
height: 100%;
// 类似于transform
// width: 50%;
// margin-left: -25%;
width: 100px;
margin-left: -50px;
background-color: greenyellow;
}
复制代码
2.垂直居中
- 若元素是单行文本, 则可设置
line-height等于父元素高度 - 若是块级元素,设置父元素为flex布局,子元素设置
margin: auto 0即可(子元素不需要定宽) - 若元素是行内块级元素,基本思想是使用
display: inline-block, vertical-align: middle和一个伪元素让内容块处于容器中央:
.box {
height: 100px;
}
.box::after, .box-center{
display:inline-block;
vertical-align:middle;
}
.box::after{
content:'';
height:100%;
}
复制代码
居中元素高度不定
- 可用
vertical-align属性(vertical-align只有在父层为 td 或者 th 时才会生效,,对于其他块级元素,例如 div、p 等,默认情况是不支持的),为了使用vertical-align,我们需要设置父元素display:table, 子元素display:table-cell;vertical-align:middle:
.box {
height: 100px;
display: table;
}
.box-center{
display: table-cell;
vertical-align:middle;
}
复制代码
- 可用 Flex 2012版, 这是CSS布局未来的趋势。Flexbox是CSS3新增属性,设计初衷是为了解决像垂直居中这样的常见布局问题:
.box {
height: 100px;
display: flex;
align-items: center;
}
复制代码
优点:内容块的宽高任意, 优雅的溢出. 可用于更复杂高级的布局技术中. 缺点:IE8/IE9不支持、需要浏览器厂商前缀、渲染上可能会有一些问题。
- 可用
transform,设置父元素相对定位:
.box {
height: 100px;
position: relative;
background-color: pink;
}
.box-center {
position: absolute;
top: 50%;
transform: translate(0, -50%);
background-color: greenyellow;
}
复制代码
缺点:IE8不支持, 属性需要追加浏览器厂商前缀,可能干扰其他 transform 效果,某些情形下会出现文本或元素边界渲染模糊的现象。
居中元素高度固定
- 设置父元素相对定位,子元素如下css样式:
.box {
position:relative;
height: 100px;
background-color: pink;
}
.box-center{
position:absolute;
top:50%;
// 注意不能使用百分比
// margin的百分比计算是相对于父容器的width来计算的,甚至包括margin-top和margin-bottom
height: 50px;
margin-top: -25px;
}
复制代码
- 设置父元素相对定位, 子元素如下css样式:
.box {
position:relative;
width: 200px;
height: 200px;
background-color: pink;
}
.box-center{
position:absolute;
top: 0;
bottom: 0;
margin: auto 0;
height: 100px;
background-color: greenyellow;
}
复制代码
3.水平垂直居中
- Flex布局(子元素是块级元素)
.box {
display: flex;
width: 100px;
height: 100px;
background-color: pink;
}
.box-center{
margin: auto;
background-color: greenyellow;
}
复制代码
- Flex布局
.box {
display: flex;
width: 100px;
height: 100px;
background-color: pink;
justify-content: center;
align-items: center;
}
.box-center{
background-color: greenyellow;
}
复制代码
- 绝对定位实现(定位元素定宽定高)
.box {
position: relative;
height: 100px;
width: 100px;
background-color: pink;
}
.box-center{
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
width: 50px;
height: 50px;
background-color: greenyellow;
}
伪类和伪元素的区别
伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树外的元素。因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
CSS3规范中的要求使用双冒号(::)表示伪元素,以此来区分伪元素和伪类,比如::before和::after等伪元素使用双冒号(::),:hover和:active等伪类使用单冒号(:)。除了一些低于IE8版本的浏览器外,大部分浏览器都支持伪元素的双冒号(::)表示方法。
作者:子弈
链接:juejin.cn/post/684490…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。