You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the previous section, we learned how to use CSS gradients to create all sorts of stripes. However, stripes are not the be-all and end-all of background patterns or even just geometric patterns. We quite often need many other different types, such as grids, polka dots, checkerboards, and many others.
Thankfully, CSS gradients can help with many of these too. It’s possible to create almost any kind of geometric pattern with CSS gradients, although it’s not always practical. If we’re not careful, we might end up with an insane amount of unmaintainable code. CSS patterns are also one case where it really pays off to use a CSS preprocessor, such as Sass to reduce repetition, as the more complex they get, the less DRY they become.
My CSS3 Patterns Gallery (found at lea.verou.me/css3patterns) showed what is possible with CSS gradients as early as 2011. It was included in almost every article, book, and conference talk that mentioned CSS gradients between 2011 and 2012 and was used by several browser vendors to fine-tune their CSS gradients implementations. However, not every pattern showcased in it would be a good use case for a production website. Some of them are included only to show what is possible, but their code is extremely long and repetitive. For those cases, SVG is a better choice. For some examples of SVG patterns, visit philbit.com/svgpatterns, which was created as the SVG answer to the CSS Patterns Gallery.
In this secret, we will focus on creating some of the easiest and commonly needed patterns.
在本篇攻略中,我们将深入讨论如何创建那些简单而常用的图案。
Grids
网格
When using only one gradient, there aren’t that many patterns we can create. The magic starts to unfold when we combine multiple gradients, having them show through each other’s transparent regions. Perhaps the easiest such pattern is overlaying horizontal and vertical stripes to create various types of grids. For example, the following code creates the tablecloth-reminiscent (gingham) pattern shown in Figure XX.XX:
Our tablecloth (gingham) pattern, as well as the two gradients that comprise it (transparency shown here as the conventional gray checkerboard)
我们的桌布(方格纹)图案,是由两层渐变图案所组成的(按照惯例,灰色的棋盘图案表示透明)。
In some cases, we want to be able to adjust the cell size of the grid, and have the width of its lines remain constant--for example, to create grid lines that serve as guides. This is a great use case for using lengths instead of percentages as gradient color stops:
background:#58a;
background-image:linear-gradient(white 1px, transparent 0),linear-gradient(90deg, white 1px, transparent 0);
background-size:30px30px;
The result (seen on Figure XX.XX) is a grid of 1px white lines with a grid cell size of 30px. Just like in the {#section}, the base color is also functioning as a fallback color.
So far, we have only used linear gradients to make patterns. However, radial gradients can be very useful as well, as they allow us to create circles, ellipses, or parts thereof. The simplest pattern we can create with a radial gradient is an array of dots (Figure XX.XX):
Admittedly, this is not very useful on its own. However, we can combine two of those gradients and give them different background positions, to create a polka dot pattern (Figure XX.XX):
Note that for the effect to work, the second background position must be half of the tile size. Unfortunately, this means that to change the tile size, we need to make four edits. This is on the brink of being unmaintainable, although whether it has crossed the line is debatable. If you are using a preprocessor, you may want to convert it into a mixin:
Then, to create the polka dot pattern, we would call it like this:
以后在创建波点图案时,我们就可以像这样调用它:
@includepolka(30px, 30%, #655, tan);
Checkerboards
棋盘图案
Checkerboard patterns are used in a number of cases. For instance, subtle checkerboards can be an interesting alternative to a bland solid color background. Also, a gray checkerboard pattern is the de facto standard way to depict transparency, which is required in a number of different UIs. Making a checkerboard pattern in CSS is possible, but considerably trickier than one might expect.
The typical tile that generates a checkerboard when repeated consists of two squares from each color, like the one indicated in Figure XX.XX. It looks like it should be easy to recreate with CSS: we would just create two squares with different background positions, right? Not exactly. Yes, we can technically create squares with CSS gradients, but with no spacing around them, the result will look like a solid color. However, there is no way to create squares with space around them with one CSS gradient. If you’re having doubts, try to find a gradient that, when repeated, produces the image in Figure XX.XX.
Repeating a square with space around it; the tile is shown with dashed lines
四周有空隙的方块在平铺之后得到的结果;单个贴片用虚线标出来了。
The trick is to compose the square from two right triangles. We already know how to create right triangles (remember our failed attempt at diagonal stripes in Figure XX.XX?). To refresh your memory, the code looked like this (here with different colors and transparency):
You might be wondering how this helps with anything. Sure, if we tried to compose squares from two triangles like the ones in Figure XX.XX, we would end up with a solid color. However, what if we reduce the legs of these triangles to half their original size, so that they occupy of the tile, instead of the current ? We can easily do that by changing the color stop position to 25% instead of 50%. Then we would end up with something like Figure XX.XX.
At first, the result in Figure XX.XX doesn’t look like we’re getting anywhere. However, we just need to move the second gradient by half the tile size, in order to combine them into a square:
Our combined triangles now form squares with space around them; the two tiles are shown with dashed lines and the second gradient is shown slightly darker
Can you guess what the result looks like? It’s exactly what we were trying to achieve earlier, and looks like Figure XX.XX. Notice that this is essentially half a checkerboard. All we need to turn this into a full checkerboard is to repeat the two gradients to create another set of squares and offset their positions again, a bit like applying the polka dot technique twice:
The result is a checkerboard, identical to the one in Figure XX.XX. We can improve the code a bit by combining the opposite facing triangles (i.e., the first with the second and the third with the fourth) and making the darker gray semi-transparent black, so that we can change the base color without always having to adjust the top color accordingly:
This is a complex pattern and it’s often difficult to wrap one’s head around how it works, especially after reducing it to two gradients. It usually aids understanding of how a pattern works to give a random color to one of the gradients or color stops. For example, here the first gradient is shown with rebeccapurple instead of the semi-transparent black and the two tiles are outlined with dashed lines.
Now we have two gradients instead of four, but the code is almost as WET as before. To change the accent color or the cell size, we need to make four edits. At this point, it might be a good idea to use a preprocessor mixin to reduce duplication. For example, in Sass it would look like this:
In the future, we won’t have to resort to meticulously overlaying triangles to create checkerboards. CSS Image Values Level 4 defines a new set of gradient functions to generate conical gradients (a.k.a. “angle gradients”). These gradients often look like a cone observed from above, hence the name “conical.” They are generated by a line that gradually changes color as it rotates around a fixed point. For example, the hue wheel shown here would be created with the following gradient:
Conical gradients are useful for far more things than hue wheels: starbursts, brushed metal effects, and many other kinds of backgrounds, including (you guessed it!) checkerboards. They would enable us to create the repeating tile of Figure XX.XX in just one gradient:
Unfortunately, there is no browser support for conical gradients at the time of writing, but you can find a polyfill at leaverou.github.io/conic-gradient.
One could reply, “But CSS gradients save us HTTP requests!” However, with modern browsers, we can embed the SVG file in our stylesheet as a data URI, and we don’t even need to base64 or URLencode most of it:
可能有人会说,“可是 CSS 渐变能省掉 HTTP 请求啊!” 其实,对于现代浏览器来说,我们可以把 SVG 文件以 data URI 的方式内嵌到样式表中,而且,我们甚至不需要用 base64 或 URLencode 来把它编码:
The SVG version is not only 40 characters shorter, but also considerably less repetitive. For example, we can change the colors in only one place and the size with two edits.
Combining these techniques with blending modes, by using background-blend-mode with values other than normal for some (or even all) of the layers a background pattern is made of can yield very interesting results, as this pattern gallery by Bennett Feely demonstrates. Most of these patterns only use the multiply blending mode, but other values such as overlay, screen, or difference can be very useful too.
Complex background patterns
复杂的背景图案
The problem
难题
In the previous section, we learned how to use CSS gradients to create all sorts of stripes. However, stripes are not the be-all and end-all of background patterns or even just geometric patterns. We quite often need many other different types, such as grids, polka dots, checkerboards, and many others.
在上一节中,我们学会了如何用 CSS 渐变来创建各种条纹图案。但是,条纹并不是我们要实现的唯一的背景图案,它甚至只是几何图案中最简单的一种。我们还需要很多其他不同类型的图案,比如网格、波点、棋盘等等。
Thankfully, CSS gradients can help with many of these too. It’s possible to create almost any kind of geometric pattern with CSS gradients, although it’s not always practical. If we’re not careful, we might end up with an insane amount of unmaintainable code. CSS patterns are also one case where it really pays off to use a CSS preprocessor, such as Sass to reduce repetition, as the more complex they get, the less DRY they become.
幸运的是,CSS 渐变在实现这些图案时也能大展拳脚。用 CSS 渐变来创建任何种类的几何图案几乎都是可能的,只不过有时这种方法不太实际。我们可能稍不留神就会弄出一大坨无法维护的代码。CSS 图案可以算是一个值得使用 CSS 预处理器(比如 Sass)来减少代码冗余的案例,因为最终图案越复杂,相应的代码就会变得越来越不 DRY。
In this secret, we will focus on creating some of the easiest and commonly needed patterns.
在本篇攻略中,我们将深入讨论如何创建那些简单而常用的图案。
Grids
网格
When using only one gradient, there aren’t that many patterns we can create. The magic starts to unfold when we combine multiple gradients, having them show through each other’s transparent regions. Perhaps the easiest such pattern is overlaying horizontal and vertical stripes to create various types of grids. For example, the following code creates the tablecloth-reminiscent (gingham) pattern shown in Figure XX.XX:
当只使用一个渐变时,我们所能创建的图案并不多。当我们开始把多个渐变图案组合起来时,让它们透过彼此的透明区域显现,神奇的事情就开始了。按照这个思路,我们首先想到的可能就是把水平和垂直的条纹叠加起来,从而得到各种样式的网格。举例来说,下面的代码会创建如图 图 2.39 所示的桌布(方格纹)图案。
In some cases, we want to be able to adjust the cell size of the grid, and have the width of its lines remain constant--for example, to create grid lines that serve as guides. This is a great use case for using lengths instead of percentages as gradient color stops:
在某些情况下,我们希望网格中每个格子的大小可以调整,同时又希望网格线条的粗细保持固定——举例来说,类似图纸辅助线的网格就是这种情况。这是一个非常好的例子,展示了使用长度而不是百分比作为色标的场景:
The result (seen on Figure XX.XX) is a grid of
1px
white lines with a grid cell size of30px
. Just like in the {#section}, the base color is also functioning as a fallback color.我们得到的结果就是一幅用
1px
白线画出来的30px
大小的网格图案(参见 图 2.40)。与 **“{$section$}” 段落(第 {$page$} 页)**中的例子类似,主色调这里也起到了回退颜色的作用。This grid is a good example of a pattern that can be made with reasonably maintainable (though not completely DRY) CSS code:
这个网格一个很好的例子,说明图案可以用合理的、可维护的(尽管还不是完全 DRY 的)CSS 代码生成出来:
We can even overlay two grids with different line widths and colors to create a more realistic blueprint grid (Figure XX.XX):
我们甚至可以把两幅不同线宽、不同颜色的网格图案叠加起来,来得到一个更加仿真的蓝图网格(参见 图 2.41):
Polka dot
波点图案
So far, we have only used linear gradients to make patterns. However, radial gradients can be very useful as well, as they allow us to create circles, ellipses, or parts thereof. The simplest pattern we can create with a radial gradient is an array of dots (Figure XX.XX):
目前为止,我们一直都是在用线性渐变来生成图案。但是,径向渐变同样也是非常实用的,因为它们允许我们创建圆形、椭圆,或是它们的一部分。我们可以用径向渐变创建的最简单的图案是圆点的阵列(参见 图 2.42):
Admittedly, this is not very useful on its own. However, we can combine two of those gradients and give them different background positions, to create a polka dot pattern (Figure XX.XX):
不过坦白地说,目前的这个样子还不是很实用。别着急,我们可以生成两层圆点阵列图案,并把它们的背景定位错开,这样就可以得到真正的波点图案了(参见 图 2.43):
Note that for the effect to work, the second background position must be half of the tile size. Unfortunately, this means that to change the tile size, we need to make four edits. This is on the brink of being unmaintainable, although whether it has crossed the line is debatable. If you are using a preprocessor, you may want to convert it into a mixin:
请注意,为了达到效果,第二层背景的偏移定位值必须是贴片宽高的一半。但不幸的是,这意味着我们如果要改动贴片的尺寸,需要修改四处。虽然可能还没到不可收拾的地步,但这样的代码就快要跌入不可维护的深渊。如果你在使用预处理器,就赶紧把它转换成这个 mixin 吧:
Then, to create the polka dot pattern, we would call it like this:
以后在创建波点图案时,我们就可以像这样调用它:
Checkerboards
棋盘图案
Checkerboard patterns are used in a number of cases. For instance, subtle checkerboards can be an interesting alternative to a bland solid color background. Also, a gray checkerboard pattern is the de facto standard way to depict transparency, which is required in a number of different UIs. Making a checkerboard pattern in CSS is possible, but considerably trickier than one might expect.
棋盘图案在很多场景下都会用到。比如说,相对于单调的纯色背景来说,具有细微对比度的棋盘图案可能就是一个有趣的替代品。同样,在各种应用程序的界面中,灰色的棋盘图案已经是用于表示透明色的事实标准。在 CSS 中创建棋盘图案是可能的,只不过实现过程比我们想像的可能要 “绕” 一些。
The typical tile that generates a checkerboard when repeated consists of two squares from each color, like the one indicated in Figure XX.XX. It looks like it should be easy to recreate with CSS: we would just create two squares with different background positions, right? Not exactly. Yes, we can technically create squares with CSS gradients, but with no spacing around them, the result will look like a solid color. However, there is no way to create squares with space around them with one CSS gradient. If you’re having doubts, try to find a gradient that, when repeated, produces the image in Figure XX.XX.
棋盘图案是可以通过平铺生成的,平铺成这个图案的最典型的贴片包含两种不同颜色的方块,且相互间隔,就像 图 2.44 中所标示出的那样。它貌似可以在 CSS 中很容易地重现出来:我们只需要创建两个不同背景定位的方块就可以了,没错吧?然而并非如此。是的,在技术上,我们可以用 CSS 渐变来创建平铺的方块,但每个方块的周围是不会有空隙的,因此最终的结果看起来就是一片实色。总的来说,只用一层 CSS 渐变是无法创建四周有空隙的方块的。如果你对此还怀有疑议,不妨找找看有没有一种渐变可以在重复平铺时产生 图 2.45 所示的图像。
The trick is to compose the square from two right triangles. We already know how to create right triangles (remember our failed attempt at diagonal stripes in Figure XX.XX?). To refresh your memory, the code looked like this (here with different colors and transparency):
这里的窍门在于用两个直角三角形来拼合出我们想要方块。我们已经知道了如何创建直角三角形了(还记得我们在 图 2.29 中尝试实现斜向条纹时所遭遇的失败吗?)。为了唤起你的记忆,我们再来看看当时的代码(这里换用了另一种颜色和透明色):
You might be wondering how this helps with anything. Sure, if we tried to compose squares from two triangles like the ones in Figure XX.XX, we would end up with a solid color. However, what if we reduce the legs of these triangles to half their original size, so that they occupy of the tile, instead of the current ? We can easily do that by changing the color stop position to 25% instead of 50%. Then we would end up with something like Figure XX.XX.
你可能还没有搞明白这个方法是怎么发挥作用的。没错,如果我们尝试直接用两个三角形组合出 图 2.29 中那样的正方形,我们可能只会得到一片实色。但是,如果我们把这些三角形的直角边缩短到原来的一半,从而只占据贴片面积的 ,而不是 时,会怎么样?要满足这一点,我们只需要简单地**把色标的位置值从 50% 改为 25%**就可以了。然后我们得到的效果会变成 图 2.46 所示的那样。
Similarly, we can create triangles of the opposite direction if we flip the color stops (Figure XX.XX):
与此类似,如果我们把色标的顺序反转,就可以创建相反方向的三角形了(图 2.47):
Can you guess what happens if we combine the two? The code would look like this:
你能猜到把它们组合到一起时会发生什么吗?代码是这样的:
At first, the result in Figure XX.XX doesn’t look like we’re getting anywhere. However, we just need to move the second gradient by half the tile size, in order to combine them into a square:
乍看起来,图 2.48 中所示的效果似乎并不我们想要的。但是,我们只需要把第二层渐变在水平和垂直方向均移动贴片长度的一半,就可以它们拼合成一个完整的方块:
Can you guess what the result looks like? It’s exactly what we were trying to achieve earlier, and looks like Figure XX.XX. Notice that this is essentially half a checkerboard. All we need to turn this into a full checkerboard is to repeat the two gradients to create another set of squares and offset their positions again, a bit like applying the polka dot technique twice:
你能猜到它的结果是什么样子吗?就是我们一直想要实现的效果,如 图 2.49 所示。请注意这本质上只是棋盘的一半。要把它转变为一幅完整的棋盘,我们只需要把现有的这一组渐变再重复一份,从而创建出另一组正方形,并且偏移它们的定位值——有点像我们在波点图案中所用到的技巧:
The result is a checkerboard, identical to the one in Figure XX.XX. We can improve the code a bit by combining the opposite facing triangles (i.e., the first with the second and the third with the fourth) and making the darker gray semi-transparent black, so that we can change the base color without always having to adjust the top color accordingly:
最终结果就是一幅棋盘图案,正如 图 2.44 所示的那样。其实这段代码还可以稍稍优化一下,比如我们可以把这些处在贴片顶角的三角形两两组合起来(即把第一组和第二组合并为一层渐变,第三组和第四组合并为一层渐变);然后还可以把深灰色改成半透明的黑色——这样我们只需要改底色就可以改变整个棋盘的色调了,不需要单独调整各层渐变的色标了:
Now we have two gradients instead of four, but the code is almost as WET as before. To change the accent color or the cell size, we need to make four edits. At this point, it might be a good idea to use a preprocessor mixin to reduce duplication. For example, in Sass it would look like this:
现在我们把四层渐变消化成了两层渐变,但代码仍然跟以前一样 WET。为了改变棋盘的主色调或者是方格的尺寸,我们还是需要修改四个地方。在这一点上,使用预处理器的 mixin 来简化代码可能是一个好主意。比如说,用 Sass 写的代码可能就是这样的:
In any case, this is so much code that it might actually be better to go the SVG route. An SVG tile for Figure XX.XX would be as small and simple as:
在任何情况下,这样的代码量都不能算少,所以转到 SVG 方案可能是更好的选择。图 2.44 中贴片如果用 SVG 来实现,就像下面这样简短:
One could reply, “But CSS gradients save us HTTP requests!” However, with modern browsers, we can embed the SVG file in our stylesheet as a data URI, and we don’t even need to base64 or URLencode most of it:
可能有人会说,“可是 CSS 渐变能省掉 HTTP 请求啊!” 其实,对于现代浏览器来说,我们可以把 SVG 文件以 data URI 的方式内嵌到样式表中,而且,我们甚至不需要用 base64 或 URLencode 来把它编码:
The SVG version is not only 40 characters shorter, but also considerably less repetitive. For example, we can change the colors in only one place and the size with two edits.
SVG 的版本不仅更短(只有 40 个字符),而且在代码冗余度方面也明显更低。举例来说,我们在改颜色时只需要改一处,而在改尺寸时只需要改两处。
The text was updated successfully, but these errors were encountered: