日志分类“HTML&CSS”的日志存档

最近碰到的前端问题集合No.1

星期一, 十二月 29th, 2008

前端TMD总是会有出不完的问题,还总是在同一个问题上栽跟头,即便一次次重复记录在处理问题的时候依然避免不了思考片刻,譬如著名的图片垂直居中的问题。因此,好记性不如烂键盘,今后出现问题的时候会有迹可循总比再上Google搜索来得强吧。最近就又碰到了一些问题,在新博客中做些记录以备后患:

问题一、这是在做这个博客的时候发现的一个问题,万能的IE再次显示出了它的无能,虽然不是什么难题不过却总令人不爽。在一个正常流的文档当中有并列三个div分别是divTop、divMiddle、divBottom,如果divMiddle为绝对定位的元素那么对接下去的divBottom如果使用负的margin-top定位会失效[例子]。在制作例子的时候怎么也不能重现问题,经过一步步排查才发现这个问题只有在divBottom设置了高度的时候才会出现,因此解决方法很简单,只要去掉divBottom的高度设定即可,不过往往很多时候我们不能那么做。我想大概是文档流本身的问题,根据html文档流的原理设为绝对定位的元素会脱离文档流而让紧随其后的元素填充自身的位置,理论上应该不会造成定位失效所以像Firefox这类标准浏览器便完全没有上述问题,我只能认为是IE本身的bug了。而为了应对这个问题,我不得不调整文档流把divMiddle放在divBottom后面,当然这样做的最大后果便是html的语义被破坏了,还好这在我的应用当中不是大问题。——根据二八原则,至此这个问题应该告一段落了,不知道是不是我理解上有错误,有高手路过的时候记得指教

问题二、这个问题也是伟大的IE给我们造成的困扰,不过这个问题并不发生在所有的IE浏览器上,只有在7.0版本以下的IE浏览器会出现这个问题。在《CSS权威指南》里面好似也有提到这个问题,IE6对于多类选择符的支持很有问题,经过简单的测试发现IE6在多类选择符面前只对最后一个命名的类生效因此可能会产生“伪有效”的样子,这也是为什么网络上有些同学说IE6对多类选择符是可以支持的。不过这个问题其实也要归结到我们自身架构设计的不合理上,使用多类选择符来制作CSS是比较不明智的方式,当然后果就是在今后的应用当中如果对原来的CSS不清楚便会发生制作好的页面无缘无故在IE6下不可用的情况并且很难查出根源。经过研究发现这个问题给了我一个启示,如果对IE6的hack使用这种方式做似乎便可以轻松通过CSS验证了,当然这个可用性还有待研究,况且不支持对全IE系列的hack(fuhei.net的hack方式使用了IE的条件注释工具)。——根据渐进增强的理念我还是认同CSS高级选择符、伪类伪元素的使用的,对于打倒IE6我们坚决不能手软

问题三、这是一个比较诡异的问题了,后来搜索网络的时候才发现这个问题是一个比较普遍存在的问题了。在使用“所见即所得HTML编辑器”来写博客、发帖子大家是否曾想过它能够导致浏览器的崩溃?在刚开始出现这类编辑器的时候我还是有一点点的担心的,但是也只是一点点而已,后来随着Rich Text Edit(后文简称RTE)的发展这一点点的担心也消失殆尽了。不过就在上周却发现即便是现在最流行的FCKeditor也会出现这个令人头疼的问题(很抱歉不能方便重现这个问题,同时忘记错误代码了,明天来贴),在某一些电脑上使用Firefox3打开RTE会导致浏览器抛出runtime error的异常,在宇宙XX同合体的google上搜索得知是因为在RTE初始化的过程当中它的父元素被置为不可见的情况引起的,因此解决方法很简单,就是保证在父元素已经在网页上可见了的情况下再初始化RTE即可。——这个问题出现在了公司网站一个常用表单的处理上,希望没有造成太大影响,现在已经被作为Firefox3的bug论处

