圖片邊框

2018-02-24 15:42 更新

原文出處:http://www.w3cplus.com/css3/css-secrets/continuous-image-borders.html

問(wèn)題

有時(shí)候,我們想將一些圖案或圖片添加為邊框,而不是背景。比如,在下圖中所示的元素就擁有一個(gè)裝飾性的邊框,邊框內(nèi)是一個(gè)被限制在邊框區(qū)域的圖片。此外,我們還希望圖片可以覆蓋整個(gè)邊框區(qū)域。那么我們?cè)鯓邮褂?CSS 達(dá)到這一目的呢?

圖片邊框

圖注:圖片被用來(lái)裝飾各種高度的邊框

此時(shí),也許在你的內(nèi)心會(huì)響起一個(gè)響亮的聲音:“border-image,border-image,我們可以使用?border-image,它可以完美的解決這個(gè)問(wèn)題!”年輕人,做事不要太急躁。讓我們重新回憶一下?border-image?的解析機(jī)制:它實(shí)際上將背景分成了九塊,然后分別將各個(gè)塊作用到了元素的邊角上。下圖就是一個(gè)視覺(jué)原理圖。

圖片邊框

圖注:border-image?的快速入門。上面:分割后的圖片;虛線框內(nèi)的就是分割后的碎片;中間:border-image: 33.34% url(...) stretch;?下面:?border-image: 33.34% url(...) round;,在線示例鏈接

那我們是否可以將圖片切分成塊,然后使用?border-image?模擬出下圖這樣的效果呢?

圖片邊框

實(shí)際上,即使我們精確計(jì)算出了元素的尺寸和邊框?qū)挾?,仍然無(wú)法達(dá)到自動(dòng)適配多種尺寸的目的。問(wèn)題的核心就是,我們并不是讓邊角具有某種特定的圖形,而且即使添加上了圖形,當(dāng)元素尺寸變化時(shí),圖形也會(huì)發(fā)生形變。如果你稍微嘗試一下,就會(huì)理解使用border-image?是無(wú)法實(shí)現(xiàn)效果的,那么我們應(yīng)該怎么辦呢?

解決這個(gè)問(wèn)題最簡(jiǎn)單的方法就是使用兩個(gè) HTML 標(biāo)簽:一個(gè)標(biāo)簽使用目標(biāo)圖片作為北京,兩一個(gè)使用白色作為背景并覆蓋在前一個(gè)標(biāo)簽上面:

<div class="something-meaningful">
    <div>
        I have a nice stone art border,
        don’t I look pretty?
    </div>
</div>

.something-meaningful {
    background: url(stone-art.jpg);
    background-size: cover;
    padding: 1em;
}
.something-meaningful > div {
    background: white;
    padding: 1em;
}

這種方法確實(shí)實(shí)現(xiàn)了下圖的效果:

圖片邊框

但是它卻需要添加額外的 HTML 標(biāo)簽。這只能算是一種折中的辦法:它不僅僅混合了表現(xiàn)和樣式,而是在某些情況下必須修改 HTML 結(jié)構(gòu)。那么我們是否可以只用一層標(biāo)簽就實(shí)現(xiàn)這個(gè)效果呢?

解決方案

值得慶幸的是,CSS 的漸變以及在?Backgrounds & Borders Level 3?中擴(kuò)展后的?background?屬性可以幫助我們實(shí)現(xiàn)這一個(gè)效果,而且是只用一個(gè)標(biāo)簽。這種方法的核心就是使用純色覆蓋背景圖片。不過(guò),為了讓第二章圖片裝飾到邊框上,我們需要為backgroud-clip?屬性配置不同的屬性值。最后一件事就是讓最底下的圖層只有一種顏色,所以我們需要通過(guò) CSS 漸變模擬一個(gè)純白色背景。

我們最初實(shí)現(xiàn)這個(gè)方法的代碼就像下面一樣:

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
            url(stone-art.jpg);
background-size: cover;
background-clip: padding-box, border-box;

圖片邊框

圖注:第一次的嘗試非常接近理想效果。

正如上圖所示,效果非常接近我們的目標(biāo)了,唯一的不足是多了一些重復(fù)的部分。其中的原因就是?backgroud-origin?屬性的默認(rèn)值為?padding-box,因此,圖片會(huì)定位到內(nèi)邊距盒模型的左上角,剩余的部分就會(huì)不斷平鋪這一圖片。為了矯正這一效果,我們需要將?background-origin?的屬性值修改為?border-box

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
            url(stone-art.jpg);
background-size: cover;
background-clip: padding-box, border-box;
background-origin: border-box;

這些新屬性也可以統(tǒng)一使用?background?簡(jiǎn)寫語(yǔ)法來(lái)聲明,從而讓我們的代碼更加簡(jiǎn)潔優(yōu)雅:

padding: 1em;
border: 1em solid transparent;
background:
    linear-gradient(white, white) padding-box,
    url(stone-art.jpg) border-box 0 / cover;

當(dāng)然,我們也可以將這一技巧應(yīng)用到和漸變相關(guān)的背景圖案上。比如,看一看下面的這些代碼,我們可以用它來(lái)生成信封風(fēng)格的邊框:

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white) padding-box,
            repeating-linear-gradient(-45deg,
              red 0, red 12.5%,
              transparent 0, transparent 25%,
              #58a 0, #58a 37.5%,
              transparent 0, transparent 50%)
