Tin's Blog

          You are coming a long way, baby~Thinking, feeling, memory...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            128 隨筆 :: 0 文章 :: 221 評論 :: 0 Trackbacks
          本文已經發表于InfoQ中文站,(充滿Trick的CSS,兩難的選擇

          javaeye的hax最近在他的blog上進行了一場關于如何寫css的討論,其中反思和討論了一些關于基于標準或trick進行設計的選擇問題,這個問題也是David Heinemeier Hansson對于XHTML/CSS/Javascript標準進行RIA開發話題的一個延展。我們可以從中思考如何在不完美的技術中選擇一條相對完美的技術路線?

          討論的起因是淘寶網的UED團隊成員段王爺在他的blog上發表了一篇關于淘寶網頁面設計上的小技巧(Trick)的介紹,這個技巧是為了讓一些條目之間的分隔線完全使用css生成,不使用多余的class,段王爺還對比了其它三種常見實現方法。實現方法如下:

          從很久很久以前開始,類目間的橫線無非都只有三種。
          1、背景圖
          在a標簽設置一個padding 用寬1px高不等的背景圖來position到右側。
          缺點:最后一個還是要用class來隱藏掉背景。
          2、符號
          在每個a標簽之間用“|”符號來填充。
          缺點:html文件變大,文件維護變得很麻煩,而且在html中毫無意義。
          3、a標簽右側的boder。
          同背景圖一樣,只不過使用border-right來代替。缺點也同上。

          其實現有(淘寶的實現方式)是利用ul的overflow:hidden 再將li的margin-left:-1px的做法做出來的。這樣的做法就可以同時避免以上的缺點了。

          上面提到的使用border的傳統方式需要在第一或者最后一個元素上面添加class來隱藏border,Realazy也在他的blog中給出了一種不錯的解決方案,他推薦這樣做:

          導航項目間的豎線,我們往往通過border或者background來實現。特殊需求是,第一項左邊無豎線或最后一項右邊無豎線。按照一般的編程方法,控制第一項要比控制最后一項容易得多。

          區分第一項的還有一個好處是,CSS有一個:first-child的偽元素(pseudo element)可以讓我們輕而易舉的選擇第一個子元素。遺憾的是,當前全球占有率最高的瀏覽器,IE6,并不支持這個偽元素。我們可以手工給第一個元素加上class然后再定義它。等ie6淘汰之時,就可以放心用 :first-child了,相權衡的話,我覺得給第一項加上class="first"也不失為實用主義做法。

          Realazy提出的方案的思路是使用基于標準的css選擇器(selector),這種方法的好處是可以實現完美的內容與表現分離。但是現實的問題是并非所有的瀏覽器都基于標準實現,這也正是基于標準的RIA開發面對的最大問題,尤其以CSS和Javascript問題最大。javaeye的hax在他的blog中提出了自己對于這個Trick的不同意見:

          因為我覺得這個方法一點也不好。很簡單的一個理由:這只是一個trick,只適合這特殊情況,假設你要換用“-”來分割呢?作為插入分割符號來說,真正合理使用css的,我給一個例子:
          li ~ li:before { content:'-'; margin:0.25em; }

          優點:含義非常清晰,維護性極高。你可以換任何的分隔字符,可以設定字體,可以設定顏色、大小等樣式,甚至可以換用圖片作為分隔。

          好了,下面說缺點。唯一的缺點:IE不支持。

          hax給出的方案在IE中無法使用,其實對于大部分網站來說這就相當于絕大多數用戶都無法看到這種表現,這就意味著失敗。淘寶UED的小馬提出“實用第一”,從這種觀點上說hax的方案就是不實用的。但是hax提出可以使用Dean Edwards的IE7 Javascript庫

          IE7是一個可以讓IE像標準瀏覽器一樣工作的Javascript庫。它修正了很多CSS問題,讓PNG在IE5和IE6下正常工作。

          IE7這個庫動態的實現了很多IE原本不支持的偽類(Pseudo Classes),讓完全基于標準的css選擇器(使用偽類)成為可能。隨后,hax在他的另外一篇blog“面向未來的CSS實踐”中作了如下設想:

          我推崇一種面向未來的CSS實踐。即大膽采用CSS2.1甚至部分CSS3的特性。因為絕大多數特性,Firefox、Opera、 Safari等都已經很好的支持了。MSIE7也改進了許多,將來IE也無疑終究會完全支持CSS2.1。對于目前的IE,除了graceful degradation的方式(實際上整個內容樣式分離的原則和良好的CSS設計可以確保這點,比如淘寶以前的“裸體”所體現的),可以考慮通過特定手段來patch之。

          在這點上,我必須說,我原來也是一直堅持只用ie6的selector的。是什么改變了我?就是Dean Edwards的IE7!它的出現不僅在于實踐價值——即提供了一個對于IE的補丁,讓開發者可以直接寫CSS2甚至CSS3。

          hax提出的這種方式是比較激進的,他還在“面向未來的CSS實踐”中進一步的描述了通過腳本修正的方式解決IE不支持標準偽類和多class問題的設想,他的核心想法就是讓CSS的開發可以遵循標準,減少為了優雅退化(graceful degradation)而向最低支持(瀏覽器)兼容造成的表達方式限制。但是hax自己也提出了這種思路面臨的尷尬,它舉了table布局的實用性價值為例:

          我認為出現這樣諷刺的情況,即遵循標準的人活得比不遵循的人更累,是很有問題的。這種矛盾在我身上存在著,2001年的時候我在某bbs上發了個貼,大數 table布局之罪,但是過了幾天我又跑上去說table布局在某種情況下也可以用用。 dlee同志貌似到現在也跟我當時一樣。如果你確實認為,table布局從實用主義角度無法被完全否定,那DHH同志采用實用主義的角度來力挺 html/css/js就也有點心虛,那個標題也就顯得帶點任性味道……

          “遵循標準的人活得比不遵循的人更累”這句話說出了很多堅持基于標準進行CSS設計的開發人員的心聲,這其實是實用性和堅持標準之間的一些交換,現實世界中兩個方面如何平衡正是廣大XHTML/CSS/Javascript開發者需要認真思考的,關鍵的問題,還是目的要明確。盲目的遵循標準,例如很多開發者著迷于使用div布局代替table,但是卻沒有明確的目標就會迷失,hax這樣評價:

          從實用主義角度說,謹慎的table布局也許更簡單,因為它更好的映射到了grid模型上。如果你轉用div/span,標簽是清晰了,但是css是混亂的!這些屬性(css屬性)是分散的,css代碼無法反映整體,無法記錄你的grid 布局意圖!這是為什么我們經常說我有一個css trick的原因,它是trick而已,是你達到最終目的的手段,但是你的目的,你的意圖,沒有好好加入文檔的話,那維護起來恐怕也不見得輕松。

          table布局 其他css樣式 = 清晰的布局意圖和內容的混合體

          div容器 css樣式 = 內容樣式分離,但是從css代碼中很難看出布局意圖

          關于div/css布局還有一些誤區,簡單的把table標簽換成div是沒有意義的(若干層級的div可能比table更糟糕)。實際上我們希望的是語義標簽。

          我們應該看到,CSS的意圖是將表現分離。從設計的角度就是實現語義化的html結構,讓html/xhtml盡量只表達純粹的數據結構。但是此時css里面的布局意圖是比較難以被記錄的(難以被理解就難以維護,難以重構),有其在充斥了大量Trick的情況下,這正是廣大程序員/設計人員需要解決的,我們是否應該通過不斷地重構來找到這個矛盾的平衡點呢?歡迎大家討論。最后附上淘寶UED團隊的小馬總結的淘寶CSS編程原則:

          1. 盡量不使用hack
          2. 盡量不使用ie6不支持的選擇符
          能符合這兩個條件的最簡潔的寫法,就是我們的目標。
          posted on 2007-09-10 08:02 Tin 閱讀(2533) 評論(1)  編輯  收藏 所屬分類: RIA

          評論

          # re: 充滿Trick的CSS,兩難的選擇 2007-09-10 13:38 編程、設計是職業更是愛好
          的確,語義化才是我們所要的,而不是zero table.   回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 南投县| 台中县| 泸西县| 玛纳斯县| 明光市| 遵化市| 庄浪县| 泰来县| 岳普湖县| 宁陕县| 威海市| 大理市| 盱眙县| 济源市| 榆中县| 永定县| 平邑县| 广德县| 武穴市| 梁山县| 安仁县| 广元市| 蕲春县| 宁波市| 泽州县| 临夏市| 谢通门县| 广汉市| 扬中市| 安塞县| 茂名市| 金湖县| 白水县| 望都县| 石阡县| 天镇县| 普定县| 台中县| 元江| 松溪县| 揭西县|