前台開發從頭說起:談談CSS選擇符

來源:互聯網
上載者:User

以前我接受了網上不少博文的說法,一直認為學習css的三大最重要問題是:盒模型、定位、浮動。因為這三塊的內容決定了css布局的能力。但是通過上一篇日誌的分析,xhtml要實現和css的解耦,就要盡量不依賴於css(或者說不要純粹為了給css預留介面而添加不必要的class和id),那麼,在用css布局之前,其實就有一個更緊迫的任務擺在我們的面前——如何將css規則準確應用到目標元素。於是,css選擇符的地位在這個前提下就空前的提高了。所以,在開始學習盒模型、浮動、定位之前,有必要回顧一下選擇符。

 

一般稍微接觸過css的網頁設計人員,都會很快地學會三種css選擇符:

  • 元素選擇符(例如:body 、a 、li )
  • ID選擇符(例如:#head、#body、#foot)
  • 類選擇符(例如:.red、.item、.content)

更進一步之後,開始瞭解到一些進階的選擇符:

  • 後代選擇符(例如 #head .menu、#foot #copyright)
  • 偽類選擇符(例如 a:hover、a:link)

以及由這些選擇符組合起來形成的綜合選擇符。實際上css還支援一些更豐富的選擇符。但是能夠被瀏覽器廣泛支援的其實主要就是上面這幾種,其它的選擇符在css中往往用來區別處理不同的瀏覽器,或者用在jQuery一類的架構中。本文就不提了。有興趣的可以自己在網上查一下,像屬性選擇符(input[type=’password’]、input[type=’radio’])、直接後代選擇符(body > div、 #head > ul)等。

實際上,有了上面列出的五種主要的選擇符,通過對它們的組合,已經能夠滿足我們絕大部分時候的要求了,這也就意味著,相同結構下的元素,父級元素或者祖先元素只要有一點點區別,我們就能夠在不藉助id或者class的情況下直接存取到。例如:

<ul>  <li><a href="#">菜單1</a>    <ul>      <li><a href="#">菜單1-1</a></li>      <li><a href="#">菜單1-2</a></li>      <li><a href="#">菜單1-3</a></li>    </ul>  </li>  <li><a href="#">菜單2</a>    <ul>      <li><a href="#">菜單2-1</a></li>      <li><a href="#">菜單2-2</a></li>      <li><a href="#">菜單2-3</a></li>    </ul>  </li></ul>

這個結構是我在《來自微軟的純css下拉式功能表》一文中用到的下拉式功能表結構。在那個樣本中,沒有使用任何的class或者id,但是我們通過不同優先順序的元素+後台選擇符,對結構中的不同層次的ul、li、a實現了精確定位。如下面的代碼:

ul {}li {}ul ul {}ul ul li {}li a {}ul li a {}ul li:hover ul {}

那麼,在實際開發中,為什麼很多網頁設計人員還是離不開多如牛毛的ID和class呢(我要聲明一下,我從來沒有說完全拋棄id和class,我的觀點是他們應該盡量少,並且由文檔結構決定而不是由css需要決定)?我覺得有三方面的原因:

第一、xhtml文檔結構不合理,通過元素不能體現文檔的階層。滿篇都是div。沒有有效利用Hx系欄標籤和ul、ol、dl等不同含義的列表標籤、沒有有效利用p、quote、pre等標籤。xhtml為我們提供了豐富的標籤元素,但是如果我們只會用div,那還不如人家用table來布局的。至少他的table在一定程度上也是文檔結構的體現,而滿篇嵌套的div,文檔結構完全沒體現。

第二、css選擇符掌握得不夠,不善於藉助文檔結構層次上的細微區別,用不同的組合選擇符來區別相似但其實不同的元素。例如上面的下拉式功能表結構,有的人就非要用“menu”和“submenu”來區別。

第三、css選擇符的優先順序不清楚。css是支援繼承和覆蓋的,什麼時候繼承,什麼時候覆蓋。兩條規則都對相同元素做出了樣式規定而且樣式規定重複的情況下,哪一條規則會被應用呢?這些問題不清楚,就沒辦法充分利用優先順序實現規則的覆蓋。於是只好每個要應用樣式的元素都加上id或者class。關於css選擇符的優先順序,網上也有很多文章,我就不贅述了。

所以說,如果感覺離不了class,離不了id,那隻能說明兩個問題——xhtml結構不合理或者css掌握得還不夠。我上一篇博文發了以後,有位朋友評論說我沒做過前台開發。因為沒有class和id,就不能實現css和javascript的分離。實際上,只要是長期深入學習css和javascript的朋友應該都清楚:在結構有差異的情況下,用css選擇符就能精確定位某個元素;在結構完全相同的情況下,藉助javascript和DOM,同樣可以精確定位某個元素。

仍然以上面的下拉式功能表列表為例。首先使用 ul a 對父級菜單的連結應用樣式,然後用ul ul a就可以精確定位到次級菜單的連結,應用新的樣式,對ul a的定義進行覆蓋。那麼,如果是要精確定位到第二級菜單的第二個元素呢?由於css3的選擇符目前還沒被廣泛支援,而結構又沒有差異,不藉助javascript有困難了。但是藉助於javascript,非常輕鬆,比如在jQuery中,我們可以用 $("ul ul:nth(2) li:nth(2)”) 或者 $("ul ul”).eq(1).find(“li”).eq(1) 都能得到第二個子功能表的第二個菜單元素。

css和javascript能夠自己精確找到網頁中的任何一個元素,那麼網頁自然就不用自己標識自己的每個元素。少了這層負擔,我們在設計網頁文檔結構的時候,自然就可以拋棄一切後顧之憂,那麼,xhtml中和結構無關的id和class,還有什麼必要存在呢?

去除了不必要的表現元素和屬性(font、center、align、height)之後,又去除了不必要的id、class、onclick、onmouseover之類的樣式和行為屬性,我們的網頁原始碼尺寸越來越小,抓一個頁面下來,少量必要的結構元素之外,剩下的全是連結和內容,這樣的網站,搜尋引擎能不喜歡嗎?

沒有了後顧之憂,認清了努力方向,那麼下一次我們就來談談css的盒模型。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.