HTML+CSS

270 阅读18分钟

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-blockinline-flexflex flow-roottable-captiontable-cell
  • overflow的值不是visible

4、BFC的应用

  • 1、清除浮动

在文章最初,提到用clear:both来清除浮动,我们也可以根据BFC的渲染规则第6点(计算BFC容器的高度时,浮动元素也参与计算)来清除浮动,解决高度坍塌的问题。

  • 2、解决上下margin边距问题

我们利用BFC渲染规则第2点(属于同一个BFC的两个相邻块级元素的margin会发生重叠),那么不属于同一个BFC的两个相邻块级元素的margin就不会发生重叠。那么我们在第二个div元素用一个div元素包裹起来,并用overflow:auto触发其BFC。再看一下效果是不是不重叠了。

弹性布局

blog.csdn.net/itwangyang5…

浏览器渲染与重绘回流

浏览器渲染过程

  • 解析HTML,生成DOM树
  • 解析CSS,生成CSSOM树
  • 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  • Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将像素发送给GPU,展示在页面上。

何时触发回流和重绘

何时发生回流:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

何时发生重绘(回流一定会触发重绘):

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。现代浏览器会对频繁的回流或重绘操作进行优化,浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。你访问以下属性或方法时,浏览器会立刻清空队列:

  • clientWidthclientHeightclientTopclientLeft
  • offsetWidthoffsetHeightoffsetTopoffsetLeft
  • scrollWidthscrollHeightscrollTopscrollLeft
  • widthheight
  • getComputedStyle()
  • getBoundingClientRect()

以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,我们在修改样式的时候,**最好避免使用上面列出的属性,他们都会刷新渲染队列。**如果要使用它们,最好将值缓存起来。

如何避免触发回流和重绘

CSS:

  • 避免使用table布局。
  • 尽可能在DOM树的最末端改变class。
  • 避免设置多层内联样式。
  • 将动画效果应用到position属性为absolutefixed的元素上
  • 避免使用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属性值:

  • 线类:baselinetopmiddlebottom
  • 文本类:text-toptext-bottom
  • 上标下标类:subsuper
  • 数值百分比类:20px、2em、20%等(对于基线往上或往下偏移)

温馨提示:负值相对于基线往下偏移,正值往上偏移,事实上vertical-align:base-line等同于vertical-align:0。这个负值真的是 CSS 神器!

vertical-align生效前提:

  • 内联元素spanstrongemimgbuttoninput
  • display值为inlineinline-blockinline-tabletable-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-Model.jpg

box-sizing: content-box(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。 box-sizing: border-box(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。

让元素消失

visibility:hidden、display:none、z-index=-1、opacity:0

  1. opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
  2. visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
  3. display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
  4. z-index=-1置于其他元素下面

关于index

image.png

绝对定位

  • 一旦给元素加上absolutefloat就相当于给元素加上了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-topmargin-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;
}

伪类和伪元素的区别

image.png

伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树外的元素。因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。

CSS3规范中的要求使用双冒号(::)表示伪元素,以此来区分伪元素和伪类,比如::before和::after等伪元素使用双冒号(::),:hover和:active等伪类使用单冒号(:)。除了一些低于IE8版本的浏览器外,大部分浏览器都支持伪元素的双冒号(::)表示方法。


作者:子弈
链接:juejin.cn/post/684490… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。