天天看点

HTML和H5、css和css3

html

html文件的解析执行顺序?

参考1

参考2很重要

参考3

参考4

参考5

参考5

正常情况:

0、加载整体html文件

1、至上而下解析html

2、解析html建立dom树,遇到诸如

<script>

<link>

等标签时,就会去下载相应内容,并解

析、执行。如果是

<link>

标签,解析css构建CSSOM树

4、DOM和CSSOM结合生成render树

5、布局render树(Layout/reflow),负责各元素尺寸、位置的计算

6、绘制render树(paint),绘制页面像素信息

7.浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。

从下载角度讲

当HTML解析器遇到

<script>、<link>、<img>

标签,开始下载时,只存在一种阻塞情况,就是

<script>

标签会阻止

<img>

资源下载,其余

<script>、<link>

相互之间下载没有影响。

外部脚本与外部样式是并行加载(即在 下载 阶段,

<script>、<link>

互不影响,符合上述结论),但直到外部样式加载完毕,外部脚本才开始执行(即外部样式的下载,虽然不会影响外部脚本的下载,但会影响脚本的运行)

从解析角度讲

下载完成之后,就会运行解析相应的JS文件或者CSS文件,运行JS文件需要JS引擎线程,前面提到,JS引擎和GUI时互斥的,所以在 解析 的角度讲,JS引擎运行,会阻塞GUI,即阻止页面渲染。

css文件不会阻塞HTML解析,但是会阻塞渲染,导致css文件未下载完成之前已经解析好html也无法先显示出来。

总结

css下载和js下载可并行,但要等css加载完在执行js,执行js时html解析被阻塞。css不阻塞html的解析但会阻塞渲染

script有async defer

HTML和H5、css和css3
defer-IE独有
原生的defer思路:为

<script>

标签配置一个defer属性(这是个bool属性,配置之后表示为true),这表明我们知道脚本内没有类似document.write的方法,此时标签内的脚本就会并行的加载,并且在DOM解析完毕之后(即document.readyState变为inactive之后和DOMContentLoaded事件触发之前),将脚本执行。注意:不同脚本的执行顺序,是按照不同脚本相应的

<script>

在HTML中出现的顺序决定的。
async
async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。

defer 与相比普通 script,有两点区别:

载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成之后。

在加载多个JS脚本的时候,async是无顺序的加载,而defer是有顺序的加载。

三种方式适合什么时候用

growingwiththeweb 推荐优先级依次是 async defer normal。。

1、当你的js是个独立的模块且不依赖任何js,使用 async;

2、如果你的js依赖其他js或者被其他js 依赖,使用 defer;

3、如果你对js文件很小且被 async script 依赖,使用正常模式的script且放在async script 前面。

js css放置顺序

参考文献

共识:

JS尽量放在HTML底部。

CSS尽量放在HTML头部。

内联js放外链css之前

JS放在底部是为了防止阻塞DOM的解析,CSS放在头部是为了尽早完成CSSOM的构建,从而尽早paint页面。

假如我们有一段内联的、需要提前加载的、JS统计逻辑代码,很自然的,会把内联JS放在head里。那么是放在css前面,还是后面呢?

1、浏览器解析HTML的时候,会对整个HTML进行『preload scanner』,提前发起网络请求,下载外链资源,并不是解析到对应标签才会进行下载。而外链下载这个过程是由浏览器进程的网络线程完成的,不会阻塞当前渲染器进程的主线程逻辑。

2、JS会阻塞HTML的解析。内联JS在CSS前面的时候,执行内联JS可以和网络请求并行执行,执行完内联JS后会继续解析HTML,并且在CSS文件下载完成后,选择合适的时机进行渲染。而内联JS在CSS后面的时候,由于考虑到内联JS可能会修改CSSOM,所以主线程会暂停,直到CSS下载完成,生成CSSOM后,才会继续执行内联JS、解析HTML.

总结:内联js放外链css之前

在WebKit中,预加载扫描器指的是一个副解析器,当HTML主解析器被一个同步的script标签阻塞时,预加载扫描器就会启动.然后,它会马上找出接下来即将需要获取的资源(比如样式表,脚本,图片等资源)的URL,然后尽可能早的发起网络请求,而不用等到主解析器恢复运行,从而提高了整体的加载时间

除了HTML文件,网站通常还会使用到一些诸如图片,CSS样式以及JavaScript脚本等子资源。这些文件会从缓存或者网络上获取。主线程会按照在构建DOM树时遇到各个资源的循序一个接着一个地发起网络请求,可是为了提升效率,浏览器会同时运行“预加载扫描”(preload scanner)程序。如果在HTML文档里面存在诸如\或者\这样的标签,预加载扫描程序会在HTML解析器生成的token里面找到对应要获取的资源,并把这些要获取的资源告诉浏览器进程里面的网络线程。

浏览器的回流与重绘 (Reflow & Repaint)

浏览器使用流式布局模型 (Flow Based Layout)。

有了 RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。

回流

当 Render Tree 中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

页面首次渲染

浏览器窗口大小发生改变

元素尺寸或位置发生改变

元素内容变化(文字数量或图片大小等等)

元素字体大小变化

添加或者删除可见的 DOM 元素

激活 CSS 伪类(例如::hover)

查询某些属性或调用某些方法

重绘

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

如何避免回流

CSS:

避免使用 table 布局。

尽可能在 DOM 树的最末端改变 class。

避免设置多层内联样式。

将动画效果应用到 position 属性为 absolute 或 fixed 的元素上。

避免使用 CSS 表达式(例如:calc())。

Javascript:

避免频繁操作样式,最好一次性重写 style 属性,或者将样式列表定义为 class 并一次性更改 class 属性。

避免频繁操作 DOM,创建一个 documentFragment,在它上面应用所有 DOM 操作,最后再把它添加到文档中。

也可以先为元素设置 display: none,操作结束后再把它显示出来。因为在 display 属性为 none 的元素上进行的 DOM 操作不会引发回流和重绘。

避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

html5

html5新特性

webworker

WebWorker,JS的多线程?

前文中有提到JS引擎是单线程的,而且JS执行时间过长会阻塞页面,那么JS就真的对cpu密集型计算无能为力么?

所以,后来HTML5中支持了Web Worker。

MDN的官方解释是:

Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面

一个worker是使用一个构造函数创建的一个对象(e.g. Worker()) 运行一个命名的JavaScript文件

这个文件包含将在工作线程中运行的代码; workers 运行在另一个全局上下文中,不同于当前的window

因此,使用 window快捷方式获取当前全局的范围 (而不是self) 在一个 Worker 内将返回错误

这样理解下:

创建Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,完全受主线程控制,而且不能操作DOM)

JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)

所以,如果有非常耗时的工作,请单独开一个Worker线程,这样里面不管如何翻天覆地都不会影响JS引擎主线程,

只待计算出结果后,将结果通信给主线程即可,perfect!

而且注意下,JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。

其它,关于Worker的详解就不是本文的范畴了,因此不再赘述。

WebWorker与SharedWorker

既然都到了这里,就再提一下SharedWorker(避免后续将这两个概念搞混)

WebWorker只属于某个页面,不会和其他页面的Render进程(浏览器内核进程)共享

所以Chrome在Render进程中(每一个Tab页就是一个render进程)创建一个新的线程来运行Worker中的JavaScript程序。

SharedWorker是浏览器所有页面共享的,不能采用与Worker同样的方式实现,因为它不隶属于某个Render进程,可以为多个Render进程共享使用

所以Chrome浏览器为SharedWorker单独创建一个进程来运行JavaScript程序,在浏览器中每个相同的JavaScript只存在一个SharedWorker进程,不管它被创建多少次。

看到这里,应该就很容易明白了,本质上就是进程和线程的区别。SharedWorker由独立的进程管理,WebWorker只是属于render进程下的一个线程

语义化

语义化优点:

易于用户阅读,样式丢失的时候能让页面呈现清晰的结构。

有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权重。

方便其他设备解析,如盲人阅读器根据语义渲染网页

有利于开发和维护,语义化更具可读性,代码更好维护,与CSS3关系更和谐。

css

css选择器的优先级?

1、位于

<head/>

标签里的

<style/>

中所定义的CSS拥有最高级的优先权。

2、第二级的优先属性由位于

<style/>

标签中的

@import

引入样式表所定义。

3、第三级的优先属性由

<link/>

标签所引入的样式表定义。

4、第四级的优先属性由

