CSS的秘密——背景和邊框(下)

lvxfcjf發表於2021-09-09

1.7

重複的幾何圖案很好,但是會有一點無聊。在大自然中幾乎沒有像相同的瓷磚一樣重複的事物。即使是重複的元素,也總是存在變化和隨機性。例如一大片花叢,規則的排列足以讓其很漂亮,但是足夠的隨機性也足夠讓其變得有趣。沒有兩朵花是一模一樣的。這就是我們要讓背景圖案看上去儘可能自然的原因。
複製隨機性可能是具有挑戰性的,因為CSS不提供任何固有的隨機效能力。讓我們以條紋來舉例。假設我們想要隨機顏色(為簡化難度,固定為四種顏色)和寬度的豎條紋背景圖案,不能有肉眼可見的“空隙”。

/* 我們的第一次嘗試,應該是製作有四種顏色的豎條紋背景圖案;這樣做重複性很明顯,每80px就重複,需要增加隨機性 */
background: linear-gradient(90deg,
            #fb3 15%, #655 0, #655 40%,
            #ab4 0, #ab4 65%, hsl(20, 40%, 90%) 0);
background-size: 80px 100%;

/* 增加隨機性的第一種想法:一種背景基色加上三個不同顏色的條紋,設定不同寬度和不同的重複值;
由於最上面的條紋重複是最顯著的(因為它沒有被任何東西覆蓋),我們要把具有最大重複間隔的條紋放在頂部(在本例中是#fb3橙色條紋)。*/
background: hsl(20, 40%, 90%);
background-image:linear-gradient(90deg, #fb3 10px, transparent 0),
                 linear-gradient(90deg, #ab4 20px, transparent 0),
                 linear-gradient(90deg, #655 20px, transparent 0);
background-size: 80px 100%, 60px 100%, 40px 100%;

/* 上面的圖案看起來更隨機,但仔細看還是能發現每240px重複一次,這裡的240正是單個條紋重複值40,60和80的最小公倍數;
邏輯上講,我們要增加隨機性就需要最大化重複值。為了使幾個數的最小公倍數最大,這幾個數就需要互質 */
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 23px, transparent 0);
background-size: 83px 100%, 61px 100%, 41px 100%;

1.8 連續的影像邊框

有時候,我們想使用一張影像,不是作為背景,而是作為邊框。將圖片裁剪至邊緣,用以裝飾元素的邊框,並且不管元素的尺寸多大,圖片都能自適應地包裹元素的邊緣。
用CSS實現連續影像邊框的主要思路是再用一個純白的背景覆蓋用以做邊框的影像,需要設定不同的background-clip,保證用以做邊框的影像透過邊框區域顯示。最後一件事是,由於我們只能在最後一層有一個背景顏色,我們需要透過從白色到白色的CSS漸變來偽造白色。
(1)

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
            url(stone-art.jpg);
/* background-size用以設定背景影像的尺寸,可用數值或百分比設定寬度和高度,如果只設定一個值,那麼第二個值會被設定為auto;
cover表示把背景影像擴充套件至足夠大,以使背景影像完全覆蓋背景區域;
contain表示把影像擴充套件至最大尺寸,以使寬度和高度完全適應內容區域。 */
background-size: cover;
background-clip: padding-box, border-box;
/* 如果不加這一句,上述程式碼形成的效果與我們想達到的效果很相近,但看起來很奇怪;
因為預設情況下background-origin的值是padding-box,即背景影像會從padding-box的0,0位置開始 */
background-origin: border-box;

/* 上述程式碼可以簡寫成:*/
padding: 1em;
border: 1em solid transparent;
background:linear-gradient(white, white) padding-box,
           url(stone-art.jpg) border-box 0 / cover;

(2)

border: 40px solid transparent;
border-image: 33.334% url('data:image/svg+xml,');
padding: 1em;
max-width: 20em;
font: 130%/1.6 Baskerville, Palatino, serif;
/* border-image-repeat設定邊框影像的平鋪方式,預設值是stretch,表示在平鋪領域影像被拉伸;
repeat表示反覆平鋪影像,如果不能正好收納影像,影像剩餘部分將被切除;
round表示反覆平鋪影像,當不能正好容納影像時,根據情況放大或縮小影像。 */
border-image-repeat: round;

(3)葡萄酒主題的信封邊框
當然,我們可以把同樣的思想用在基於漸變的圖案上。例如,葡萄酒主題的信封邊框:
1)

/* 可以很方便地透過background-size修改條紋寬度,透過border修改邊框的厚度 */
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;

2)透過border-image

/* 這種方式有以下問題:一是每次需要更新border-image-slice時,都需要改變border-width並讓其匹配;
二是border-image-slice不能使用em,必須嚴格用畫素描述邊框厚度;
三是條紋寬度需要描述停止位置,如果要改變,需要修改四個地方 */
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);

(4)
這種技術的另一個有趣的應用是製作前進的螞蟻邊界。前進的螞蟻邊界是虛線邊界,看起來像螞蟻行軍(如果你想象破折號是螞蟻)。
為了實現前進的螞蟻邊界,我們將把條紋轉換為黑白,將邊框寬度減小到1px(才能將條紋變成虛線),並將背景尺寸更改為適當的尺寸。然後,background-position到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;
}

(5)
我們還可以用border-image製作腳註,只需要一個裁剪過的頭部邊框:

/* 使用currentColor,當color改變時,邊框的顏色會隨文字顏色的改變而改變 */
border-top: .2em solid transparent;
border-image: 100% 0 0 linear-gradient(90deg,
              currentColor 4em,
              transparent 0);
padding-top: 1em;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2807372/,如需轉載,請註明出處,否則將追究法律責任。

相關文章