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):
<!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');}
</style>
</head>
<body>
<div id="pg"></div>
</body>
</html>
拖動浏覽器邊緣改變浏覽器窗口的寬度,可以看到在某些時候body和#pg在右側的交界處會有1px的空隙,這個問題存在於IE6/Chrome3/Safari4中。 以搜集IE BUG聞名的PIE(Position Is Everything)也有一篇《IE Background Positioning Bug》,不過其中的外層元素是固定寬度,對我們用處也不大。同事77總結了兩個方法:
方法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>
眼看就要圓滿了,轉念一想:“如果大圖寬度是奇數,會出現這個問題嗎?如果出現了,那怎麼搞捏?” 額…介個,介個…