<link/>

标签所引入的样式表内的

@import

导入样式表定义。

5、第五级优先的样式有用户设定。

最低级的优先权由浏览器默认。

6、 属性选择器的权重问题:

// !important ---------> 无穷

// 行间样式-------------> 1000

// id------------------> 100

// class|属性|伪类------> 10

// 标签|伪元素 ---------> 1

// 通配符---------------> 0

权重的进制是256

说一下position都有哪些,并详细的说说他们之间的区别

position: 
 1、absolute  绝对定位 脱离原来位置进行定位 相对于自身最近的父级进行定位
 2、relative	相对定位  保留原来位置进行定位 参照元素自身 用于设置参照物
 3、static	默认属性 元素默认定位是static
 4、fixed		可视窗口进行定位 网页上应用的广告栏
 5、position:sticky是一个新的css3属性,它的表现类似position:relative和position:fixed的合体,
            在目标区域在屏幕中可见时,它的行为就像position:relative;
            而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。
            淘宝的侧边栏
  6、inherit:继承父级的定位
           

如果position设置成absolute属性该元素的display属性会变成什么

position:absolute和float会隐式的改变display类型,不论之前是什么类型的元素(display:none除外),
	只要设置了position:absolute或float,都会让元素以 **display:inline-block** 的方式显示,可以设置长宽,默认宽度并不占满父元素,就算是显示的设置display:inline或display:block,仍然无效。
           

块级元素行级元素的区别

"block" 块级元素  :占满整行 可以改变宽高  
                    ```<div/><from/><address/><hr/><h1/>```
   "inline" 行级元素内联元素 :不占满整行 不可以改变宽高
                    ```<a/><br/><em/><span/>```
   "inline-block" 行级块元素:可以改变宽高 也不独占整行
                    ```<img/> <input />  ```
           

可替换元素

可替换元素(replaced element)的展现效果不是由 CSS 来控制的。这些元素是一种外部对象,它们外观的渲染,是独立于 CSS 的。

简单来说,它们的内容不受当前文档的样式的影响。CSS 可以影响可替换元素的位置,但不会影响到可替换元素自身的内容。

典型的可替换元素有 ,还有一些元素仅在特定情况下被作为可替换元素处理,比如

说说怎么去除浮动

(1)为什么要清除浮动?
		浮动起来的元素不会脱离文字流 但是会脱离文档流
		不脱离文字流:display属性是inline和inline-block 的元素还是可以看见他的  文字本身是inline属性
		脱离文档流的意思是 正常元素看不见他了  类似absolute属性
		内部改元素的样式display:inline-block;
	(2)不清除浮动的效果:
		border不能被撑开 背景不能显示  margin设置值不能正确显示
    (3)清除浮动的方法:
        1.底下添加新的元素 ,应用 clear:both;
        2.父级属性:overflow:hidden;
		3.可以在外层套一个标签</p> 设置属性 clear:both;
		4.添加一个after
			xxx:after{
				content: '';
				clear:both;
				display: block; 
			}
            IE67触发haslayout :wrapper{ zoom:1}
		  "原理":他就是在最后加了一个伪元素  这个元素不是浮动的,他是抗浮动的,所以能看到浮动元素来定位自己的位置
			然后父级元素能看到这个伪元素 所以他只是按照这个伪元素的位置来改变自己的宽高 
		"clear解释":该属性的值指出了不允许有浮动对象的边情况,又对象左边不允许有浮动、右边不允许有浮动、不允许有浮动对象

    (4)为什么给父级元素设置overflow属性会去除浮动,具体说说内部机制
		触发BFC,计算时会计算浮动元素
           

BFC的通俗理解:

Block Formatting Context(块级格式化上下文)
    如果一个元素符合了成为BFC的条件,该元素成为一个隔离了的独立容器,元素内部元素会垂直的沿着其父元素的边框排列,和外部元素互不影响 。比如浮动元素触发BFC,浮动元素内部的子元素主要受到该浮动元素的影响,而两个浮动元素之间是互不影响的。
    BFC的排列:
    在BFC中,盒子从顶端开始垂直地 一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的 垂直外边距会产生折叠。在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。
   BFC的特性
        边缘不和浮动元素重叠
        不存在collapsing margins问题

    第一个特性特别有用,因为元素触发了BFC的话,就不会被float元素覆盖,当子元素全部浮动的时候也能够正确地包含了
    第二个margin不会叠加的特性,可以理解为两个处于普通流的盒子,会有margin叠加的问题,是因为他们属于相同的BFC,当他自身创建了一个新的BFC时,这个问题就不存在了
    BFC的常见应用
    1.通过边缘不和浮动元素重叠的特性,实现两栏结构。 
    2.清除元素内部浮动
    3.解决合并外边距的问题
           

