CSS多邊框
Backgrounds & Borders Level 3 還是一份草案的時候,CSS WG 就在是否支持多重邊框的問題進行了大量的探討,就像是討論多重背景圖片一樣。不幸的是,當時認為多重邊框的用處並不大,即使需要也可以使用border-image屬性來模擬。不過,WG顯然忘記了在 CSS 代碼中靈活地調整邊框,才是我們需要的,現在開發者只能使用一些Hack手段來模擬多重邊框,比如使用多重元素的嵌套來模擬多重邊框。現在,我將告訴你一些更優秀的方法,無需使用多余的標簽即可實現多重邊框。
box-shadow解決方案
現在,大多數的時候都用box-shadow來創建陰影。不過,很少有人知道它還接受第四個參數(spread),該參數可以縮放陰影的范圍。比如下面的示例,我們創建了一個水平和垂直偏移量為0 的陰影,它就使用了上述所說的第四個參數:
CSS Code復制內容到剪貼板
background: yellowgreen;
box-shadow: 0 0 0 10px #655;
效果如下圖所示:
圖注:使用 box-shadow 模擬邊框線
這還不夠令人驚訝,因為它和我們使用 border 創建的邊框差不多。不過,強大的是我們可以使用逗號來創建任意數量的陰影。所以,只需要繼續添加陰影就可以實現多重陰影了,比如,添加一個顏色為 deeppink 的邊框:
CSS Code復制內容到剪貼板
background: yellowgreen;
box-shadow: 0 0 0 10px #655, 0 0 0 15px deeppink;
唯一需要牢記的事情就是,box-shadow 屬性是疊在一起的,第一個陰影總是位於最頂層,所以你需要調整陰影的大小。比如,在上一段代碼中,我們希望最外層的邊框為 5px,那麼我們就可以設置一個 15px(10px + 5px) 的陰影。如果你需要,那麼就可以為指定任意層次的陰影:
CSS Code復制內容到剪貼板
background: yellowgreen;
box-shadow: 0 0 0 10px #655,
0 0 0 15px deeppink,
0 2px 5px 15px rgba(0,0,0,.6);
除了下述的少數情況外,使用 box-shadow 的解決方案都很好用:
陰影並不是邊框,它們並不占有實際的空間,也不能歸屬於 box-sizing 的范圍。不過,你可以通過使用內邊距或外邊距(取決於陰影是內部的還是外部的)占據額外的空間來模擬。
上述示例模擬的邊框是位於元素外部的。它不能捕獲類似懸停和點擊的鼠標事件。如果事件很重要,那麼可以通過添加 inset 關鍵字讓陰影出現在元素的內部。注意,你可能需要添加額外的內邊距來擴充空間。
outline的解決方案
在某些情況下,如果我們只需要兩層邊框,那麼我們只需要一層常規的邊框和一層outline 就可以實現。這也讓我們的邊框在樣式上保持了足夠的靈活性(比如我們想要一個虛線邊框),但是使用 box-shadow 的話,我們只能模擬出實線邊框。如下圖所示:
注:使用 box-shadow 模擬兩條輪廓線
CSS Code復制內容到剪貼板
background: yellowgreen;
border: 10px solid #655;
outline: 15px solid deeppink;
使用 outline 的另一個好處就是,我們可以通過 outline-offset 控制 outline 到元素邊框的距離,該屬性甚至可以接受負值。這對很多效果都非常有用,如下圖所示:
*注:對於虛線樣式的輪廓線,通過給 outline-offset 設置負值,創建了一個基礎的縫紉效果 *
不過,這種方法也有一些限制:
就像起初說的那樣,這種方法只能模擬兩層邊框,因為每個元素只能創建一個 outline。如果需要創建多重邊框,那麼只能使用 box-shadow 的方法。
border-radius 並不能讓 outline 呈現圓角效果,所以,即使你的邊框是圓角的,outline 仍然是直角的(如下圖所示)。注意,CSS WG 認為這是一個 bug,在未來border-radius可能可以將 outline 變為圓角。
根據 CSS User Interface Level 3 specification 的說法:“outliens 可能並不是矩形。”雖然大多數情況下它看起來像是矩形,但是在你使用這一方法時,還是需要進行跨浏覽器測試的。
圖注:通過outline創建的輪廓線並沒有貼合元素的圓角,這個問題在未來可能會被修正
border-colors解決方案
border-colors是一個獨特的屬性,從字面上來說就是為多邊框而生,只可惜的是,到目前為止這僅是Gecko內核浏覽器獨有的屬性。
如果不追究浏覽器的兼容性,那麼border-colors也可以實現多邊框的效果。在具體使用時,需要分成四邊邊框來寫:
CSS Code復制內容到剪貼板
-moz-border-top-colors:
-moz-border-right-colors:
-moz-border-bottom-colors:
-moz-border-left-colors:
雖然這種方式也能實現多邊框效果,但相比前兩種解決方案而言要麻煩一些,來看一個簡單示例:
CSS Code復制內容到剪貼板
border: 10px solid;
-moz-border-top-colors: red red red red green green green blue blue blue;
-moz-border-bottom-colors: red red red red green green green blue blue blue;
-moz-border-right-colors: red red red red green green green blue blue blue;
-moz-border-left-colors: red red red red green green green blue blue blue;
為了要實現三個顏色的多邊框效果,red占4px,green占3px和blue點4px。需要大費周折。而且還不能直接寫border-colors,因為浏覽器不識別這樣的屬性。
除此之外,目前浏覽器對這個屬性支持度相當的弱。可以說,它只是Firefox的私有屬性。
CSS透明邊框
對 CSS 中的半透明顏色可能已經有了基礎的了解,比如 rgba() 和 hsla()。從 2009 年開始,雖然在開發設計中使用它們需要付出一些代價,比如提供降級措施、使用IE濾鏡,但是總得來說它是一個巨大的變革。不過在實際中,它們主要被用於背景,有這麼幾點原因:
早期的開發者沒有意識到這些新屬性就是類似 #ff0066 和 orange 的色彩,而是將它們看作是圖片,所以僅用在了背景上。
為背景提供降級方案比其他屬性更簡單。比如,可以直接使用單像素的半透明圖片替代半透明背景。對於其他屬性,則只能使用不透明顏色。
在其他屬性上使用半透明顏色,比如邊框,並不簡單,我們將在下文介紹原因。
圖注:24ways.org 是第一個在設計中使用半透明顏色的網站,那時還是 2008 年,那時它們網站的特點就是使用了大量的背景(由 Tim Van Damme 設計)
假設我們想要美化一個容器,讓它擁有一個白色的和半透明白色的邊框——這個半透明邊框可以讓它後面的內容顯示出來。我們要做的第一步就像是下面這樣:
CSS Code復制內容到剪貼板
border: 10px solid hsla(0,0%,100%,.5);
background: white;
除非你非常了解background和border這兩個屬性的工作原理,否則上面代碼得到的結果會讓你感到非常的困惑。邊框哪裡去了呢?是不是不能為邊框添加半透明顏色呢?到底該怎麼做?
圖注:第一次嘗試實現半透明邊框
解決方案
雖然看起來的效果和預期有所差異,其實邊框是存在的。實際上,背景色默認會擴展到邊框上,這一點可以通過給邊框添加虛線觀察到。如下圖所示:
圖注:背景默認會擴展到邊框區域下方
雖然這和你使用不透明的實線邊框是一樣的,但在這個示例中,它完全推翻了我們的預期。結果看起來是純白色的邊框,實際上是一個半透明白色的邊框,然後在它下面是白色的背景色。
在 CSS 2.1 中,這就是 background 的工作原理。我們不得不接受和使用