css Sub-Pixel Bug?!

所属分类: 网页制作 / CSS 阅读数: 1846
收藏 0 赞 0 分享

jQuery之父John Resig写过一篇《Sub-Pixel Problems in CSS》,一个50px宽的div中有4个float的div,每个宽25%,然而各个浏览器对50*25%的理解有些纠结(demo):

随后Steven Wittens的《CSS Sub-pixel Background Misalignments》,测试了固定宽度的元素水平居中时父元素背景图片居中的差异,更让我们看到眼花(demo):

让人郁闷的是:不止IE,各浏览器的不同版本也有些许差异… 还好,现实工作中很少会碰到这种情形,遇到了也只是一个相对简单的情形,比较典型的应用场景是:某些QQ会员活动类的页面,背景一幅很宽大宏伟的1280px大图居中,中间区域980px居中,1024分辨率下980px外的部分能显示多少就显示多少,不出现横向滚动条,大于1024的分辨率则大图全部显示。 下面来看个简单的demo(为了方便发现及总结问题,外围大图宽400px(对应上面的1280px),中间200px掏空(对应上面的980px),中间图宽200px):

XML/HTML Code复制内容到剪贴板
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2.   
  3. <html xmlns="http://www.w3.org/1999/xhtml">  
  4. <head>  
  5. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
  6. <title>Sub-Pixel</title>  
  7. <style type="text/css">  
  8. body, div, p{margin:0;padding:0;}   
  9. body{text-align:center;}   
  10. button{margin:1em;padding:0 1em;}   
  11. #pg, body{background-position:center 0;background-repeat:no-repeat;}   
  12. body{background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_003.jpg');}   
  13. #pg{margin:0 auto;width:200px;height:200px;background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_004.jpg');}   
  14. </style>  
  15. </head>  
  16.   
  17. <body>  
  18.   
  19.     <div id="pg"></div>  
  20.   
  21. </body>  
  22.   
  23. </html>  

拖动浏览器边缘改变浏览器窗口的宽度,可以看到在某些时候body和#pg在右侧的交界处会有1px的空隙,这个问题存在于IE6/Chrome3/Safari4中。 以搜集IE BUG闻名的PIE(Position Is Everything)也有一篇《IE Background Positioning Bug》,不过其中的外层元素是固定宽度,对我们用处也不大。同事77总结了两个方法:

  1. 切图时body和#pg的图片不要分开,合在一张大图上,然后对body写背景图片居中,图片太大的话则切为多个相同宽度的小图,通过嵌套多个div来写,比如


复制代码
代码如下:

<div class="bg1">
<div class="bg2">
<div class="bg3">
<div id="pg"></div>
</div>
</div>
</div>

  1. body大图中间挖空区域多留几个像素,比如现在是200px,切图时为198px,两侧各多留1px

方法1在多数情况下很完美,不过也有某些个案不能使用这种方法;方法2对于body和#pg交界处比较淡化的图片来说非常适合,比如ISD Webteam博客的关于页面,不过有些时候交界处这1px会衔接不自然得非常明显,是我们这些追求完美的页面重构工程师所不能容忍的。 下面我们改变点结构来具体分析一下(注:此例为临时用例,下文中提到的body/#pg与之无关):

复制代码
代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Sub-Pixel</title>
<style type="text/css">
body, div, p{margin:0;padding:0;}
body{text-align:center;}
button{margin:1em;padding:0 1em;}
#pg, #hd{background-position:center 0;background-repeat:no-repeat;}
#pg{background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_003.jpg');}
#hd{margin:0 auto;width:200px;height:200px;background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_004.jpg');}
</style>
</head>
<body>
<div id="pg">
<div id="hd"></div>
</div>
<button id="sum">+1</button><button id="substruction">-1</button>
<p>#pg宽度为<strong id="current"></strong>px</p>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
var pg = $('#pg');
var current = $('#current');
function getWidth(){
current.text(pg.width());
}
getWidth();
$(window).resize(getWidth);
$('#sum').click(function(){
pg.width(pg.width() + 1);
getWidth();
});
$('#substruction').click(function(){
pg.width(pg.width() - 1);
getWidth();
});
})
</script>
</body>
</html>

通过连续的点击+1/-1按钮可以看出,当#pg宽度>#pg背景图片宽度(400px)且为奇数时,右侧才会出现这1px的空隙

当我们纠结于奇偶数的时候,神奇的
body{margin-left:1px}

