CSS之背景與邊框

所有圖都在body背景設置為green下的截圖,請不要把最外層的綠色當成邊框

半透明邊框

如果我們想給一個容器設置一層白色背景和一道半透明的白色邊框,使容器后面的容器背景透上來,一般我們會這樣子嘗試:

border: 10px solid hsla(0, 0%, 100%, .5);background: white;

顯示結果如下:


Paste_Image.png

你會發現邊框不知道那里去了,這是為何,還有什么辦法?

  • 原因:其實我們的邊框是存在的,只是背景會侵透到邊框,而上層我們設置的也是白色實線半透明邊框,故看上去好像邊框不見了,可以換個虛線邊框加以驗證:


    Paste_Image.png

    這個表現即是CSS2的背景工作原理,我們只能接受它。

  • 解決方法:好在CSSb3可以通過background-clip屬性來調整背景范圍,默認值為border-box,意味著背景會侵透到邊框的外沿框,我們只要把值設置為padding-box,背景就會被內邊距的外沿剪切掉

border: 10px solid hsla(0, 0%, 100%, .5);background: white;background-clip: padding-box;
Paste_Image.png

這樣就達到我們預想的效果。
注:IE8以下需要使用濾鏡來達到半透明效果,或者準備一張半透明的圖片充當背景。

多重邊框

如何實現多重邊框,或許你會想到使用多個元素來模擬多重邊框,不過這樣子會需要額外的元素來實現,有沒有其他辦法叻?

解決方法-box-shadow

box-shadow即投影,通過設置兩個偏移,一個模糊量值,一個擴張半徑來控制投影。box-shadow: 0 0 0 10px #655 只設置一個10px的擴張半徑來模擬邊框:

Paste_Image.png

它支持逗號分隔,來創建多個投影,因此我們可以在加上一條邊框:

background-color: yellowgreen;
box-shadow: 0 0 0 10px #655, 0 0 0 20px deeppink;

效果如下:

Paste_Image.png
  • 投影跟邊框不完全一致,投影不影響布局,也不受box-sizing屬性的控制。投影占據的空間需要通過設置margin||padding騰出來。
  • 投影不會響應鼠標事件,為了解決這問題,可以通過給投影添加關鍵字inset,控制向元素內投影,對應的需要padding提供足夠的空間
box-shadow: 0 0 0 10px #655 inset,
              0 0 0 20px deeppink inset, 
              2px 2px 5px 5px rgba(0, 0, 0, 0.6);

效果如下:

Paste_Image.png

注意:投影是按照順序層層疊加,第一層位于最頂層

解決方案二-outline

如果只需要實現二層邊框,可以使用outline來實現,并且這種方法可以實現不同樣式的邊框,box-shadow只能實現實線邊框,如果要實現虛線就不行了。

border: 10px solid #655;
outline:10px solid deeppink;

效果如下:

Paste_Image.png

通過設置outline-offset可以設置outline(描邊)與border(邊框)之間的間隔

border: 10px solid #655;
outline:10px solid deeppink;
outline-offset: 10px;
Paste_Image.png

注意:- outline方式只能實現雙重邊框,如果要實現多重只能選擇box-shadow方式

  • 如果通過border-radius設置了圓角,outline并不會貼這邊框,還是直角的。
Paste_Image.png

明顯看到了邊框與描邊四角之間的空隙

靈活的背景定位

如何實現相對容器某個角對背景圖片做偏移定位?
CSS2只能設置背景圖片相對于左上角進行偏移或者固定在其他三個角,那如何讓背景圖片相對某個角留出一定的空隙叻?
CSS2要實現只能計算背景圖片距離左上角的偏移來實現,如果容器尺寸不固定,這樣的方法就失效了。

解決方法-background-position擴展

background: url(img/3_0.png) no-repeat #58a;
background-position: right 20px bottom 20px;

只需在偏移量之前設置指定關鍵字,效果如下:

Paste_Image.png

背景圖距離右下各20px
注:老版瀏覽器不支持擴展的話,背景圖片會顯示在左上角,所以需要設置background:url(img/3-0.png) no-repeat right bottom來實現回退方案。

解決方法-background-origin

如何設置偏移量與內邊距一致?
用上面的方法:

pading: 10px;
background: url(img/3_0.png) no-repeat #58a;
background-position: right 10px bottom 10px;

這樣可以實現,不過在修改padding之后,其他幾處的偏移量也需要修改。
有方法實現偏移跟著內邊距變化嗎?
首先我們需要確認background-position設置的偏移是相對于那個左上角,每個元素都有三個矩形,border(邊框的外沿框),padding(內邊距的外沿框),content(內容區的外沿框)?
默認情況下,偏移是以padding為準的,在CSS2是不能修改的,CSS3中我們可以通過background-origin來改變這種行為,通過變更這個屬性值可以設置相對于那個邊框進行偏移。

