深刻淺出CSS3:background-clip,background-origin和border-image教程

注: 做者 hh54188 , 轉自 http://www.cnblogs.com/hh54188/archive/2011/01/12/1929061.htmlcss

有一篇來自懌飛博客的 background-clip與background-origin 的一則運用,可是幾年前的文章,其中的部份內容已經不適用於如今的標準了。html

一.從傳統的多圖像背景技術談起前端

在CSS3以前,2.0也好,2.1也罷。要想給一個塊級元素添加圓角或是陰影,又或是一個比較複雜的背景圖像(好比多邊形,多紋路)都是至關困難的一件事。在這裏先列舉兩個例子,有關如何組織複雜的背景和陰影效果。一方面是爲了照顧一些入門web的朋友,另外一方面也爲了和後面這兩個技術的應用作一個對比,作一個承上啓下的做用。熟練的朋友能夠跳過這一節,直接從下一節開始閱讀css3

 1.請你們先看這樣一個效果:注意文字的背景,你們有沒有主意如何實現?一個最普通不過的想法是,我就按我須要的文字的長度,用photoshop作一個包含左右半圓形狀的完整一體圖片。但問題是,若是我文字的長度須要更改,變得更長或者更短時應該怎麼辦?爲了實現這個效果,一般咱們只須要三幅圖:。具體原理如圖所示:web

咱們在原來惟一一個用來存放文字的div中,又插入了三個 div:div#left,div#center,div#right。其中#left和#right分別用來存放半圓形的左右邊緣且固定寬度,而中間 的#center用來存放文字,背景採用repeat-x定位,且不定位寬度,再經過其它css設置讓它能收縮緊貼內容區域(content),這樣就能 隨着文字的長短而自如伸縮了。最後經過position或display屬性讓#lef,#center,#right實現無縫隙的拼接,同時讓最外層的 div#content也收縮緊貼它包裹的三個div,而後——大功告成。chrome

這個技術的關鍵在於如何讓存放文字的div#center的伸縮引發外部整個div#content的的伸縮,且保持#left,#center和#right的佈局不被破壞……這樣就完成了自動伸縮功能。精簡的代碼以下: 瀏覽器

<div class=」content」 style=」height:32px;」> /*這個是伸縮的*/
<div class=」left」 style」width:15px; height:32px;」></div>
   <div class=」center」 style=」height:32px;」>這裏存放文字內容</div>/*這個也是能夠伸縮的*/
<div class=」right」 style=」width:15px; height:32px;」></div>
</div>

   但至於如何才能使最外層的容器內收縮緊貼內部div,使div#center自動伸縮,你們能夠百度,也能夠參照《深刻理解box盒子模型》框架

 

例子2.咱們先看一個jQuery插件fancybox的陰影效果:工具

這是模仿MacOS的效果的一個插件,因爲整張圖片太大,我只是截取了一個角下來。你們須要注意的重點是白色邊框的外邊緣的陰影效果(可能不是很明顯)——參照上面的例子,您以爲陰影效果是如何實現的?佈局

  對,仍是用九個盒子拼成的,一個盒子裝的是中間的照片,另外八個盒子分別裝東,西,南,北,東南,西南,東北,西八個方向的陰影。這個不用畫圖,你們應該能夠想象出來吧。但這個例子又有不一樣——這 一次有九個盒子,要是按上一個例子同樣,在一容中放九個盒子,再經過浮動,定位屬性等來實現他們無縫拼接,也會是至關繁瑣的一事。由於要考慮每個盒子周 圍的盒子在本身伸縮時也能適當的作一些調整,不至於出現錯位和縫隙。因此的此次的作法是將放陰影的八個盒子用絕對定位固定在中間的盒子的八個方向上,這樣 以中心盒子爲中心,不管它怎麼放大仍是縮小,周圍八個盒子都死死的附屬着它,就不再用考慮本身周圍的盒子有錯位之類的問題。圖例以下:

 

