兼容性处理
浏览器和服务器工作流程
在浏览器里面输入一个网址,接下来发生了什么?
-
浏览器输入地址,回车——浏览器首先验证URL地址,会有检索的功能。
-
在网络环境中找到里配置DNS服务器,将域名解析为ip地址并且放回浏览器
-
浏览器根据ip地址+端口号可以唯一定位一台服务器地址,发送请求
-
服务器接受浏览器发送过来的请求,给浏览器返回你需要的资源,请求如果没有指定资源,服务器会返回默认的资源。
-
浏览获取到当前的资源,解析,如果资源中涉及其他资源链接,会立即服务器发送请求其他资源。
-
浏览器解析服务器传递回来的各种资源,渲染出结果。
-
浏览器和服务器断开连接。
浏览器内核的了解
浏览器拿到的页面——可以是服务器返回过来的,还可以是本地磁盘里面
内核其实是浏览器最底层、最核心的代码。内核用来解析网页。
内核的作用
-
解析网页
-
html内容的解析
-
css解析
-
js解析
-
内核按照功能可分为:渲染引擎和js引擎。而内核里面有一个非常重要的概念:渲染引擎
内核里的渲染引擎主要包含以下几个部分
-
HTML解析器:会将html代码解析成一颗dom树,例如:html>body>div1>div2....
-
CSS解析器:会将css最终效果计算出来,并且内存cpu一起工作。
-
JavaScript引擎:允许js脚本的运行的环境
-
布局:主要是处理网页中模块定位、浮动、排列等等。
网页是如何解析出来的?
-
浏览器加载
网页代码
-
判断是否是网络资源,是就利用网络模块从网络上获取网页代码
-
如果是本地文件,则直接加载本地文件代码到浏览器内核中
-
-
经过HTML解析器,对代码进行解析
-
浏览器从代码的第一行开始解析,把不同类型的代码交给对应的解释器进行解析
-
css代码——css解析器
-
JavaScript代码——js解析器
-
html——html解析器
-
-
同时执行
-
-
将各个解析器的结果综合进行梳理(内部表示)
-
将标签和对应的css结合起来,每个标签都有自己的渲染对象,里面包含了该个标签样式等等。
-
-
布局和绘图
-
会把每个标签的样式、位置会绘制在页面上,如果需要图片、视频等内容,再利用对应模块进行处理,处理完之后直接显示在页面上
-
兼容性问题来源
浏览器的内核
浏览器内核就是各大浏览器最底层、最核心的代码,每个浏览器内核都会有一些差异,有些浏览器直接使用别人的内核。
目前主流的浏览器:Google 、firefox、opera、ie、edge、safira
国产浏览器:360、猎豹、QQ、搜狗等等
主流浏览器的内核
IE:ie10及以下版本 trident js引擎:ie9以下 Jscript ie9以上 chakra
Edge:内核EdgeHTML
safira:webkit/webkit2 js引擎:JScore
chrome:webkit、blink js引擎:v8引擎(市场上最强大的引擎)
firefox:Gecko内核 js引擎:jaegerMonkey
opera:blink
目前国内浏览器没有一款自己的内核,都是使用以上的各大厂商的内核。
包括360浏览推出双核浏览器,IE 的Trident和safira 的webkit一起集成。
兼容性问题
内核是浏览器最核心的代码,决定了网页是如何解析,页面是如何加载的,脚本如何执行。
不同浏览器的内核不同,每个浏览器对相同的页面有不同的解析方式,最终结果不一样,这种情况称为兼容性问题。
同一网页在不同浏览器下面运行的结果不一样,就叫兼容
常见的一些兼容
目前我们的开发过程中,我们兼容ie9以上,低版本的浏览器一般不考虑
创建一个提示页面,当检测到浏览器版本过低,提示用户换浏览器进行访问。
-
ul、p、h标签默认有marigin、padding,这些值在不同浏览器中不一样,产生兼容
-
将默认padding、margin手动去掉,在开发过程中写代码,或者设置值
-
借助第三方文件进行处理,第三方总结出来的一些网页样式初始化文件
-
Normalize.css:将可能出现的兼容样式进行统一样式的操作,达到各个浏览器显示效果都支持的作用。给一个统一标准
Normalize.css: Make browsers render all elements more consistently.
-
reset.css:专注于将样式全部覆盖掉,重置,以用户书写的样式为准
-
一般在开发中,都是基于normalize.css在加上自己的公共样式来开发,不推荐reset.css,因为reset.css太暴力,页面没有任何的样式。
-
-
-
各种属性和标签在使用过程中也有兼容
老板本的浏览器暂时不考虑,只考虑新版本的浏览,以及高版本浏览器的兼容问题。
兼容处理方案
对于CSS2.1里面的样式,只有在老版本的浏览器下面,比如IE67等等才会出现,更多兼容问题在于CSS3属性。
解决CSS3代码的兼容问题:
-
语义化标签出现兼容问题。在IE8下面无法渲染出来
<script> // IE8 下面无法支持header 我们创建一个header document.createElement("header"); </script> <style> header{ height: 100px; background-color: red; /* 本身就是块级元素,但是在IE8 这个版本下面 无法识别这个标签,给浏览器创建一个标签 */ display: block; } </style>
在开发中,这么多语义化标签,不可能每个语义化标签自己写脚本来创建。
谷歌已经设计了一个插件,专门用于处理语义化标签兼容性问题的。
<!-- 这是引入的插件,这个插件已经将脚本创建好 --> <!--[if lt IE 9]> <script src="https://cdn.bootcdn.net/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script> <![endif]-->
-
浮动元素如果没有设置宽度,在IE5 6这两个版本下面会出现默认占满一行的问题。
处理方案:给元素加width或者内容设置浮动。
<style> .box{ width: 400px; border: 1px solid red; overflow: hidden; } .left{ /* width: 100px; */ float: left; background-color: royalblue; } .right{ /* width: 100px; */ float: right; background-color: salmon; } h2{ float: left; margin: 0; height: 30px; } </style> <div class="box"> <div class="left"> <h2>logo</h2> </div> <div class="right"> <h2>logo</h2> </div> </div>
-
hack代码
专门针对特定版本浏览器设置的css代码
针对不同浏览器或者浏览器不同的版本写不同的代码,这个写css代码的过程就称为CSS hack
主要研究IE hack代码
CSS hack分类:
-
属性前缀法
属性前缀法就是在css中样式属性名前加上一些只有特定浏览器才能识别的hack前缀,以达到预期页面的展示效果
属性前缀只能单个属性设置,多个属性需要一个一个设置
IE浏览器各版本 CSS hack 对照表
hack 写法 实例 IE6 (S) IE6 (Q) IE7 (S) IE7 (Q) IE8 (S) IE8 (Q) IE9 (S) IE9 (Q) IE10 (S) IE10 (Q) * *color
青色 Y Y Y Y N Y N Y N Y + +color
绿色 Y Y Y Y N Y N Y N Y - -color
黄色 Y Y N N N N N N N N _ _color
蓝色 Y Y N Y N Y N Y N N # #color
紫色 Y Y Y Y N Y N Y N Y \0 color:red\0
红色 N N N N Y N Y N Y N \9\0 color:red\9\0
粉色 N N N N N N Y N Y N !important color:blue !important;
color:green;
棕色 N N Y N Y N Y N Y Y 案例:
.box{ width: 100px; height: 100px; background-color: red; /* 在属性前面加上*代表要适配IE7 这个版本 */ *background-color:orange; /* + 在IE6 IE7这两个版本里面可以生效 */ +border: 3px solid green; color:white; /* - 减号 在IE 6 里面可以生效 */ -color:green; /* \0 针对IE8 以上版本*/ color: red\0; /* 只针对 IE9 IE10 */ color: blue\9\0; /* important 在IE6中失效 */ }
-
选择器前缀法
选择器前缀法师针对一些页面表现不一致或者需要特殊对待的浏览器,在css选择器前加上一些只有某些浏览器可以识别的前缀hack代码。
语法 IE6 IE7 IE8 IE9 IE10 * html *
√ × × × × * +html*+
× √ × × × @media screen\9{...}
√ √ × × × @media \0screen{...}
× × √ × × @media \0screen\ , screen\9{...}
√ √ √ × × @media screen\0{...}
× × √ √ √ @media screen and (min-width:0\0){...}
× × × √ √ @media screen and (-ms-hirh-contrast : active) , (-ms-high-contrast:none){...}
× × × × √ -
条件注释法
通过注释语法来完成样式指定版本的导入
<!--[if IE]><![endif]-->
针对IE9及以下的版本<!--[if lte IE10]><![endif]-->
lt 小于 lte小于等于 gt大于 gte大于等于案例:
只在IE下生效 <!--[if IE]> 这段文字只在IE浏览器显示 <![endif]--> 只在IE6下生效 <!--[if IE 6]> 这段文字只在IE6浏览器显示 <![endif]--> 只在IE6以上版本生效 <!--[if gte IE 6]> 这段文字只在IE6以上(包括)版本IE浏览器显示 <![endif]--> 只在IE8上不生效 <!--[if ! IE 8]> 这段文字在非IE8浏览器显示 <![endif]--> 非IE浏览器生效 <!--[if !IE]> 这段文字只在非IE浏览器显示 <![endif]-->
hack代码在使用过程中可以解决兼容问题,但是给代码带来更多的混乱,慎用。
为了向下兼容,你可以设计一个CSS文件通过条件注释法引入进来,以后单独设计这个向下兼容的文件。
caniuse
一款前缀兼容性自查网址:Can I use... Support tables for HTML5, CSS3, etc
css兼容思想指导
网页开发过程中,对兼容性代码的工作指导:
优雅降级(推荐)
-
先不管兼容,直接以现在主流的浏览器为基础,实现最佳效果,然后再考虑低版本浏览器兼容的问题,再去书写低版本css hack,保证低版本浏览器统一可以有较好的效果
渐进增强
-
先把页面内容给搭建好(不考虑效果),在内容不受影响的情况下逐步添加页面样式,先针对所有浏览器写基础代码,在针对高版本浏览器添加样式,浏览器版本越高,页面效果越好。
面试题
-
谈一谈兼容思想(围绕优雅降级或渐进增强描述即可)
-
hack兼容有哪些方式? css hack是什么?
练习
京东三级菜单