前言
當CSS3推出border-radius
屬性時我們是那么欣喜若狂啊,一想到終于不用再添加額外元素來模擬圓角了,但發現border-radius還分水平半徑和垂直半徑,然后又發現border-top-left/right-radius的水平半徑之和大于元素寬度時,實際值會按比例分配元素寬度時,不禁會問"我真的懂border嗎?"。本系列將稍微深入探討一下那個貌似沒什么好玩的border!
《CSS魔法堂:重拾Border之——解構Border》
《CSS魔法堂:重拾Border之——圖片作邊框》
《CSS魔法堂:重拾Border之——不僅僅是圓角》
《CSS魔法堂:重拾Border之——更廣闊的遐想》
解構border-image
<style type="text/css">
div {
border: double orange 1em;
border-image: url("border.png") 27 round stretch;
}
</style>
<div>........</div>
起初瀏覽一遍border-image的用法時,總以為就是border變粗了,然后以圖片作為Line Pattern,接著是各種平鋪方式就完事了。后來細讀W3C Spec,發現我還是2 young 2 simply了,簡稱太2了。
要理解好border-image,那么先要理解它由那幾類對象組成,對象間的關系和組合規則。
3個和尚有水喝
- 目標元素本身(即上面的div元素)
- 用作邊框素材的圖片(即上面的border.png)
- 貼圖區(Border Image Area)
引入圖層概念
用過PS或Flash的同學應該都清楚圖層的概念吧,反正我是現在才理解圖層的:(
目標元素和貼圖區分別位于兩個圖層,并且貼圖區所在的圖層位于目標元素所在的圖層之上,而素材圖片經切割后將在貼圖區圖層上作后期處理,最后作圖層合成處理。
重申3點
- 目標元素和素材的圖片分別在各自獨立的圖層上繪制;
- 圖片會經過切割后,按規則在所屬圖層上的貼圖區內作定位和平鋪處理;
- 圖片所屬圖層在目標元素所在圖層之上。
透過屬性看本質
在理解border-image的組成和整體處理流程后,我們先通過屬性來認識與圖片和貼圖區密切相關的知識——圖片切割/切片和貼圖區切割/切片
圖片切割/切片
- 屬性
border-image-source
作用:引入用作邊框素材的圖片資源
語法:border-image-source:url("image url")
url入參為圖片路徑,可以是HTTP或HTTPS Scheme URI下的絕對或相對路徑,或采用Data Scheme URI。 - 屬性
border-image-slice
作用:對通過border-image-source
引入的圖片資源,以九宮格的形式作切片
語法:border-image-slice: [<percentage> | <number>]{1,4} fill?
屬性值的順序和簡寫時語法擴展的規則與屬性border-width
一致(top,right,bottom,left),而其含義為距離圖片各邊(top/right/bottom/left)多遠的位置上,畫一條與對應邊相互平衡的切割線。注意:切割線必須位于圖片所在面積內
<percentage>
:以圖片的尺寸(寬、高)作為參考系,設置距離各邊的距離。默認值為100%
<number>
:設置距離各邊的絕對距離,單位固定為px
fill
:設置是否將九宮格里正中間的切片,應用到貼圖區中。默認值為禁用,即默認情況下九宮格中僅有8塊切片會應用到貼圖區中。
注意
當水平方向(left/right)的切片重疊時,會導致top、middle和bottom切片的尺寸為0;
當垂直方向(top/bottom)的切片重疊時,會導致left、middle和right切片的尺寸為0;
因此默認情況下border-image-slice: 100%
,所以top/right/bottom/left/middle的切片尺寸均為0,而4個角top-left/right和bottom-left/right切片的尺寸為整張圖片,因此最后結果僅看到邊框4個角有圖片,而4邊卻沒有顯示。
示意圖:
4條灰色線表示切割線,它們和圖片的4條邊框一起把圖片劃分為九宮格,得到以下9幅切片。
貼圖區(Border Image Area)切割/切片
相對目標元素和素材圖片而言,貼圖區由于無法直接觀察,導致比較難理解。
- 默認情況下貼圖區與目標元素完全重疊;
- 貼圖區同樣被劃分成9塊區域,分別對應素材圖片的9塊切片。默認情況下貼圖區中除middle區域外,其他區域的尺寸與目標元素的border box一致。
- 通過
border-image-width
可修改各區域的尺寸; 通過
border-image-outset
可修改貼圖區的尺寸。
border-image-outset: 12px;
- 屬性
border-image-width
作用:以九宮格的形式對貼圖區進行切片
語法:border-image-width: [<length> | <percentage> | <number> | auto]{1,4}
屬性值的順序和簡寫時語法擴展的規則與屬性border-image-slice
一致(top,right,bottom,left),而其含義為距離貼圖區各邊(top/right/bottom/left)多遠的位置上,畫一條與對應邊相互平衡的切割線。注意:切割線必須位于貼圖區所在面積內
<length>
:設置距離各邊的絕對距離,負數無效。
<percentage>
:以貼圖區的尺寸(寬、高)為參考系,設置距離各邊的距離
<number>
:以對應的border-width為參考系,設置距離各邊的距離。默認值為1
auto
:設置為與素材圖片中對應的切片一致
注意:若貼圖區水平方向(left/right)或垂直方向(top/bottom)的區域發生重疊,則會對其進行縮放直到不發生重疊為止。計算縮放因子的公式f = min(width/(left + right), height/(top + bottom))
,然后left/right/top/bottom4個區域則按縮放因子進行縮放操作。 屬性
border-image-outset
作用:擴大貼圖區所占的面積。
語法:border-image-ouset: [<length> | <number>]{1,4}
屬性值的順序和簡寫時語法擴展的規則與屬性border-image-width
一致(top,right,bottom,left),而其含義為將貼圖區各邊(top/right/bottom/left)向外擴展多大距離。
<length>
:設置距離各邊的絕對距離,負數無效。
<number>
:以對應的border-width為參考系,設置距離各邊的距離。默認值為0
注意
經過上述兩步"圖片切片"和"貼圖區切片"后,是時候將兩者糅合在一起了。具體邏輯如下: 合成過程中有兩點是至關重要的: 語法: 素材圖片原尺寸: 粵語的"一鋪搞定"其實就是一次完成全部工作的意思,上面關于border-image的屬性,要是每次都逐個設置那要敲多少次鍵盤啊。。。其實我們可以通過 粵語的"一鋪清袋"其實就是把之前的成果一次性歸零。當我們辛辛苦苦設置好border-image后,一個不小心又設置了border屬性,那么之前關于border-image的設置將全部失效。因此先設置border屬性,然后再設置border-image最為穩妥。 總算折騰出來了,累啊!!!起初以為花2個晚上就能理解好并記錄下來,誰知道理解就花了2晚,然后各種試驗。。。看來還是太高估了自己了:(不過不管如何,弄明白后還是覺得很爽的哦! CSS Backgrounds and Borders Module Level 3 4. Borders
通過border-image-outset
擴大貼圖區的面積時,若border-image-width
采用border-image-width
采用其他作屬性值時,只會看到圖片邊框向外移動而已。合成的法則
1.1. 將素材圖片各切片移至貼圖區中對應的區域;
1.2. top/bottom圖片切片的高度縮放至于對應的貼圖區域的高度一致,并以相同的縮放比來調整圖片切片的寬度;
1.3. left/right圖片切片的寬度縮放至于對應的貼圖區域的寬度一致,并以相同的縮放比來調整圖片切片的高度;
1.4. top-left/right和bottom-left/right圖片切片的寬度和高度則各自縮放至于對應的貼圖區域一致即可
2.1. 根據border-image-repeat
屬性值對切片尺寸進行調整。
3.1. 當border-image-repeat
屬性值為repeat時,切片位于對應貼圖區域的中央位置,否則則緊貼對應貼圖區域的左邊框。border-image-repeat
屬性值對切片進行復制、拉伸等平鋪操作,然后將貼圖區與目標元素所在的圖層進行合成即可!
border-image-repeat
相關。border-image-repeat
border-image-repeat: [stretch | repeat | round | space]{1,2}
第一個屬性值為水平方向的平鋪方式,第二個屬性值為垂直方向的平鋪方式。
stretch:拉伸圖片切片,默認值。
repeat:復制平鋪圖片切片(不保證每幅圖片切片副本恰好能完整顯示)。
round:根據貼圖區域尺寸調整圖片切片尺寸,然后復制平鋪圖片切片,從而保證每幅圖片切片副本恰好能完整顯示。
space:復制平鋪圖片切片,并通過調整圖片切片副本間的空白,從而保證每幅圖片切片副本恰好能完整顯示。(效果和flexbox中content-align設置為space-round差不多)
最終效果:
大家可以看到最終效果里面4個角落的切片均縮小了,而left和right則是拉伸,top和bottom則是復制平鋪。一鋪搞定&一鋪清袋
border-image
屬性一次搞定。
語法:border-image: <‘border-image-source’> || <‘border-image-slice’> [ / <‘border-image-width’> | / <‘border-image-width’>? / <‘border-image-outset’> ]? || <‘border-image-repeat’>
兼容性
總結
尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/5449717.html^_^肥仔John感謝
《圖解CSS3核心技術與案例實戰》——第3章 CSS3邊框
文章列表