再看看實際的定位是否是這樣定位的呢,看看從firebug下的截圖:

再看看其中一個fancybox-bg-n的具體css:

三 、background-clip,background-origin入門

 

相信當您閱讀完這一節的內容後,你就會開始學會如何用新技術擺脫那些陳舊繁瑣的步有三個屬性來就不復雜的效果了。

在開始以前,先作幾點說明,請看:

首先咱們要引入幾個概念:內容邊緣(content edge),內邊距邊緣(padding edge),邊框邊緣(border edge),外邊距邊緣(margin edge)。爲了理解,咱們能夠把內邊距,邊框,外邊距當作一個環形的容器,而且每一個環形容器都只有兩條邊,一條衝內,一條衝外(內和外也是相對的,比如外邊距的外邊就是邊框的內邊),因而咱們把衝外(outer)的那條邊稱爲這個環形的邊緣(edge)。固然由於內容區域是「實心」的,因此不存在內外的問題。  

  origin的翻譯過來時原始的意 思。顧名思義,因此background-origin是用來決定圖片的原始起始位置。它有三個可選值content-box,padding- box,border-box(background-origin若是寫在css中只有Opera瀏覽器能夠識別,若是但願在火狐或者chrome或 Safari中使用,要使用它們瀏覽器的私有屬性-moz-background-origin(Firefox),-webkit-background-origin(chrome,safari),而且對應的值是content,padding,border,省略了-box),即你能夠選擇背景圖片是從內容區域開始顯示,仍是內邊距,仍是邊框。

  舉個例子,咱們有一個div,關鍵在定位它的背景圖片,爲了讓演示的效果更明顯,咱們讓它從左上角開始定位,position:left top而且no-repeat。而且內容區於圖片大小一致,邊框和內邊距都設置爲30像素寬。OK,

在沒有加入background-origin以前的代碼爲:

複製代碼
.border
{
background:url("images/qwqw_s.jpg");
background-repeat:no-repeat;
background-position:left top;

border-width:30px;
border-style:dashed;
border-color:red;

width:180px;
height:254px;
padding:30px;
margin:0 auto;
}
複製代碼

設置background-origin以後的效果圖:

由於是在火狐下作的測試,因此-moz-background-origin代替background-origin,相應的屬性因此也去掉了-box  

  效果和做用已經一目瞭然了:咱們看 到,當background-origin的值爲content-box時,首先會讓背景圖片的左上角和內容邊緣左上角對齊,padding-box時, 則會讓背景圖片的左上角和內邊距的左上角對齊。以此類推。可見background-origin的值的確是決定背景圖片開始從哪一個區域開始顯示。但話說 回來,若是我沒有設置任何的background-origin屬性的話,它默認的起始位置在哪呢?這裏就不演示了,但有必要記住——padding。

  有一點要十分的注意:若是背景不是no-repeat的話,這個屬性是無效的。它會從border-box區域開始顯示,這一點很重要。

  background-origin屬性就先介紹到這裏。應該不難吧。下面繼續介紹background-clip。之因此沒有把這兩個屬性分爲兩節分別介紹,由於實戰的經驗告訴我這兩個屬性應該是相互搭配才能相得益彰。

   clip原意爲裁剪,截取。一樣顧名思義,background-origin的做用爲將背景圖片作適當的裁剪,以適應須要。固然這裏並非真正意義上 的把圖片給裁剪了,而是根據屬性值。把圖片的某些部位作適當的隱蔽。background-clip與origin的可選擇同樣,也是有content- box,padding-box,border-box(要注意在火狐和Chrome和Safari中,須要使用私有屬性,加上-mox-和 -webkit-,這裏就不贅述了,參考解釋background-clip的內容)。怎樣個剪裁法呢。根據你設置的盒子部位,那麼圖片在這個部位的外邊 緣之外的部分都會不可見。舉個具體例子,圖片起始位置和上面的例子同樣,好比是從border-box開始,但我background-clip設置的值 是content-box,在content以外,也就是border-box內,padding-box內的圖片內容通通不可見。儘管你是讓圖片從邊框 開始顯示。