[纯技]产品列表到底应该怎么做?(例子更新)

星期四, 十二月 18th, 2008

最近随着狂风计划的席卷,我也终于开始公司某产品位列表展示的编码工作,这只是一个改进项目,因此有原代码可供参考。但是当我打开原代码模板的时候便愣住了,一个4 × n的矩阵为了执行div + CSS的标准而放弃使用非常牛B的table布局,这本无可厚非,可是由于“某原因”(后文会陈述)却让本来很有优势的div布局失去了原有的优势,在我反复思考这个问题的时候怎样都觉得table布局能比现在的这个更加合适。那么这个非常霹雳的布局是怎么样的呢?请见下图:

产品列表结构图(png太牛B了只有18K)

产品列表结构图(png太牛B了只有18K)

我想绝大多数UEDer都不会使用如上布局来实现这个模块,首先想到的当然是使用DIV[productItem]做4 × n次的循环,然而这个布局却使用程序控制每四个DIV[productItem]给它们套一个DIV[productListRow]。可能很多人都已经发现了,这个布局有一个先天性的不足,也就是前文提到的“某原因”,那就是由于产品简介的长度不同导致每个DIV[productItem]的高度不同,因此需要在每行列表后面都清除浮动以让浏览器可以做出正确排列。那么解决办法也就出来了,很简单,有如下几个:

1、最方便、最有效、性价比最高的方法就是我们当然可以知道最长长度的产品名称和产品简介,因此我们分别取这两个值排满的最高高度来作为DIV[productItem]即可,但是这个方法却有致命的缺点导致所有UEDer都不会这么做得,那就是当出现有人不填写产品简介或者产品简介填写得非常少的时候便会出现大段的空白严重影响观看阅读。

2、那就这样把,咱把“产品简介”给拿掉吧,然后使用方法1便可以完美解决问题了。这个想法非常牛B,可是它太牛B了,我绝对不敢这样操刀直接把这么重要的内容给砍掉(也许有人觉得这些内容并不重要,但是这不是这篇文章所要讨论的东西)。我对曾经抱有次想法表示遗憾和羞愧。

3、为什么不使用table布局呢?天哪我觉得这简直就是最完美的办法了,table一出八马难追的。能够自适应高度的table在这个应用上拥有绝对的优势啊,如果前端开发工程师们可以放下一点架子在html上使用它原本应该使用的结构该是多么美好的事情,我直到在写这篇博客的时候依然觉得使用table解决问题又快又省力还很有快感哦~(其实原代码中的div布局就是抄袭了table的“思想理念”了)

但是作为一个在非常牛B的UED团队的还是菜鸟的我为了要做出非常牛B的事情也为了团队的面子,怎样也不能使用上面三种投机取巧的办法来敷衍这个现实的问题吧,因此就有了这篇博客最重要的内容。

第一次尝试:

首先我们还是来考虑考虑到底使用什么标签来写这个列表吧,所谓back 2 base嘛。重新分析列表中最重要的元素有且仅有:标题、图片、简介。显然标题是最重要的,作为一个product的title存在,而图片和简介都是用来描述标题的内容,因此第一个想到的标签就是dl(请不要问我dl是什么,如果真的不知道请看这里)这样便有了以下布局(抱歉还没有时间整一个代码输入):

1
2
3
4
5
6
<dl>
  <dt>[name]</dt>
  <dd>
    <div>[photo]</div>
    <div>[intro]</div></dd>
</dl>

对dt和dd都做float:left,dt做一个margin-top:100px来定位到图片和简介中间,dd做一个margin-left:-25%来定位到和dt相同的x坐标(由于无法输入代码就不贴css了,请看例子)这样的html是我认为最贴切的,根据现在流行的html语义化定义这样的布局太合适不过了。当然css中还是存在非常多的困难,而前面所说的“某原因”也并没有得到解决,反而更甚了,因为把标题和简介流拆开后,标题过长便会和简介的文字叠加根本无法阅读!然而经过几秒钟的思考后认为这玩意儿的解决已经超出了我的范围了。当然,有人可能会说把标题和图片换一个不就可以了么?是的,没错,但是如果这样的话使用dl标签还有什么意义呢?可能有意义吧,就是标题和简介都是为了说明这张图片而存在的,但是真的可以这么想吗?还有待实验去证明,这里就不讨论了。

第二次尝试:

如上所述,dl的存在就没意义了,那就算了吧,退而求其次使用ul(请在砸我鸡蛋前念着我还死了那么多脑细胞在这个上面的份上轻点儿吧),无序列表虽然不如定义列表来得语义那么强烈,但至少它还是和列表吧,至少不是一个division吧。ul的布局相比较就简单多了,看上去也只是把div标签换成了li而已,那么html结构如下:

1
2
3
4
5
6
7
<ul>
  <li>
    <div>[photo]</div>
    <div>[name]</div>
    <div>[intro]</div>
  </li>
</ul>

到这个时候终于要直面本文第四次提到的“某原因”了(详见“某原因”例子),如何解决li浮动后高度不同导致的矩阵错位问题?最先进入脑子的想法就是记得很久很久以前看到过一篇关于div自适应高度的文章,于是就在google翻找,当时没有收藏真是太失误了。在google搜索自适应高度那是相当多呀,但是有一篇文章是不得不借鉴的,但是这篇文章并不是适应于我们的案例,很显然它更适用于两栏或者三栏布局,而我们至少有四栏甚至五栏。自此还有什么办法可以让多列布局自适应高度呢?(请不要跟我提关于巨大的padding与负margin这件事)伪装的自适应对于需要货真价实产品的我们是没有用的……至此思维告一段落,我需要回到源头来,最开始的出发点在哪里?如果只是为了清除浮动的话?使用最简单的方法?

带着上面的问题,便渐渐有了解决方案,不可避免的,我可能需要借助后台工程师的力量了,我在每4个li之后的那个li上加上clear:left属性,以清除左边的浮动来防止它因为前面li的高度不够而导致的错位,从它之后的li就应该会乖乖地跟在它的后面了。这个想法很美好,但是很天真,可能我确实在FF等标准浏览器下面获得了预想中的效果(没有想到实现起来那么简单,正在开心中),突然发现又是那该死的IE!!!那个加了clear属性的li确实正常显示了,但是在它之后的那些继续原来它应该范的错误,没有起到清除整行浮动的作用(详见该死的IE的例子)。我懊恼了~通过漫长的研究至今已经找到了一个语义和样式都比较平衡的点却无法在IE中得以实现,怎么办?

第一个想法就是使用hack技术(虽然UEDer们都不推崇,但是为了维护之前的成果,老子发飙了),问题就是如何做hack。先看这样的例子,如果我每4个li后面都插一个<li style=”clear:both;float:none;”></li>的话,不管在IE下还是在FF下都可以完美地完成任务,但是这个方案有一个致命的缺陷,就是对原有html语义的破坏,凭什么好好的列表突然就多出一个空li来?那么能不能在不影响原来语义的情况下,在FF依然使用它应该使用的clear:left方式的情况下来针对IE进行hack呢?非常幸运的是IE给我们提供了条件注释工具<!–[if IE]><![endif]–>(我想一旦开始使用这个东西之后一定会非常依赖它的),因此html结构就变成了这样:

1
2
3
<li>[productItem]</li>
<!--[if IE]><li class="clearForIE"></li><![endif]-->
<li class="clearForFF">[productItem]</li>

希望这样子写代码可以看得懂(详见我的解决方案例子)。至此为了尽力表述完整语义的目的就达到了,因为所有的浏览器、搜索引擎和用户都会把那段IE的hack作为一个普通的注释来看待(这里也包括IE自己,这是一段条件注释,那还是注释),因此产品列表的li就没有被中途无故打断,更不会像最早的div版本每四个是一个division。到这里研究工作就算完成了(关于这个IE特有的hack的可能的严重后果木有给予考虑。。。),不过还有一些额外的思考。

