手记

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

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)用SVG绘制的3×3九宫圆点背景图

border: 40px solid transparent;
border-image: 33.334% url('data:image/svg+xml,<svg xmlns="http:%2F%2Fwww.w3.org%2F2000%2Fsvg" width="30" height="30"> \
                          <circle cx="5" cy="5" r="5" fill="%23ab4"%2F><circle cx="15" cy="5" r="5" fill=" %23655"%2F> \
                          <circle cx="25" cy="5" r="5" fill="%23e07"%2F><circle cx="5" cy="15" r="5" fill=" %23655"%2F> \
                          <circle cx="15" cy="15" r="5" fill="hsl(15, 25%, 75%)"%2F> \
                          <circle cx="25" cy="15" r="5" fill=" %23655"%2F><circle cx="5" cy="25" r="5" fill="%23fb3"%2F> \
                          <circle cx="15" cy="25" r="5" fill=" %23655"%2F><circle cx="25" cy="25" r="5" fill="%2358a"%2F><%2Fsvg>');
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

/* 可以很方便地通过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;
2人推荐
随时随地看视频
慕课网APP