十二月, 2009


19
十二 09

用display:inline-block做产品列表

由于D2的关系看到这篇文章《[纯技]产品列表到底应该怎么做?》,评论发不成功,又恰逢最近频繁遇到类似的项目,总结如下:

传统的实现方式是用float来实现,换一种思路用display:inline-block,比如这篇《Cross-Browser Inline-Block》(中文翻译)。在Firefox/Safari/Chrome/IE8中会遇到《说说display:inline-block》提到的第一个空隙问题,不过现在已经有了解决方法(详见《Firefox Bug: inline/inline-block的间隙》的评论并略作改进):

ul{letter-spacing:-.25em}
li{letter-spacing:normal;}

同时我也尝试了《Layout of repeating blocks》提到的word-spacing,不过仅Firefox/IE8有效,而在Chrome/Safari中无效

另外要注意的是-.25em是字体设置为Arial时的情况,为其他字体时会有些不同,下面仅列出了常用的几个

常用字体与letter-spacing的关系
宋体/Verdana -.5em
Arial -.25em
Tahoma -.333em

于是display:inline-block加上vertical-align就OK鸟

ul{letter-spacing:-.25em}
li{display:inline-block;#display:inline;#zoom:1;letter-spacing:normal;vertical-align:top;}

如果li中只有img,vertical-align:middle可以实现未知高度图片列表垂直居中,比如Picasa图片列表的效果(单个图片垂直居中请看怿飞的《图片垂直居中的使用技巧,不过个人认为这个通常只会出现在面试题中:P


6
十二 09

Object Oriented CSS UML

via Object Oriented CSS UML


6
十二 09

Sub-Pixel Bug?!

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,各浏览器的不同版本也有些许差异…

还好,现实工作中很少会碰到这种情形(某些像我这种一个月都做此类页面的人除外),遇到了也只是一个相对简单的情形,比较典型的应用场景是:某些活动类的页面,背景一幅很宽大宏伟的1280px大图居中,中间区域980px居中,1024分辨率下980px外的部分能显示多少就显示多少,不出现横向滚动条,大于1024的分辨率则大图全部显示。

下面来看个简单的demo(为了方便发现及总结问题,外围大图宽400px(对应上面的1280px),中间200px掏空(对应上面的980px),中间图宽200px):

<!DOCTYPE html>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Sub-Pixel</title>
<style>
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://docs.google.com/File?id=ddrrtxb_1769dm8c7hgm_b');}
#pg{margin:0 auto;width:200px;height:200px;background-image:url('http://docs.google.com/File?id=ddrrtxb_1770hjz8j6gb_b');}
</style>
</head>

<body>

    <div id="pg"></div>

</body>

</html>

不停缩小浏览器窗口的宽度,可以看到在某些时候body和#pg在右侧的交界处会有1px的空隙,这个问题存在于IE6/Chrome3/Safari4中。

大名鼎鼎的PIE也有一篇《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>
  2. body大图中间挖空区域多留几个像素,比如现在是200px,切图时为198px,两侧各多留1px

方法1在多数情况下很完美,不过也有某些个案不能使用这种方法;方法2对于body和#pg交界处比较淡化的图片来说非常适合,比如这个页面,不过有些时候交界处这1px会衔接不自然得非常明显,尤其是在我们这些比较龟毛追求完美的人眼中。

下面我们改变点结构来具体分析一下(注:此例为临时用例,下文中提到的body/#pg与之无关):

<!DOCTYPE html>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Sub-Pixel</title>
<style>
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://docs.google.com/File?id=ddrrtxb_1769dm8c7hgm_b');}
#hd{margin:0 auto;width:200px;height:200px;background-image:url('http://docs.google.com/File?id=ddrrtxb_1770hjz8j6gb_b');}
</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.3.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>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Sub-Pixel</title>
<style>
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://docs.google.com/File?id=ddrrtxb_1769dm8c7hgm_b');}
#pg{margin:0 auto;width:200px;height:200px;background-image:url('http://docs.google.com/File?id=ddrrtxb_1770hjz8j6gb_b');}
.fix-bg{margin-left:1px;}
</style>
</head>

<body>

    <div id="pg"></div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.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>

后记

眼看就要圆满了,心中突然冒充一个声音:“如果大图宽度是奇数,会出现这个问题吗?如果出现了,那怎么搞捏?”

额…介个,介个…我不玩了~


1
十二 09

The Life of Page 2.0


via The performance roadmap