什么是CSS hack?
由于不同厂商的浏览器或某浏览器的不同版本(如IE6-IE11,Firefox,Safari,Opera,Chrome等),对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。
因此,为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack。
CSS hack大致有3种表现形式,CSS属性前缀法、选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。
属性前缀法:
1 | .container{ |
选择器前缀法(即选择器hack):
针对一些页面不一致或者需要特殊对待的浏览器,在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行hack。1
2
3
4*html{}/*只对IE6生效*/
*+html{}/*只对IE7生效*/
@media screen\9{...} //IE6-7生效
IE条件注释法(即HTML条件注释hack):
(注:IE10+已经不再支持条件注释)这类hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。
如何应对浏览器兼容?
把浏览器分两类,一类是历史遗留浏览器,一类是现代浏览器。
按照W3C标准流程和规范,优先为高端浏览器设计,同时考虑低端浏览器的退化方案。
策略:
- 渐进增强(progressive enhancement):
针对低版本浏览器进行构建页面,保证最基本的功能,然后在针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。 - 优雅降级(graceful degradation):
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。
reset.css和normalize.css
reset.css是通过重新定义标签样式,把浏览器的默认样式覆盖掉,以便保持个浏览器渲染的一致性。相对暴力
normalize.css是reset.css的替代方案,保留有用的浏览器默认样式,重置掉该重置的样式,同时进行一些bug的修复。相对平和
IE8不支持HTML5也不支持CSS3 Media
需要加载两个JS文件,来保证我们的代码实现兼容效果:1
2
3
4<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
IE6不支持透明图片
解法方案:
通过JS代码让IE6支持
- 下载JS支持文件:下载地址
- 将下面的代码放到html文件中的
<head></head>
之间,注意修改成正确的路径!1
2
3
4<!--[if IE 6]>
<script type="text/javascript" src="js/DD_belatedPNG_0.0.8a-min.js"></script>
<script type="text/javascript" src="js/ie6Fixpng.js"></script>
<![endif]-->
背景透明度问题
IE8以下浏览器都不支持 opacity透明度设置。
可以使用IE自带的“滤镜”来实现,使用filter:alpha(opacity=)来设置透明度。
案例:设置div元素的背景。1
2
3
4
5
6
7
8<style type="text/css">
#oDiv{ height:100%; width:100%;
background:#000;
opacity:0.5; //兼容Chrome,firefox,Safari;
filter:alpha(opacity=50); //IE8以下透明度兼容
position:absolute; left:0; top:0;
}
</style>
IE浏览器下图片边框问题
IE浏览器下,图片会自动加上黑色的边框,看起来不美观。
此问题不是图片自身问题(如格式问题,png24/png32/jpg/gif)
解决方法:
在相关CSS样式文件中为图片设置边框即可:img{border:0;}
ie6行类标签浮动父级宽度的50%的bug
问题描述:
页面布局需要左右两块各占窗口的50%,把外层容器的宽度设为100%,左侧div宽50%左浮动,右侧同样50%有浮动。
调试时,其他浏览器都好用,只在ie6与ie7中出现问题,貌似多出一像素的宽,导致右侧被挤到下面去。
解决方案
将宽度设为49.9%即可。
IE6/7子元素超过父元素时触发的bug
问题描述:
IE6/7子元素不能超出父元素,否则会错乱;
示例:1
2
3
4
5
6
7
8
9
10.products_title{
height: 34px;
border-bottom: 2px solid #ccc;
}
.products_title h3{
width: 180px;
border-bottom: 2px solid #096DBA;
height: 34px;
line-height: 34px;
text-indent: 9px;
这里效果是需要两个底边框重合,但在IE6/7下会错乱。
修改如下,h3中添加代码:margin-bottom: -2px;position: relative;
这里效果是需要两个底边框重合,所以要设置h3的margin-bottom=-2px,
这样两个底边框重合,但是父元素的底边框盖住了子元素h3的,
所以要设置子元素h3的相对定位relative,来提升h3的层级。*/
ie6/7中span(或a等行内元素)右浮动折行问题
W3C标准:
如果一个元素浮动前是一个行内元素,则该元素浮动后,顶部应与其之前所在的行框顶部对齐。
但在IE6 IE7 IE8(Q) 下,若浮动元素之前存在兄弟行内非浮动元素,IE 会将浮动元素所在的“当前行”认为是其前边的兄弟行内元素所产生的匿名框的底边,导致该浮动元素折行,
代码示例:1
2
3
4
5
6<div class="shopping_item">
<h3 class="shopping_tit">送货清单<a href="#" class="backCar">返回购物车修改</a></h3>
<div class="shopping_cont ">
<div class="cart_inner">
<div class="cart_head clearfix">
<div class="cart_item t_name">商品名称</div>
CSS部分:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22.shopping_item{
border: 1px solid #ccc;
margin-bottom: 20px;
}
.shopping_tit{
height: 31px;
background: url(../images/icon/check_bg.png) left top repeat-x;
font-size: 16px;
line-height: 31px;
color: #444;
text-indent: 12px;
font-weight: normal;
}
.backCar{
float: right;
font-family: "宋体";
font-size: 12px;
margin-right: 33px;
color: #3377ff;
*margin-top: -31px; //此为IE6/兼容解决方案。
}
解法方法:
- 使用绝对定位模拟右浮动
使用绝对定位(position:absolute)模拟右浮动(float:right)。 为了避免 IE6 IE7 的这个 BUG,可以不使用右浮动,而是用绝对定位及右偏移(right:XXXpx),如为右浮动元素设置 ‘position:absolute’ 及 ‘right:3px’ 替代 ‘float:right’,但这样做的代价是必须为父容器 DIV 元素设置 ‘postion:relative’,这么做仍然会破坏原文档结构。所以我们并不推荐此方法。 - 使用 IE hack 专门在IE6 IE7 中设置负的上外边距
使用 IE hack 专门在IE6 IE7 中设置负的上外边距(margin-top:-XXXpx)。 既然此 Bug 为IE6 IE7 专有,则只需要在 IE6 IE7 下为右浮动元素设置一个负的上外边距即可,其他浏览器保持原样式。所以可以考虑使用只有 IE6 IE7支持的 hack 方式:在 CSS 特性前加星号 ‘‘。
如 margin:-23px 5px 0 0,这样既可消除 IE6 IE7 中的 Bug,但是这么做是利用了浏览器的 Bug,并没有消除 Bug。 - 将右浮动的 SPAN 元素调整到所有非浮动 SPAN 元素之前。
通过上面总结的 Bug 触发条件,我们可以考虑直接调整父容器中 SPAN 子元素的位置来回避 IE6 IE7 中此 Bug,即将右浮动的 SPAN 元素调整到所有非浮动 SPAN 元素之前。