實例以下

 

 
.border
{
background:url("images/qwqw_s.jpg") black;
background-repeat:no-repeat;
background-position:left top;

border-width:30px;
border-style:dashed;
border-color:red;

background-clip: content-box;
background-origin: border-box;

-moz-background-clip: content;
-moz-background-origin: border;

-webkit-background-clip: content;
-webkit-background-origin: border;

width:180px;
height:254px;
padding:30px;
margin:0 auto;
}
 

 

正如以上所說,咱們能夠看見雖然圖片是從頂着邊框的左上角進行定位,可是裁剪屬性background-clip的屬性是設置爲content-box,因此只有content區域的內容看得見,也就是隻要是在content以外的圖片內容都被隱蔽掉了。

  我之因此要在不一樣瀏覽器下進行測試( Firefox/3.6.3,Google:7.0.517.24, Opera/9.80,Safari:5.0.1),答案也在圖上,咱們看到在火狐下的結果和其餘瀏覽器結果居然不同。明明background-clip設置的屬性是content-box,但卻沒有圖片的任何部位被屏蔽。我想說的是:在 火狐下-moz-background-clip屬性是沒有content這一值的(可是padding和border仍是有的),在firebug中可 以看到,-moz-background-clip的值直接是border,當你強行改成content時,這條屬性會直接從bug中消失。固然這只是在 3.6.3版本下的結果,至於在4.0版本中表現如何(雖然只是beta版)。能夠自行測試

四.實戰

  在學習了基本background-clip和background-origin用法和原理以後,咱們將經過操做一個實際的例子,來加深咱們的學習:

                  

這個圓角背景是由三部分組成:(呃, 實際上是從Webqq2.0網站上撬下來的,就是上面的工具條……可是做爲教學用,應該無傷大雅吧……),思路和開篇的那個黑背景製做過程是同樣的,左右固 定,中間窄的repeat-x。可是這會不用插入三個div,又要設置float,又要設置display考慮佈局那麼麻煩。

步驟一:

先搭建一個框架出來,給一個佈局。不着急把圖片插入進去。主意看如下代碼,有幾點須要說明的:由於僅需在盒子左右兩側插入背景,且剛好爲左右要插入 圖片的寬度(若是不剛好爲那麼寬呢?那麼不會成功的,由於css3中尚未屬性能控制圖片在邊框中的定位,你會想不是有background- position屬性嗎?要注意那個是控制圖片在整個盒子中的定位。仍是不信的話你能夠親自試試);還有就是padding的值也是能夠不用設置的,是爲 了與上面的例子盡力保持一致,方便你們對比學習 margin也是爲了讓盒子居中而已,能夠忽略;最後border-style和border-color也是方便你們理解佈局才添加上去的。

複製代碼
.border
{
background:black;

border-width:0 11px; /*爲了要適應左右兩個圖片的寬度,且只有左右須要,上下的寬度就不須要了*/
border-style:dashed;
border-color:Red;


width:180px;
height:90px; /*由於要適應圖片,因此寬度改小一點*/
padding:30px; /*其實Padding也是能夠不須要的,爲了方便說明一些問題,仍是保留*/

margin:0 auto;
}
複製代碼

步驟二:

這一步很簡單,就是把中間須要x軸重複的圖片添加上去,而且把黑色背景去掉

複製代碼
.border
{
background:url("images/tool-bar/bg_b_c.png");/*添加背景*/
background-repeat:repeat-x;
background-position:center;

border-width:0 11px; /*爲了要適應左右兩個圖片的寬度,且只有左右須要,上下的寬度就不須要了*/
border-style:dashed;
border-color:Red;


width:180px;
height:90px; /*由於要適應圖片,因此寬度改小一點*/
padding:30px; /*其實Padding也是能夠不須要的,爲了方便說明一些問題,仍是保留*/

margin:0 auto;
}
複製代碼