其实使用division也不完全是不好,如果division这样做:

1
2
3
4
5
6
7
8
9
10
11
12
<div class="top20">
  <div class="top15">
    <div class="top10">
      <div class="top5">
        DIV[productItem]{1-5}
      </div>
      DIV[productItem]{6-10}
    </div>
    DIV[productItem]{11-15}
  </div>
  DIV[productItem]{16-20}
</div>

《超越CSS》

星期天, 九月 7th, 2008

我承认我是一个不爱看书的人,每次捧起书都会觉得困意十足,不过也终于历时N久的时间把这本《超越CSS》给啃完了,其实前三章用了三天就处理掉了,只是最后一章一直没有动力,拖了近一个月才在今天把它给完结了。

《超越CSS》(Transcending CSS)

《超越CSS》(Transcending CSS)

这本书超贵的69块钱一本,还好我这本是借来的,即便是300多页彩印铜版纸也用不了那么离谱的价格嘛。。。不过好在书的内容确实很好,不仅介绍了许多CSS的技巧和基本的设计准则,而且还为读者敞开了一扇新的大门,它以CSS的视角放眼整个web的设计和开发过程,创造好的版式、好的交互、好的代码、好的流程。超越CSS是每一个优秀的web设计师都必须做到的,所谓在遵循规则的基础上打破规则才能创造出最优秀的作品。

首先我们要遵循的规则便是:CSS是一个非常优秀的定义样式的工具,但是我们不能要求所有的使用者都能够顺利地从你设计的CSS界面当中获取合理的排版信息和漂亮的图片说明,因此我们必须创造出一个在没有CSS状态下也能够顺利被阅读的文档。在这个基础上我们需要使用合理的标签去标记内容,请尝试把生活当中的所有物品都标签化吧,这将对今后的设计有很大的帮助。

其次我们需要一个好的工作流程:收集内容->框架图/灰盒->静态设计->交互原形->有意义的标签->CSS编码/JS编码。要注意的是CSS工作可并不只是CSS编码那么简单的事情,每一个CSSer要把自己放在一个设计师的角度来看待整个设计才能创造出优秀的页面,往往视觉设计师只是注重了视觉的效果,而你作为一个CSS设计师则需要更加关注内容的突出表现、用户的交互甚至搜索引擎等等更为细节的内容,而这些内容都建立在内容排版之上。

那么接下来如何创建一个优秀的排版呢?我们可以引入网格的设计,我们可以在任何你想得到的地方使用黄金比例和三分之一规则,而更能吸引人的地方便是在遵循网格的基础上突破它,创造出令人意想不到的版面设计。我们可以去参考新闻报纸,那是最最基本的网格应用,几乎早期的所有报纸都遵循8列或6列的网格版面,而今的报纸则更加多元化,在那些花哨的广告和醒目的娱乐头条上都能找到网页的设计灵感。同时我们还可以在杂志、唱片店、剪贴簿甚至Flicker上面寻找创作的灵感。

真正的超越CSS不是在一些常规的或者旁门的小技巧上的应用,而是不被现在的CSS规则拌住了脚,譬如我们总是以为:唉~这个设计太麻烦了~CSS的编码会很痛苦的~还是算了吧~;再譬如我也总是想着:我要让使用任何浏览器的用户看到的都是一模一样的优秀设计~,这些都是非常愚蠢的想法,而要改变这样的想法仅仅需要记住超越CSS就可以了。。。

CSS和CSSer们一样的年轻,可CSS3已经指日可待了,那么在超越CSS的最后还是让我们期待这个优秀的样式设计表继续在未来的浏览器甚至应用程序中发挥出巨大的作用吧。

PS1:如果想买这本书可以在卓越网获得75折的优惠。

PS2:自从这本书以后便多去关注了一下相关类别的其他书籍,发现人民邮电出版社是非常王道的,因此可以直接去新华书店的人民邮电出版社专柜。