说说触发bfc的几种方式

   1.设置除 float:none 以外的属性值(如:left | right)就会触发BFC
  2.设置除 overflow: visible 以外的属性值(如: hidden | auto | scroll)就会触发BFC
  3.设置 display属性值为: inline-block | flex | inline-flex | table-cell | table-caption 就会触发BFC
  4.设置 position 属性值为:absolute | fixed 就会触发BFC
  5.使用 fieldset 元素(可以给表单元素设置环绕边框的html元素)也会触发BFC
  html根元素触发BFC
           

说说常见的将元素垂直水平居中的方法

1.父级定宽高 知道自身宽高
            {
            	position:absolute;
                left:50%;
                top:50%;
                margin-left:-元素宽一半的大小;
                margin-top:-元素高一半的大小;
            }
      
		2. 父级定宽高 知道自身宽高
		{
	    position: absolute;
	    top: calc(50% - 50px);
	    left: calc(50% - 150px);
	    width: 300px;
	    height: 100px;
	    border: 1px solid #000;
	}
	3.父级定宽高 不知道自身宽高  
       {                   
			position:absolute;
			left:0;
			right:0;
			top:0;
			bottom:0;
			margin:auto; 或 margin:0
		}
        2.父级定宽高 不知道自身宽高  
            {
            position:absolute;
            transform:translateX(-50%)translateY (-50%);
            }
        3.flex 布局 :在父级上
        	{
				position:absolute;
				display:flex;
				justify-content:center;//水平
				aligin-items:center;//竖直
			}
        4.行内元素水平居中 : text-align: center;
        行内元素垂直居中 :height = line-height
           

盒模型

盒模型

首先我们要区分盒模型和盒子:盒模型有margin部分,而盒子不算margin部分。

1. w3c的标准盒模型,一个盒子的大小是width+padding+border,width是内容区,即width不包含padding和border。

  而IE6混杂模式的盒模型,一个盒子的大小是width,即width包含padding和border。

 2. css3中就有一个属性可以设置我们使用哪一种盒模型。

       box-sizing: border-box  IE6混杂模式的盒模型
                   content-box; 标准模式的盒模型
           

弹性盒子

这是我认为css3中最重要的一部分。

        我们在移动端开发的时候,由于手机的大小都各不相同,所以我们的元素不能定宽,要用弹性盒子来按照百分比分配元素的宽度。

        我们给父级的display设置成flex之后,就让父元素变成了一个弹性盒子,里面的子元素都可以使用flex属性了。

        这个时候,所有的元素会自动变成一行,因为加上display:flex之后还会默认加上一个flex-wrap:nowrap,即不换行,
              这个时候如果子元素的总宽度大于父元素的宽度,就会压缩子元素,让它们可以在父级容器中排成一行。如果改成wrap值,
              那么超过容器的宽度之后就会换行了。

        //flex属性是一个复合属性,它包括flex-grow、flex-shrink、flex-basis

              flex-grow  按比例分配剩余空间。
              flex-shrink 设置收缩比例,多出盒子的部分按照比例的大小去掉相应的大小,比例越大,削减的越多,
                          具体的削减数值有一个复杂的计算公式:
              flex-basis 伸缩基准值。该属性设置元素的宽度,如果同时出现了width和该属性,那么会覆盖掉width属性的值。

        justify-content:center

        align-items:center

        这两个属性同时在父级中设置的时候,会让子元素在父级中水平垂直居中,其中justify-content是设置水平方向,align-item是设置垂直方向。 
           

两栏布局类比三栏布局

两栏布局