padding:10px;
background: url(img/3_0.png) no-repeat #58a;
background-position: right 10px bottom 10px;
background-origin: content-box;

效果如下:

Paste_Image.png

距離右下角20px,10px是padding值,10px是偏移量

解決方案-calc()方案

background: url(img/3_0.png) no-repeat #58a;
background-position: calc(100% - 20px) calc(100% - 20px);

效果如下:

Paste_Image.png

是不是跟上一個一樣,不過這個是相對于padding外沿框的偏移
注意:calc函數內部的 - + 運算符左右都需要一個空格,否則是解析出錯。

邊框內圓角

想想如何實現一下效果:

Paste_Image.png

一個容器有內側圓角,但是邊框或者描邊是直角

解決方法-多元素

<style>
.container{ 
    padding: 1em; background: red; 
} 
.container > div {
    padding: .8em; 
    background: tan; 
    border-radius: .4em; 
}
</style>
<div class='container'> 
    <div> </div>
</div>

效果如下:

Paste_Image.png

這個方法需要兩個元素,是否可以通過一個元素實現叻?

解決方法-box-shadow&outline

上一小節得知,outline描邊并不會受到border-radius的影響而表現為直角。box-shadow會受到border-radius的影響而表現為圓角。
所以本方法即用陰影去填充描邊已邊框之間的空隙

padding: 1em;
border-radius: .8em;
box-shadow: 0 0 0 .4em #655;
outline: .4em solid #655;

效果如下:

Paste_Image.png

成功實現
考慮下陰影需要設置為多大才能剛好填充空隙叻?

由勾股定律得知陰影的擴張值應該為 (a^2 + b^2 開根)- 圓角圓心到邊框的距離,當直角兩邊相等時,這個值為(2a^2開根)-a。

因為所以得出結論:要覆蓋掉描邊與邊框之間的空隙,陰影的值需要大于某個值,如果圓角兩邊相等,這個值小于0.4, 為了好記,避免每次都需要計算,可以把這個值設定為圓角半徑的一半。但是這個值不能沒有上限,當值超過描邊的寬度時候,就會出現以下情況:

border-radius: .8em;
box-shadow: 0 0 0 .5em #655;
outline: .4em solid #655;
Paste_Image.png

條紋背景

網頁中我們經常使用條紋背景圖案,通常我們的解決方法是創建一個單獨的圖片。但是它并不是最理想的,每次調整都需要圖像編輯器來進行修改圖片。如何使用CSS創建條紋背景叻?

解決方法-linear-gradient