0 / 5em 5em;

最終結(jié)果如圖所示:

圖片邊框

圖注:我們實(shí)現(xiàn)的懷舊信封邊框

現(xiàn)在,你可以使用?background-size?隨意修改條紋的寬度,也可以使用?border?隨意修改邊框的寬度。不同于前一個(gè)示例,這種效果是可以使用?border-image?來(lái)實(shí)現(xiàn)的:

padding: 1em;
border: 16px solid transparent;
border-image: 16 repeating-linear-gradient(-45deg,
                   red 0, red 1em,
                   transparent 0, transparent 2em,
                   #58a 0, #58a 3em,
                   transparent 0, transparent 4em);

不過(guò),使用?border-image?會(huì)遇到幾個(gè)問(wèn)題:

  • 每次修改?border-width?的時(shí)候,同時(shí)需要修改?border-image-slice
  • 因?yàn)椴荒茉?border-image-slice?中使用類似?em?的單位,所以我們只能對(duì)邊框?qū)挾仁褂孟袼貑挝?/li>
  • 條紋的寬度需要硬編碼到顏色過(guò)渡點(diǎn)上,那么當(dāng)需求變化時(shí)就需要修改四個(gè)地方的代碼

這種技巧的另一種有趣應(yīng)用就是創(chuàng)建一個(gè)類似選區(qū)的邊框(marching ants borders)。選區(qū)型邊框(譯者:之所以稱之為選區(qū)型,是因?yàn)樾Ч浅n愃?ps 中選區(qū)邊框的效果,更容易理解)是虛線邊框,而且虛線是實(shí)時(shí)滾動(dòng)的,非常類似行進(jìn)中的螞蟻(當(dāng)然,這需要一定的想象力將虛線想象為螞蟻)。這在 GUI 中幾乎是不可想象的效果。圖像編輯軟件通常使用這種邊框來(lái)表示這是一塊被選中的區(qū)域,簡(jiǎn)稱選區(qū)。

圖片邊框

圖注:選區(qū)型邊框在 Adobe Photoshop 中被用來(lái)標(biāo)志被選中的地方

為了創(chuàng)建這種邊框,我們將要使用前面創(chuàng)建信封邊框的技巧。首先是將條紋更改為黑白兩色,并且將邊框調(diào)整為?1px?的寬度(你注意到現(xiàn)在條紋是怎樣變化為虛線邊框的了吧?),然后適當(dāng)修改一個(gè)?background-size,最后為?background-size?添加動(dòng)畫效果(從初始值增加到?100%):

@keyframes ants { to { background-position: 100% } }
.marching-ants {
    padding: 1em;
    border: 1px solid transparent;
    background:
        linear-gradient(white, white) padding-box,
        repeating-linear-gradient(-45deg,
          black 0, black 25%, white 0, white 50%
        ) 0 / .6em .6em;
    animation: ants 12s linear infinite;
}    

現(xiàn)在,你可以從下圖中看到一個(gè)靜態(tài)的效果。

圖片邊框

圖注:在紙上顯示選區(qū)型邊框是不可能的,可以訪問(wèn)在線示例進(jìn)行查看——非常有意思!

顯然,這種技巧不僅僅對(duì)選區(qū)型邊框有用,只需修改一下邊框顏色和虛線之間的間距,就可以用來(lái)創(chuàng)建各種自定義的虛線邊框。

目前,如果想要使用?border-image?屬性實(shí)現(xiàn)類似的效果,那么就只能使用?border-image-source?添加 GIF 來(lái)模擬了,詳情見(jiàn)?Marching ants animated selection rectangle in CSS。當(dāng)瀏覽器廣泛支持漸變效果之后,我們就可以用漸變來(lái)創(chuàng)建這種效果了,而且代碼會(huì)更加簡(jiǎn)練優(yōu)雅。

圖片邊框

圖注:頂部剪切過(guò)得邊框,用來(lái)模擬傳統(tǒng)書(shū)籍中的腳注

不過(guò),border-image?也是非常強(qiáng)大的屬性,甚至有時(shí)比漸變更強(qiáng)大。比如,假設(shè)我們需要一個(gè)裁剪過(guò)的頂部邊框,就像常見(jiàn)的腳注樣式。那么只需要使用?border-image和垂直漸變就可以實(shí)現(xiàn),其中裁剪的長(zhǎng)度可以硬編碼實(shí)現(xiàn)。邊框的寬度則有?border-width?來(lái)控制。代碼就像是這樣:

border-top: .2em solid transparent;
border-image: 100% 0 0 linear-gradient( 90deg, 
            padding-top: 1em;
            currentColor 4em,
transparent 0);

最終結(jié)果如上圖所示。此外,因?yàn)槲覀冊(cè)谶@里使用?em?單位,所以整體效果就能隨字體大小而變化;因?yàn)槭褂昧?code>currentColor,所以它也可以隨字體顏色而改變顏色。

總結(jié)

在CSS2.1的時(shí)代要實(shí)現(xiàn)圖片邊框效果是一種奢侈的想法,但在CSS3中雖然增加了border-image屬性實(shí)現(xiàn)圖片邊框,但依舊受到諸多的限制性,其中最大的限制就是瀏覽器對(duì)其支持度。在這一節(jié)中,我們介紹了使用多背景,以及配合background-clip、background-origin屬性模擬出圖片邊框效果。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)