步驟三:

這步也很簡單,就是把中間重複的背景的左右兩端去掉,爲了方便咱們下一步在左右邊框中插入須要的圖片。注意這裏的

 -moz-background-origin的content屬性是無效的,實際上這裏的值是padding。正如在上一節的最後說道,在火狐 中是沒有content這個屬性的。若是有朋友想要copy這段代碼,記得根據瀏覽器版本作相應的修改,把origin的值content改成 padding,或者把盒子的padding去掉。

複製代碼
.border
{
background:url("images/tool-bar/bg_b_c.png");
background-repeat:repeat-x;
background-position:center;

-moz-background-clip: padding; 
-moz-background-origin: content; /*firefox中background-origin沒有content這個屬性,其實如今的值是padding。在其餘瀏覽器中是有效的*/

border-width:0 11px; /*爲了要適應左右兩個圖片的寬度,且只有左右須要,上下的寬度就不須要了*/
border-style:dashed;
border-color:Red;


width:180px;
height:90px; /*由於要適應圖片,因此寬度改小一點*/
padding:30px; /*其實Padding也是能夠不須要的,爲了方便說明一些問題,仍是保留*/

margin:0 auto;
}
複製代碼

步驟四:

這一步仍是很簡單,插入邊框的左右兩張圖片,並設置好position,repeat,clip等值。注意當存在多個圖片時,設置值的格式,用逗號隔開。

複製代碼
.border
{
background:url("images/tool-bar/bg_b_c.png"),
              url("images/tool-bar/bg_b_l.png"),
              url("images/tool-bar/bg_b_r.png");
background-repeat:repeat-x,no-repeat,no-repeat;
background-position:center,left center, right center;

-moz-background-clip: padding,border,border; 
-moz-background-origin: content,border,border;

border-width:0 11px; /*爲了要適應左右兩個圖片的寬度,且只有左右須要,上下的寬度就不須要了*/
border-style:dashed;
border-color:Red;

width:180px;
height:90px; /*由於要適應圖片,因此寬度改小一點*/
padding:30px; /*其實Padding也是能夠不須要的,爲了方便說明一些問題,仍是保留*/

margin:0 auto;
}
 
複製代碼

 

重要提示!寫到這一步,能夠從上圖看到已經快大功告成了。把左右的紅色邊框去掉就能夠了——那麼把 border-color改成none或是直接去掉這句話?不行的。若是不設置顏色的話邊框就會變成黑色,由於邊框有樣式,並且樣式還有11px寬啊,所 以會用默認的黑色來填充。如今你可能又會以爲是邊框樣式border-style的問題,那我們把樣式去掉,把寬度保留?也不行,由於若是沒有樣式寬度是 無效的,結果會以下圖(咱們能夠從firebug中看到邊框的寬度是0,雖然仍然保留border-width)。因此border- style,border-color,border-width缺一不可!這一點要十分注意!

 

步驟五:

綜上所述,你可能會以爲既不能改border-style又不能改border-color豈不是沒轍了?正確答案是——仍是修改border-color,別忘了,color還有一個值transparent,透明。顏色還讓它在,但只要人們看不見就好了。咱們實現它:

複製代碼
.button
{
background:url("images/Fancybox/fancy_title_main.png"),
              url("images/Fancybox/fancy_title_left.png"),
              url("images/Fancybox/fancy_title_right.png");
background-repeat:repeat-x,no-repeat,no-repeat;
background-position:center,left,right;

background-clip: padding-box,border-box,border-box;
background-origin:padding-box,border-box,border-box;

-moz-background-clip: padding,border,border;
-moz-background-origin: content,border,border;

border-width:0 15px;
border-style:dashed;
border-color:transparent;

width:80px;
height:32px;
}
複製代碼

 