出现了,详见《CSS IE one pixel image offset hack》。当设置了body的左外边距为1px时,不管奇偶数都不会出现这个1px的空隙了。不过,当body宽度小于背景大图宽度(这里是400px)且为偶数时,左侧交界处却出现了1px的空隙

看来只有用JS解决了,是当body宽度≥背景大图宽度(这里是400px)时,令body margin-left:1px,<时则去除margin-left:1px 全部代码如下:


复制代码
代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Sub-Pixel</title>
<style type="text/css">
body, div, p{margin:0;padding:0;}
body{text-align:center;}
button{margin:1em;padding:0 1em;}
#pg, body{background-position:center 0;background-repeat:no-repeat;}
body{background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_003.jpg');}
#pg{margin:0 auto;width:200px;height:200px;background-image:url('http://webteam.tencent.com/wp-content/uploads/2010/3/1749_004.jpg');}
.fix-bg{margin-left:1px;}
</style>
</head>
<body>
<div id="pg"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
var body = $('body');
function fixBg() {
(body.width() >= 400) ? body.addClass('fix-bg') : body.removeClass('fix-bg');
}
fixBg();
$(window).resize(fixBg);
})
</script>
</body>
</html>

后记
眼看就要圆满了,转念一想:“如果大图宽度是奇数,会出现这个问题吗?如果出现了,那怎么搞捏?” 额…介个,介个…

更多精彩内容其他人还在看

Opera中国的WEB标准课程

网页制作Webjx文章简介:在这篇文章里,我要向大家介绍我和其他很多人花费数月时间开发的一个课程——Web标准课程,该课程旨在向大家提供Web设计和开发的坚实基础,无论读者是谁,此教程完全免费、可访问,并且不需要预备知识。当然,我主要还
收藏 0 赞 0 分享

CSS样式表渐进增强的基本概念

网页制作Webjx文章简介:如果你挠着头想弄清楚优雅降级和渐进增强的区别,我告诉你,这是视角问题。优雅降级和渐进增强都考虑网站在各种设备的各种浏览器上如何良好运转。两者区别的关键在于它们各自关注的焦点,以及这种关注对工作流程的影响
收藏 0 赞 0 分享

简单介绍Web Developer插件制作网页

网页制作Webjx文章简介:Firefox浏览器是一个良好支持W3C标准的开放源代码的浏览器,拥有Linux/Windows/Mac版本。因为Firefox浏览器良好支持W3C标准,所以使用Firefox来调试网页是非常好的。 Firefox浏览器是
收藏 0 赞 0 分享

CSS布局带来的巨大影响:CSS display属性值

网页制作Webjx文章简介:网页元素应用上那些与表格相关的display属性值后,能够模仿出与表格相同的特性。我将会在该文中给大家演示这种方法给CSS布局带来的巨大影响。 应原书编辑要求,先在文章顶部给出链接:《Everything You
收藏 0 赞 0 分享

用div css模拟表格对角线

这只是探讨一种CSS模拟表格对角线的用法,实际在工作中可能觉得这样做有点小题大作,这不是本主题讨论的重点。如果对此深以为然的朋友,请一笑过之 首先声明: 这只是探讨一种CSS模拟表格对角线的
收藏 0 赞 0 分享

IE Firefox在css中的差别 (部分)

1、单位问题 问题:任何距离的数值ie可以不加单位,ff必须要求写单位(0除外) 解决:写全单位如padding:0px; 2、水平居中 问题:div里的内容,ie默认为center,而ff默认left 解决:mairgin:0px auto; 3、高度问题
收藏 0 赞 0 分享

不用js可以实现信息提示效果

[code] <style> body { font:verdena; font-size:14px; color:#000 } h1{ font:verdena; font-size:22px; color:#000 } h2{ font:verdena;
收藏 0 赞 0 分享

CSS解决未知高度的垂直水平居中自适应问题

今天有人问起,晚上试着写出来,供参考; 以下代码兼容主流浏览器IE6、IE7、Firefox、Opera。 从最简单的开始………… 一、如何让一个DIV水平居中? 这个简单不作过多说明! [code] <st
收藏 0 赞 0 分享

CSS cursor 属性 -- 鼠标指针样式效果

取值: [ [<uri> ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize |
收藏 0 赞 0 分享

css 简单区别ie6,ie7,firefox的写法

同一样式里可以这样 [code] margin:17px; FF +margin:17px; IE6 IE7 _margin:17px; IE6 [/code] 按这个顺序,刚好区分开三个浏览器
收藏 0 赞 0 分享
查看更多