/ Web Design

[Layout] Web Design Part 9

大過年的,穿新衣戴新帽好像已經是小時候的事情了。所以,趁著大過年,找點事情來充實一下其實也是不錯的。當然,肚子已經充實了,腦袋也要充實一下,不然實在有點說不過去。

是說包紅包嘛,紅包肥了,荷包就瘦了。所以不要來跟我拜年。


如何選擇

市面上眾多的 CSS Framework 之所以說樣式無用(Style Agnostic),是因為他們已經幫你定義好,什麼樣的選擇器,該做什麼樣的事情。但是,如果我們從頭開始,我們該怎麼去選擇?

實際上,你對於選擇器這樣的東西,有多少的了解?簡單的說,他就像是積木,一個蘿菠一個坑,只是最終的結果不同而已。我在上一篇已經有提過,萬用且常見的選擇器有三種,ID, Class, Tag,那,我們就從這裡開始。

ID SELECTOR

顧名思義,他就是使用 HTML 中的 id 屬性值來定義的。例如:<a id="mylink" href="...">...</a>,那麼這裡就定義了一個 id 屬性,他的名稱叫做 mylink。請注意,id 屬性的值是唯一值,換句話說,在整份的 HTML 文件中,只能出現一次

這個值,我們在 CSS 當中,是以井字符號(#)來代表我們要使用ID SELECTOR。而,在樣式表當中,使用 ID SELECTOR 的權重是相當高的,你也許曾經看過一些樣式權重的計算機,將 ID SELECTOR 給予 1000 這樣的數值,方便運算使用。

CLASS SELECTOR

這個選擇器又稱為類別選擇器,與 ID SELECTOR 一樣,也是使用 HTML 中的 class 屬性值來定義。唯一不同的地方是,他是可以多重定義的一種屬性。例如:<a class="links background-blue text-color-white" href="...">...</a>,那麼,這裡就定義了三種不同的類別屬性值,分別叫做 links, background-blue, text-color-white

而,在 CSS 樣式表中,我們使用類別選擇器時,是以點字符號(.)來代表我們要使用類別選擇器。類別選擇器本身有兩種用法,這是有別於其他選擇器的用法。類別選擇器可以將類別相黏,來做到多重類別混用的情況。

例如剛剛的例子,我們有三種不同的類別屬性。假設,我們需要某兩種同時出現時,才套用某種效果,那麼,我們的 CSS 就可以這樣寫,

.links {
}
.background-blue {
}
.text-color-white {
}
/* 這裡代表著,需要同時符合兩種屬性值,這樣的樣式設定才會生效 */
.links.background-blue {
}

如果說 ID SELECTOR 是針對單一元素做設定,那麼類別選擇器就是利用在高重複性的樣式上面。

TAG

標籤,就是 HTML 的標籤,他也是一種選擇器,只是,通常我們不會用選擇器來稱呼他。在樣式表當中,我們僅只用元素標籤來稱呼這樣的設定。標籤可以與上述兩種選擇器做相黏的混用,不過,通常與類別選擇器相黏居多。因為 ID SELECTOR 是唯一值,所以做相黏設定有點多此一舉。

body {
}
/* 標籤與類別相黏 */
a.mylink {
}
/* 標籤與擬似元件選擇器相黏 */
a:hover {
}
/* 標籤與 ID SELECTOR 相黏 */
a#my_home {
}

以上這三種是最基本的選擇器應用方式,我們接著來繼續看其他的選擇器,到底是如何被應用的。還有,這些選擇器之中,是不是有什麼致命的缺點?

SELECTORS

再上一篇文章中,我們提到了很多的選擇器、擬似類別與擬似元素等等。而這些設定我們該怎麼使用呢?雖然這些選擇器千奇百怪,不過,大抵上都是依照上述的三種基本方式演變而來。使用的方式是相當主觀的

由於選擇器的規則,與 DOM Tree 脫不了關係,所以,在使用某一些較為特殊的選擇器時,你必須對 HTML 的 DOM Tree 有一定的了解。這裡不詳細解釋那到底是什麼,簡單的說,他就是 HTML 標籤與標籤之間的事情。

<div id="main" class="main-container">
    <div id="header" class="my-header">
        <div id="nav" class="navigation">
        </div>
    </div>
</div>

以上述的例子來說,#main, #header, #nav 就是三種 ID 選擇器,而他們個別有類別選擇器。跳脫這些事情,我們以 HTML 的 DOM Tree 來看,他的結構就是這樣,

#main > #header > #nav

每一個 HTML 標籤往下包著另外一個 HTML 標籤。這種層層包疊的方式,就是一種DOM Tree。這顆樹會越來越大,當你的切版愈趨複雜的時候,你的 DOM Tree 就會相對的變得相當龐大。

那麼,選擇器與 DOM 之間的關係是什麼?我們從上一篇文章中,得知有許多不同種類的選擇器。在這些選擇器當中,有不少是根據 DOM Tree 而運作的,舉例來說:

/* 親代(後代)選擇器,使用空白分隔兩種選擇器 */
#main .my-header {
}

這個寫法的意思就是,我使用親代(後代)選擇器,這個選擇器發生作用的時機是,#main 容器中,包含了 .my-header 這個類別,則當這種情況發生時,這樣的選擇器就會發生作用。

也許,我們用 TAG 的例子會更容易理解。

<div id="container">
    <header class="my-header">
    </header>
    <div id="main">
    </div>
    <footer class="my-footer">
    </footer>
</div>

如果我們使用了這樣的樣式設定,

div#container header {
}

那麼,你知道這樣的撰寫方式,他會在什麼時候生效嗎?

所以,絕大部分的選擇器,都與 DOM Tree 有關。例如,

/* 子元件(子嗣)選擇器 */
div#container > header {
}

子元件(子嗣)選擇器的使用方式跟親代(後代)選擇器非常相似。唯一不同的地方,是子元件選擇器適用於該元件所包含的第一代子元件,而親代選擇器,則是無論你是第幾代全部都適用。

另外像是相鄰元素選擇器,則是兩種 HTML 元素立即相鄰時會發生作用,這比起上述兩種選擇器又更嚴格了一點。

header + #main { }

而有趣的是,Selector Level 3 又新定義了一種叫做一般相鄰元素選擇器,

header ~ footer { }

差別在於,相鄰元素選擇器需要立即的元素相鄰,而一般相鄰元素選擇器,則不需要。

何謂相鄰

<div id="first"></div>
<div id="second"></div>
<div id="thrid"></div>

上述這樣的寫法就叫做相鄰。而 #first#second 稱作立即相鄰,而 #first#thrid 則稱為一般相鄰

這樣對於選擇器有多一點認識了嗎?下一回,我們來聊聊致命的缺點