「响应式网页设计」 CSS多变应用范例

CSS application scenarios

Posted by Mingyu on May 2, 2022

背景与边框

半透明边框

对于边框border,最简单的尝试是直接使用透明颜色,但是这种方法无法显示半透明的边框,因为默认情况下背景会延伸到边框所在的区域下一层。

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

解决方案是,用使用background-clip属性来设置:

描述
border-box 背景被裁剪到边框盒。
padding-box 背景被裁剪到内边距框。
content-box 背景被裁剪到内容框。
1
2
3
border: 10px solid hsla(0,0%,100%,.5);
background: white;
background-clip:padding-box;

多重边框

box-shadow方案

box-shadow的第3个参数模糊值设置为0,再设置第4个参数扩张半径,所得到的投影就是实线边框。box-shadow的好处在于,支持逗号分割语法,因此可以叠加多个边框。甚至在多个边框外部再加一层常规的投影。

1
2
3
4
5
6
7
8
9
div {
	width: 200px;
	height: 200px;
	margin: 25px;
	background: yellowgreen;
	box-shadow: 0 0 0 10px #655,
            0 0 0 15px deeppink,
            0 2px 5px 15px rgba(0,0,0,.6);
}

outline方案

对于只需要两层边框的情况比较适用,可以先设置一层常规边框,再加上outline产生外层的边框,这样的好处是边框样式十分灵活,不像box-shadow仅能模拟实线边框。并且可以通过offline-offset属性设置负值。

1
2
3
4
5
6
7
8
9
10
div {
	width: 300px;
	height: 200px;
	margin: 25px;
	background: #655;
	border:10px solid #655;
	border-radius:50px;
	outline: 2px dashed white;
	outline-offset:-20px;
}

注意:outline的圆角会随着border的变化而变化(在较低版本的css中可能并不具备这一特性)

灵活的背景定位

在基于左上角的位置方案中,如何基于右下角进行偏移需要通过偏移计算才能得出,这对于可变尺寸的容器来说往往不能得到精确的效果。

background-position的扩展语法方案

利用background-position的扩展语法,在偏移量前指定关键字即可,如下代码使得背景图片和右边缘保持20px偏移,和下边缘保持10px偏移。

1
background-position: right 20px bottom 10px;

background-origin方案

当偏移量与容器的内边距一致时,让其自动的跟着内边距走,不必另外证明偏移量的值。在盒模型中,由外到内分别包括border-boxpadding-boxcontent-box,默认情况下图片background-position中的设置是根据padding-box设置的,因此对于padding内偏移不起作用,只需将其改成content-box即可使其随着padding而更改。

1
2
background-position: bottom right;
background-origin: content-box;

calc()方案

calc()可以允许进行css的对应值计算,需要注意的是内部运算符号的前后需要留出空格,否则会发生解析错误。

1
background-position: calc(100% - 20px) calc(100% - 20px);

条纹背景

利用线性渐变生成条纹

对于线性渐变的色标,假如让两个色标具有相同的位置,那么中间就不存在过渡区域,从效果上看也就是一个颜色突然转变成另一个颜色。进一步地利用背景的重复效果,在默认状态下背景是重复的,也即等价于background-repeat: repeat;,这样就可以获得重复的条纹效果。(关于色标的位置,如果某个色标位置比前面的色标的位置值小,那么该色标的位置将会被设置为前面所有色标的最大值,利用这一点我们可以将第二个色标的位置值设置为0,那么它会自动和前一个色标保持一致)

