1.什么是 CSS hack?
由于不同厂商的浏览器,比如Internet Explorer,Safari,Mozilla Firefox,Chrome等,或者是同一厂商的浏览器的不同版本,如IE6和IE7,对CSS的解析认识不完全一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果。CSS hack在这种情况下针对不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果。
CSS hack
CSS Hack大致有3种表现形式,CSS属性前缀法、选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS Hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。
- 属性前缀法(即类内部Hack):
例如 IE6能识别下划线"—"和星号" * ",IE7能识别星号" * ",但不能识别下划线"—",IE6~IE10都认识"\9",但firefox前述三个都不能认识
2.选择器前缀法(即选择器Hack)
3.IE条件注释法(即HTML条件注释Hack):
针对所有IE(注:IE10+已经不再支持条件注释): ,针对IE6及以下版本:。这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效
2.谈一谈浏览器兼容的思路
-
要不要做
- 产品的角度(产品的受众、受众的浏览器比例、效果优先还是基本功能优先)
- 成本的角度 (有无必要做某件事)
-
做到什么程度
- 让哪些浏览器支持哪些效果
-
如何做
- 根据兼容需求选择技术框架/库(jquery)
- 根据兼容需求选择兼容工具(html5shiv.js、respond.js、css reset、normalize.css、Modernizr)
- postCSS
- 条件注释、CSS Hack、js 能力检测做一些修补
-
方法思路
-
渐进增强
(progressive enhancement): 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验 -
优雅降级
(graceful degradation): 一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
stackoverflow-渐进增强和优雅降级的区别
-
3.列举5种以上浏览器兼容的写法
- 属性前缀法(即类内部Hack):如
box{
color: red;
_color: blue; /*ie6*/
*color: pink; /*ie67*/
color: yellow\9; /*ie/edge 6-8*/
}
2.IE条件注释法(即HTML条件注释Hack):如
<!–-[if IE 7]>
<link rel="stylesheet" href="ie7.css" type="text/css" />
<![endif]–->
3.选择器前缀法(即选择器Hack)
*html *前缀只对IE6生效
*+html *+前缀只对IE7生效
@media screen\9{...}只对IE6/7生效
@media \0screen {body { background: red; }}只对IE8有效
@media \0screen\,screen\9{body { background: blue; }}只对IE6/7/8有效
@media screen\0 {body { background: green; }} 只对IE8/9/10有效
@media screen and (min-width:0\0) {body { background: gray; }} 只对IE9/10有效
@media screen and (-ms-high-contrast: active),
(-ms-high-contrast: none) {body { background: orange; }} 只对IE10有效等等
4.条件注释结合类选择器整体优化
<!DOCTYPE html>
<!--[if IEMobile 7 ]> <html dir="ltr" lang="en-US"class="no-js iem7"> <![endif]-->
<!--[if lt IE 7 ]> <html dir="ltr" lang="en-US" class="no-js ie6 oldie"> <![endif]-->
<!--[if IE 7 ]> <html dir="ltr" lang="en-US" class="no-js ie7 oldie"> <![endif]-->
<!--[if IE 8 ]> <html dir="ltr" lang="en-US" class="no-js ie8 oldie"> <![endif]-->
<!--[if (gte IE 9)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html dir="ltr" lang="en-US" class="no-js"><!--<![endif]-->
5.利用Modernizr工具
参考文章
运行的时候它会在html元素上添加一批CSS的class名称,这些class名称标记当前浏览器支持哪些特性和不支持哪些特性,支持的特性就直接显示该特性的名称作为一个class(例:canvas,websockets),不支持的特性显示的class是“no-特性名称”。以下是Chrome下生成的特征类型。
<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage
websqldatabase indexeddb hashchange history draganddrop websockets
rgba hsla multiplebgs backgroundsize borderimage borderradius
boxshadow textshadow opacity cssanimations csscolumns cssgradients
cssreflections csstransforms csstransforms3d csstransitions fontface
generatedcontent video audio localstorage sessionstorage webworkers
applicationcache svg inlinesvg smil svgclippaths">
下面这段代码是运行在IE9下的效果:
<html class=" js no-flexbox canvas canvastext no-webgl no-touch geolocation
postmessage no-websqldatabase no-indexeddb hashchange no-history
draganddrop no-websockets rgba hsla multiplebgs backgroundsize
no-borderimage borderradius boxshadow no-textshadow opacity
no-cssanimations no-csscolumns no-cssgradients no-cssreflections
csstransforms no-csstransforms3d no-csstransitions fontface
generatedcontent video audio localstorage sessionstorage
no-webworkers no-applicationcache svg inlinesvg smil svgclippaths">
你可以直接使用Modernizr在<html>元素里生成的class名称,在你的css文件里定义相应的属性以便支持当前浏览器。例如,下面的代码在支持shadow阴影的浏览器显示shadow,不支持的浏览器显示标准的边框:
.boxshadow #MyContainer {
border: none;
-webkit-box-shadow: #666 1px 1px 1px;
-moz-box-shadow: #666 1px 1px 1px;
}
.no-boxshadow #MyContainer {
border: 2px solid black;
}
4.以下工具/名词是做什么的
1.条件注释
条件注释 (conditional comment) 是于HTML源码中被IE有条件解释的语句。条件注释可被用来向IE提供及隐藏代码。例:
<!--[if !IE]><!-->
<script>alert(1);</script>
<!--<![endif]-->
<!--[if IE 8]>
<link href="ie8only.css" rel="stylesheet">
<![endif]-->
使用了条件注释的页面在 Windows Internet Explorer 9 中可正常工作,但在 Internet Explorer 10 中无法正常工作。
IE10不再支持条件注释
项目 | 范例 | 说明 |
---|---|---|
! | [if !IE] |
非IE |
lt | [if lt IE 5.5] |
小于IE 5.5 |
lte | [if lte IE 6] |
小于等于IE6 |
gt | [if gt IE 5] |
大于 IE5 |
gte | [if gte IE 7] |
大于等于IE7 |
l | [if (IE 6)l(IE 7)] |
IE6或者IE7 |
2.IE Hack
针对IE浏览器编写不同的CSS来兼容不同版本的IE,让IE能够正常渲染
3.js 能力检测
浏览器的能力检测目标不是检测特定的浏览器,而是检测浏览器的能力。这样,只需要检测浏览器是否支持特定的能力,就可以给出特定的解决方案。这一部分检测是解决浏览器兼容问题的主要检测。
4.html5shiv.js
用于解决IE9以下版本浏览器对HTML5新增标签不识别,并导致CSS不起作用的问题。所以我们在使用过程中,想要让低版本的浏览器,即IE9以下的浏览器支持,可以使用html5shiv.js。
原理:html5shiv主要解决HTML5提出的新的元素不被IE6-8识别,这些新元素不能作为父节点包裹子元素,并且不能应用CSS样式。让CSS 样式应用在未知元素上只需执行 document.createElement(elementName) 即可实现。html5shiv就是根据这个原理创建的。
使用方法:
tml5shiv的使用非常的简单,考虑到IE9是支持html5的,所以只需要在页面head中添加如下代码即可:
<!--[if lt IE 9]>
<script type="text/javascript" src="js/html5shiv.js"></script>
<![endif]-->
5.respond.js
Respond.js 是一个快速、轻量的 polyfill,用于为 IE6-8 以及其它不支持 CSS3媒体查询功能的浏览器提供媒体查询的 min-width 和 max-width 特性,实现响应式网页设计(Responsive Web Design)。
6.css reset
将浏览器的默认样式全部去掉,更准确说就是通过重新定义标签样式。“覆盖”浏览器的CSS默认属性。最简单的说法就是把浏览器提供的默认样式覆盖掉。核心作用是清零,而且过于暴力。
7.normalize.css
Normalize.css 是一个可以定制的CSS文件,它让不同的浏览器在渲染网页元素的时候形式更统一。其优势可以完全取代css reset.
它可以:
1.保护有用的浏览器默认样式而不是完全去掉它们。
2.标准化的样式,适用范围广的元素。
3.修复浏览器自身的bug并保证各浏览器的一致性。
4.优化CSS可用性:用一些小技巧。
5.使用详细的注释来解释代码
8.Modernizr
Modernizr 使你可以方便地为各种情况编写 JavaScript 和 CSS,无论浏览器是否支持这些特性。这是处理渐进增强的完美方案。
Modernizr 会在页面加载后立即检测特性;然后创建一个包含检测结果的 JavaScript 对象,同时在 html 元素加入方便你调整 CSS 的 class 名。
具体用法见文章上面案例。
9.postCSS
它可以被理解为一个平台,可以让一些插件在上面跑,它提供了一个解析器,可以将CSS解析成抽象语法树,通过PostCSS这个平台,我们能够开发一些插件,来处理CSS。热门插件如autoprefixer,它可以帮我们处理兼容问题,只需正常写CSS,autoprefixer可以帮我的自动生成兼容性代码
参考文章
5.一般在哪个网站查询属性兼容性?
- caniuse.com查CSS属性兼容
-
browserhacks查 Hack 的写法
另外 浏览器市场份额可以查看各个浏览器所占市场的份额。