CSS魔法堂:重拾Border之——圖片做邊框

前言

 當CSS3推出border-radius屬性時咱們是那麼欣喜若狂啊,一想到終於不用再添加額外元素來模擬圓角了,但發現border-radius還分水平半徑和垂直半徑,而後又發現border-top-left/right-radius的水平半徑之和大於元素寬度時,實際值會按比例分配元素寬度時,不由會問"我真的懂border嗎?"。本系列將稍微深刻探討一下那個貌似沒什麼好玩的border!
《CSS魔法堂:重拾Border之——解構Border》
《CSS魔法堂:重拾Border之——圖片做邊框》
《CSS魔法堂:重拾Border之——不只僅是圓角》
《CSS魔法堂:重拾Border之——更廣闊的遐想》css

解構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,那麼先要理解它由那幾類對象組成,對象間的關係和組合規則。html

3個和尚有水喝

  1. 目標元素自己(即上面的div元素)
  2. 用做邊框素材的圖片(即上面的border.png)
  3. 貼圖區(Border Image Area)

引入圖層概念

 用過PS或Flash的同窗應該都清楚圖層的概念吧,反正我是如今才理解圖層的:(
目標元素和貼圖區分別位於兩個圖層,而且貼圖區所在的圖層位於目標元素所在的圖層之上,而素材圖片經切割後將在貼圖區圖層上做後期處理,最後做圖層合成處理。
 重申3點css3

  1. 目標元素和素材的圖片分別在各自獨立的圖層上繪製;
  2. 圖片會通過切割後,按規則在所屬圖層上的貼圖區內做定位和平鋪處理;
  3. 圖片所屬圖層在目標元素所在圖層之上。

透過屬性看本質

 在理解border-image的組成和總體處理流程後,咱們先經過屬性來認識與圖片和貼圖區密切相關的知識——圖片切割/切片貼圖區切割/切片flex

圖片切割/切片

  1. 屬性border-image-source
    做用:引入用做邊框素材的圖片資源
    語法:border-image-source:url("image url")
    url入參爲圖片路徑,能夠是HTTP或HTTPS Scheme URI下的絕對或相對路徑,或採用Data Scheme URI。
  2. 屬性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邊卻沒有顯示。flexbox

示意圖:

4條灰色線表示切割線,它們和圖片的4條邊框一塊兒把圖片劃分爲九宮格,獲得如下9幅切片。
url

貼圖區(Border Image Area)切割/切片

 相對目標元素和素材圖片而言,貼圖區因爲沒法直接觀察,致使比較難理解。spa

  1. 默認狀況下貼圖區與目標元素徹底重疊;code

  2. 貼圖區一樣被劃分紅9塊區域,分別對應素材圖片的9塊切片。默認狀況下貼圖區中除middle區域外,其餘區域的尺寸與目標元素的border box一致。
    htm

  3. 經過border-image-width可修改各區域的尺寸;對象

  4. 經過border-image-outset可修改貼圖區的尺寸。

    border-image-outset: 12px;
  5. 屬性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個區域則按縮放因子進行縮放操做。

  6. 屬性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-outset擴大貼圖區的面積時,若border-image-width採用 做屬性值,則同時擴大除middle區域外其餘區域的尺寸;當 border-image-width採用其餘做屬性值時,只會看到圖片邊框向外移動而已。

合成的法則

 通過上述兩步"圖片切片"和"貼圖區切片"後,是時候將二者糅合在一塊兒了。具體邏輯以下:

  1. 初次調整圖片切片尺寸
    1.1. 將素材圖片各切片移至貼圖區中對應的區域;
    1.2. top/bottom圖片切片的高度縮放至於對應的貼圖區域的高度一致,並以相同的縮放比來調整圖片切片的寬度;
    1.3. left/right圖片切片的寬度縮放至於對應的貼圖區域的寬度一致,並以相同的縮放比來調整圖片切片的高度;
    1.4. top-left/right和bottom-left/right圖片切片的寬度和高度則各自縮放至於對應的貼圖區域一致便可
  2. 深度調整圖片切片尺寸
    2.1. 根據border-image-repeat屬性值對切片尺寸進行調整。
  3. 定位切片
    3.1. 當border-image-repeat屬性值爲repeat時,切片位於對應貼圖區域的中央位置,不然則緊貼對應貼圖區域的左邊框。
  4. 3秒の合體:),即根據border-image-repeat屬性值對切片進行復制、拉伸等平鋪操做,而後將貼圖區與目標元素所在的圖層進行合成便可!

 合成過程當中有兩點是相當重要的:

  1. "初次調整圖片切片尺寸"是基礎,並且要注意的是,是以相同的縮放比來調整圖片,而不是直接讓圖片切片的尺寸與對應的貼圖區域尺寸一致;
  2. "深度調整圖片切片尺寸"、"定位切片"和平鋪方式均與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: <‘border-image-source’> || <‘border-image-slice’> [ / <‘border-image-width’> | / <‘border-image-width’>? / <‘border-image-outset’> ]? || <‘border-image-repeat’>

 粵語的"一鋪清袋"其實就是把以前的成果一次性歸零。當咱們辛辛苦苦設置好border-image後,一個不當心又設置了border屬性,那麼以前關於border-image的設置將所有失效。所以先設置border屬性,而後再設置border-image最爲穩妥。

兼容性

總結

 總算折騰出來了,累啊!!!起初覺得花2個晚上就能理解好並記錄下來,誰知道理解就花了2晚,而後各類試驗。。。看來仍是過高估了本身了:(不過無論如何,弄明白後仍是以爲很爽的哦!
 尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/5449717.html_肥仔John

感謝

CSS Backgrounds and Borders Module Level 3 4. Borders 《圖解CSS3核心技術與案例實戰》——第3章 CSS3邊框

相關文章
相關標籤/搜索