1
2
3
4
5
6
7
8
9
10
background: linear-gradient(#fb3 50%, #58a 0);
/*
同样可以考虑不规则的条纹分布,只需调整色标位置比例
background: linear-gradient(#fb3 30%, #58a 0);
考虑多颜色条纹
background: linear-gradient(#fb3 30%, #58a 0,#58a 60%, yellowgreen 0);
考虑垂直条纹
background: linear-gradient(to right,#fb3 30%, #58a 0);
*/
background-size: 100% 30px;

关于background-repeat的可选属性值:

描述
repeat 默认。背景图像将在垂直方向和水平方向重复。
repeat-x 背景图像将在水平方向重复。
repeat-y 背景图像将在垂直方向重复。
no-repeat 背景图像将仅显示一次。
inherit 规定应该从父元素继承 background-repeat 属性的设置。

斜向条纹

在普通的横向和纵向条纹中,我们利用了背景的重复来铺满整个背景达到目标效果,但是对于斜向条纹而言,则不太容易找到一个可以用来重复的构造单元,因此需要使用循环式加强过的渐变。

repeating-linear-gradientrepeating-radial-gradient:语法与非重复的渐变类似,第一个参数是角度,后面是多个色标。

1
2
3
4
background: repeating-linear-gradient(60deg, 
              #fb3, #fb3 15px,
              #58a 0, #58a 30px);
height: 100%;

同色系条纹

对于同一色系条纹,往往条纹之间仅仅存在明度上的差异,因此更方便的做法是,把最深的颜色指定为背景色,把半透明白色的条纹叠加在背景色之上。

1
2
3
4
5
background: #58a;
background-image: repeating-linear-gradient(30deg, 
              hsla(0,0%,100%,.1), hsla(0,0%,100%,.1) 15px,
              transparent 0, transparent 30px);
height: 100vh;

复杂的背景图案

网格

多个渐变图案组合起来,让彼此的透明区域显现,就可以组合出网格。

1
2
3
4
background: white;
background-image: linear-gradient(90deg, rgba(200,0,0,0.5) 50%, transparent 0),
                  linear-gradient(0deg, rgba(200,0,0,0.5) 50%, transparent 0);
background-size: 50px 50px;

进一步地使用粗细固定的条纹来分割网格

1
2
3
4
5
6
7
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: 50px 50px, 50px 50px,
                 10px 10px, 10px 10px;

波点

我们可以使用线性渐变生成图案,但是径向渐变同样也是非常实用的,径向渐变能够创建的最简单的图案是圆点的阵列,可以生成两层圆点阵列图案,并把它们的背景定位错开。

1
2
3
4
5
background: #655;
background-image: radial-gradient(tan 20%, transparent 0),
                  radial-gradient(tan 20%, transparent 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;

为了达到效果,第二层背景的偏移定位必须是贴片宽高的一半,但是如果需要改变贴片尺寸,需要修改四处,可维护性不好,可以进一步地使用scss来创建。

1
2
3
4
5
6
7
8
9
10
11
@mixin polka($size,$dot,$base,$accent){
	background:$base;
	background-image: radial-gradient($accent $dot, transparent 0),
                  radial-gradient($accent $dot, transparent 0);
	background-size: $size $size;
	background-position: 0 0, $size/2 $size/2;
}

div{
    @include polka(30px,30%,#655,tan);
} 

在scss中,定义指令混入@mixin 可以将定义的指令混入到一个元素的样式里面去,混入的方式是使用@include 来混入。

棋盘

在平铺时,很难直接通过平铺方格的形式来做到平铺棋盘,因此可以使用的一种技巧是,通过平铺直角三角形的方式来拼合出想要的方块。

1
2
3
4
5
6
7
8
background: #eee;
background-image: 
	linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0),
	linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0);
background-position: 0 0, 15px 15px;
background-size: 30px 30px;

min-height: 100%;

伪随机背景

为了更加真实地模拟条纹的随机性,我们后续可以把一组条纹从一个平面拆散为多个图层:一种颜色作为底色,另外几种颜色作为条纹,然后再以不同的间隔重复平铺。这样顶层的条纹在重复的过程中会覆盖底层地条纹,由于每次覆盖的位置不一样,因此产生了类似随机的效果。但是需要注意的是,这只是一种“伪随机”现象,因为多个条纹之间重复间隔的最大公倍数,就是这组条纹的重复周期,如果要让条纹的随机性更加真实,就需要让最小公倍数最大化——采用质数作为间隔像素数。

1
2
3
4
5
6
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. Lea Verou著《CSS揭秘》
  2. CSS background-clip 属性,原文链接:https://www.w3school.com.cn/cssref/pr_background-clip.asp
  3. CSS background-repeat 属性,原文链接:https://www.w3school.com.cn/cssref/pr_background-repeat.asp