OK,完全大功告成,很簡單不是嗎。

四.border-image

  寫到這裏我發現文章的戰線貌似拉的有點長了。因此我打算border-image在這裏只是做爲附加內容說明,並不會深究,儘量簡扼一些。開始(因此廢話也簡扼一些……):

  border-image是定位在邊框上的圖片——那不是和把background-origin屬性設爲border差很少一個意思?是的,的確有這層含義。但在接下來的說明和例子中,你將看到它的便利之處。

  這個屬性說到底仍是在搗鼓一張圖片。先直接看一張說明圖片:

      

  草圖左邊是舉例border-image所使用的圖片,右邊的草圖是比喻一個盒子。border- image有兩個值須要設定,頭一個是切割屬性(border-image-slice),最多有四個值能夠設置,命名規則和margin、 padding都是一致的,順序上右下左。四個值對應左邊草圖的不一樣區域的寬度,一樣上右下左的順序,也就是2,6,8,4區域的寬度(四、6區域爲橫向 長度,2,8區域爲叢向長度)。從圖中可知,由於是交集的緣故,只要定義好這四塊的寬度,一、三、九、7區域的長寬也就隨之肯定。在映射到盒子模型上,從 1到9(除5)正好連成盒子的邊框區域,這樣盒子的邊框圖片就有着落了。

  但還有一個疑問。若是實際圖片真如左邊草圖那麼小,而實際盒子真有右邊草圖的那麼大,那二、六、八、4區 域的圖片可能就不夠用呀?問得好,因此border-image還提供一種機制來處理這個問題——圖片重複屬性(border-image- repeat),也叫拉伸值(stretch value)。有四個值能夠選擇:stretch(拉伸且默認)、repeat(重複)、round(平鋪)。是否是聽着很耳熟,對,和電腦壁紙的位置屬 性是同樣的。對每一張border-image最多能夠設置兩個拉伸屬性如round round。前一個針對圖片側邊(除5區域之外),後一個針對中間部分,即5區域。若是隻有一個值的話,則認爲因此區域都按照此值佈置。若無設置此屬性, 則按默認值拉伸(stretch)來佈置image。

因此對應上圖,我們再來一個例子,就一目瞭然了:

回到上節的那個例子,這回咱們只須要兩張圖片:

能夠看出後面那種圖就是左右兩側拼接而成的,這回我們用border-image屬性完成上面的一樣效果,很簡單,直接看CSS代碼:

 

 
.border
{
background:url("images/tool-bar/bg_b_c.png");
background-repeat:repeat-x;
background-position:center;

-moz-background-clip: padding;
-moz-background-origin: padding;

-moz-border-image:url("images/bg_b_l_r.png") 0 11; 

border-width:0 11px; /*爲了要適應左右兩個圖片的寬度,且只有左右須要,上下的寬度就不須要了*/

width:180px;
height:90px; /*由於要適應圖片,因此寬度改小一點*/
padding:0 30px; /*其實Padding也是能夠不須要的,爲了方便說明一些問題,仍是保留*/

margin:0 auto;
}
 

仍是要作幾點說明。由於在這個例子中咱們只須要左右側有圖片,因此切割屬性只要將圖片左右切割開去能夠了:0 11。在上一節最後一步的重要提示中,我反覆強調border-style,border-color,border-width缺一不可。但在這裏只需 要一個border-width就足夠了!這就是它的便利之處。但在使用時要記得不一樣瀏覽器之間的差別,判斷是否要使用-moz-或-webkit-或 -o-前綴。

再給你們看幾個驚豔的例子:

----->

 

還有小的:------->

 

 五.再嘮叨幾句

本身一旦遇到了不少前端的問題都只能google國外的文章,或是去stack overflow(但真的頗有效果,回覆的速度快,集思廣益,並且句句錙銖,向你們強烈推薦)。

相關文章
相關標籤/搜索