水平條紋
background: linear-gradient(#fb3, #58a);
Paste_Image.png

可以看到實現的是一條垂直方向上的顏色漸變背景。通過調整色標來對漸變區域進行調整

background: linear-gradient(#fb3 30%, #58a 70%);
Paste_Image.png

可以看到背景只有中間40%的區域是漸變,上下兩邊各30%都是純色。
如果把色標重合在一起也就是設置為50%,有何效果?

Paste_Image.png

沒錯,就是兩條具大的條紋出現了.

漸變是由代碼生成的圖片,可以像對待圖片一樣對待漸變,通過設置background-size可調整漸變圖案的尺寸

background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
Paste_Image.png

因為默認背景圖案會進行平鋪,所以得到了如上兩色的條紋背景。如果想實現不等寬條紋,只需要調整色標的位置值

background: linear-gradient(#fb3 30%, #58a 30%);
background-size: 100% 30px;

如果一個色標值比之前設置的色標值都小,該色標值會設置成前面所有色標值中的最大值,所以可這樣設置

background: linear-gradient(#fb3 30%, #58a 0);
background-size: 100% 30px;
Paste_Image.png

兩種都將得到上圖,因為后一種只需修改一個地方。所以也算是寫代碼的捷徑吧。
此外還可以設置超過兩種顏色的條紋,以三色為例

background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 45px;

效果如下:

Paste_Image.png
垂直條紋

實現了水平條紋,垂直條紋如何實現叻?
垂直條紋只需要在開頭添加一個額外的參數來指定漸變方向,默認值是to bottom,我們只需要設置為 to right即可

background: linear-gradient(to right, 
                            #fb3 25%, #58a 0, 
                            #58a 50%, yellowgreen 0, 
                            yellowgreen 75%, black 0);
                            background-size: 60px 100%;

效果如下:

Paste_Image.png
斜向條紋

實現了水平與垂直條紋,順下想,如果實現一個斜向的條紋叻?
比如斜向45°
嘗試如下實現方式:

background: linear-gradient(45deg, #fb3 50%, #58a 0);
background-size: 30px 30px;
Paste_Image.png

失敗了,這樣只是把背景圖案中每個貼片旋轉了45°,根據用圖片實現斜向條紋的經驗,我們需要在每個貼片中包含四條條紋才能做到無縫拼接,在次嘗試如下方式:

background: linear-gradient(45deg, 
                            #fb3 25%, #58a 0, 
                            #58a 50%, #fb3 0, 
                            #fb3 75%, #58a 0);
background-size: 30px 30px;
Paste_Image.png

成功拼接成了斜向的條紋圖案,不過變成四條條紋之后對應的每條條紋的寬度變窄了,如何才能擴大到指定寬度的條紋圖案叻?
根據勾股定理,當設置背景尺寸為30px時,條紋的寬度為15/(2開根),約為10.6px。所以通過增加背景尺寸可以增加條紋寬度,這個值大約為42.4大小的時候得到的寬度近似為15px。

background: linear-gradient(45deg, 
                            #fb3 25%, #58a 0, 
                            #58a 50%, #fb3 0, 
                            #fb3 75%, #58a 0);
background-size: 42.426406871px 42.426406871px;
Paste_Image.png

得到了如上背景,不過上面的方法得到的也只是近似為指定寬度的條紋。有沒有更好的方法叻?

更好的斜向條紋

之前的斜向條紋只能在斜向45°,如果要實現其他角度的時候,之前的方法就顯得不好了,其實linear-gradientradial-gradient還各有一個循環式加強版:repeating-linear-gradientrepeating-radial-gradient,加強版色標是無限循環重復的,直到填滿整個背景。

background: repeating-linear-gradient(45deg, 
                                      #fb3, #fb3 15px,
                                      #58a 0, #58a 30px);
Paste_Image.png

這樣可以實現任意角度,任意寬度條紋的背景。我們再也不需要算什么勾股定理了。
變更60°試試:

Paste_Image.png

注意:該方法需要設置四個色標,所以要實現水平或者垂直條紋還是用上一種方法

同色系條紋
background: repeating-linear-gradient(30deg, 
                                      #79b, #79b 15px, 
                                      #58a 0, #58a 30px);
Paste_Image.png

對于這種同一色系,不同色調組成的條紋,我們可以換一種實現方式,把最深的顏色指定為背景色,同時在背景色之上添加半透明白色條紋來得到淺色的條紋。

background: #58a;
background-image: repeating-linear-gradient(30deg, 
                                            hsla(0, 0%, 100%, .1), hsla(0, 0%, 100%, .1) 15px, 
                                            transparent 0, transparent 30px);
Paste_Image.png

這樣的好處就是可以變更背景顏色,達到實現不同顏色的同系條紋背景。

復雜的背景圖案

通過組合對個漸變圖案我們可以得到一些列神奇的背景

background: white;
background-image: linear-gradient(90deg, 
                                  rgba(200, 0, 0, 0.5) 50%, transparent 0), 
                  linear-gradient(rgba(200, 0, 0, 0.5) 50%, transparent 0);
background-size: 30px 30px;
Paste_Image.png

桌布效果

background: #58a;
background-image: 
            linear-gradient(90deg, white 1px, transparent 0), 
            linear-gradient(white 1px, transparent 0););
background-size: 30px 30px;
Paste_Image.png

網格效果

background: #58a;
background-image: 
            linear-gradient(white 2px, transparent 0),
            linear-gradient(90deg, white 2px, transparent 0), 
            linear-gradient(hsla(0,0%,100%,.3) 1px, transparent 0), 
            linear-gradient(90deg, hsla(0,0%,100%,.3) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 
                 15px 15px, 15px 15px;
Paste_Image.png

藍圖網格

background: #655;
background-image: 
            radial-gradient(tan 30%, transparent 0),
            radial-gradient(tan 30%, transparent 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
Paste_Image.png

波點效果

background: #eee;
background-image: 
            linear-gradient(45deg, #bbb 25%, transparent 0), 
            linear-gradient(45deg, transparent 75%, #bbb 0),
            linear-gradient(45deg, #bbb 25%, transparent 0), 
            linear-gradient(45deg, transparent 75%, #bbb 0);
background-position: 0 0, 15px 15px, 15px 15px, 30px 30px;
background-size: 30px 30px;
Paste_Image.png

棋盤效果
注意:遇到復雜的圖案,還可以選擇SVG的方式來實現。
更多css背景圖案可以參見 http://bennettfeely.com/gradients

background: hsl(20, 40%, 90%);
background-image: linear-gradient(90deg, #fb3 11px, transparent 0),
                  linear-gradient(90deg, #ab4 23px, transparent 0),
                  linear-gradient(90deg, #655 41px, transparent 0);
background-size: 41px 100%, 61px 100%, 83px 100%;
Paste_Image.png

偽隨機背景圖案

連續的圖像邊框信封邊框

padding: 1em;
border: 1em solid transparent;
background: 
         linear-gradient(green, green) 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;
Paste_Image.png
padding: 1em;
border: 1em 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);
Paste_Image.png

以上兩種方式掘客實現這種信封式的邊框

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

實現PS選區出現的動畫邊框效果

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

上邊不完全邊框效果

以上就是本文所有內容

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容