1.columns width:宽度列
            count:列数
  2.浮动  左定宽高 浮动 右边设置margin-left
        .left{
                width:100px;
                height:100px;
                background-color: red;
                float:left;
            }
            .right{
                height:100px;
                background-color:green;
                margin-left: 100px;
            }
  3.定位 :左边定宽高 设置定位position absolute left 0 ;
            .left{
                width:100px;
                height:100px;
                background-color: red;
                position:absolute;
                left:0;
            }
            .right{
                height:100px;
                background-color:green;			
                right:0;
            }
 4.flex 布局   外容器设置display:block;
            .wrapper{
                display:flex;
            }
            .left{
                width:100px;
                height:100px;
                background-color: red;

            }
        .right{
            height:100px;
        	flex-grow:1;
            background-color:green;	
        }
           

三列布局

有两种实现方式 1.左右两侧的div先用absolute定位,再给中间的div加margin-left和margin-right(值分别是两个div的宽度)

2.用flaot替换上面的absolute就行

.left {
        float: left;
        width: 100px;
        height: 100px;
        background-color: orange;
    }
    .right {
        float: right;
        width: 100px;
        height: 100px;
        background-color: red;
    }
    .mid {
        height: 100px;
        margin-left: 100px;
        margin-right: 100px;
        background-color: blue;
    }
           

要注意的是,div.mid记得写在后面,如果写在最前面的话,因为div是block块级元素会独占一行,

这样就会把右侧的div给挤到下一行了。当然我们给.left和.right都加上top:0px;之后,这个问题也就不用考虑了。

3.flex布局

.wrapper{ display:flex}

.left.right{定宽高 背景色}

.middle{flex-grow:1;定高}

middle必须放在中间布局

4.columns属性

原生JS的ofsetwidth求得的宽度包括什么

原生JS的offsetwidth求得的宽度包括什么: content padding border

css(‘width’)求得的宽度包括什么: content padding border

jq的innerWidth求得的宽度包括什么: content padding

line-height 110%和1.1啥区别

一个是相对于父级fontsize,一个是相对自己fontsize的

margin合并和margin塌陷

margin合并问题的现象:并列结构的话 上下两个margin 分别有一个margin-bottom 下边这个元素有一个margintop 这样的画会产生一个重叠取最大的一个margin的值作为他们之间的距离
解决合并外边距的问题:
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是父子关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有线盒(其实就是非空内容),没有间隙(clearance,设置clear以闭合相关方向的浮动 ),没有padding和border将他们分隔开就会发生margin重叠。解决方式就是使元素不属于同一个BFC。
CSS及浏览器的设计者们希望我们在布局时,如果遇到上下两个并排内容块的安排,最好只设置其中每个块上或下margin的一处即可。
解决方式
解决父子DIV中顶部margin cllapse的问题,需要给父div设置:
 1、边框,当然可以设置边框为透明;
 2、为父DIV添加padding,或者至少添加padding-top;
 3.还可以通过overflow来解决,给父DIV写入: over-flow:hidden;**触发BFC,使之不属于同一个BFC**
           

说一下

<link/>

@import

的区别

本质上,这两种方式都是为了加载CSS文件,但还是存在着细微的差别。 
           

[email protected] 机制不同于link,link是加载页面前css加载完毕,@import 是先读取文件再加载

[email protected]是css2.0里的 ie5以上不支持

3.用js控制dom时改变样式,只能用link,@import不是dom能控制的

4.最后一个很有意思,@import url有最大次数的限制,IE6最多引入31次,firefox并没有发现

@import的优点: 多个样式表导入一个样式表中,页面只需要引入一个即可

关于伪元素你了解多少,请说出五个常用的伪元素,那么伪类呢?也请说出五个常用的伪类

"区别":伪元素是相当于添加一个元素 伪类相当于是在元素上添加样式 这俩**都不实际存于在dom树中**
    用来格式化文档流之外的东西
    伪类则是像真正的类一样发挥着类的作用,没有数量上的限制,只要不是相互排斥的伪类,也可以同时使用在相同的元素上
		伪元素:::first-line                     
				:first-letter
				:last-letter 
				:before 
				:after

		伪类:	  :first-child 
				:link: 
				:visitive 
				:hover 
				:active 
				:focus 
				:lang 
           

HTML5

新增属性scoped

<style scoped>
</style>
           
scoped 属性是一个布尔属性。
如果使用该属性,则样式仅仅应用到 style 元素的父元素及其子元素。