是时候继续我的云陪读计划了 ????。
《精通 CSS》往期陪读章节:
今天我们要阅读的章节是《精通 CSS》的第五章 漂亮的盒子。
前面我们了解过了盒模型,知道盒子由外边距、边框、内边距和内容区组成。对于整个盒子,我们可以通过一系列的手段来美化,如指定盒子的背景、边框以及盒子的阴影。
本文将从这三个方面来介绍如何美化一个盒子。
给盒子指定纯色、渐变色背景以及图片背景
给盒子设置圆角边框/图片边框
给盒子设置阴影
本章文中示例代码托管在CodeSandbox[1],请按需取用
一、设置盒子的背景
背景相关的属性有很多,接下来歪马一个一个给大家展示。先来看一下背景颜色。
1.1 设置背景颜色
首先,我们创建一个盒子,然后我们给它设置一个颜色。设置什么颜色好呢,呃,那就基佬紫吧。
可以通过下面两种方式设置背景颜色,如下:
/* 方式1 */
background-color: #9a08e3;
/* 方式2 */
background: #9a08e3;
这两种方式设置之后,效果都如下:
虽然上面两种方式都能设置背景颜色,不过我们需要注意的是,简写背景属性不仅仅会设置背景颜色,还会把其他背景相关属性设置为默认值,如果不注意可能会覆盖其他值。
关于颜色,现在 CSS 支持设置 16 进制表示的颜色、rgb()/rgba()
以及hsl()/hsla()
。其中的rgba()
和hsla()
除了可以设置颜色值之外,还可以设置颜色的透明度。
CSS 中还有另外一个属性opacity
可以设置透明度,这个属性会把整个盒子变的透明,而不单单是背景色。
关于颜色的原理大家感兴趣可以参考文博大佬的这份 PPT[2]。
1.2 设置渐变色背景
你可能会说,纯色的基佬紫不够“骚”,不符合你的气质。如果是这样的话,歪马向你推荐渐变色背景。
虽然说叫作渐变色,但其实是一种绘制渐变图的机制。这个机制可以与任何接受图片的属性一起使用,本文我们用到的是background-image
。
渐变方案包括线性渐变、放射渐变、重复渐变。下面我们挨个看过。
1.2.1 线性渐变
首先是linear-gradient()
线性渐变函数,线性渐变会沿着一条假想线,绘制一个颜色渐变的图片。它支持逗号分隔的多组值。如下:
background-image: linear-gradient(45deg, #d041e8 0%, #9a08e3 100%);
其中第一组值可以表示这条假想线的延伸方向,可以是角度值也可以是关键字。假想的渐变线会按照指定的方向,穿过元素的中心区域。
其中,关键字形式是使用to
后面加上某个边(top/right/bottom/left
)或某个角top left/top right/bottom-left/bottom right
。使用角度值deg
时,0deg
表示垂直向上,增大角度值则沿顺时针旋转。
渐变线的示意图如下:
表示方向的值可以省略,默认是to bottom
,用角度值表示就是180deg
。
表示方向的值后面的各组值表示渐变的颜色色标,至少要有两组值,一组值时无渐变效果。
新增的色标如果未指定位置,则在 0%~100%范围内取均值。
除了百分比,我们也可以使用绝对单位来指定色标位置。
各类用法的效果如下图所示:
1.2.2 放射渐变
除了上面按照直线进行渐变的线性渐变,还有一种可以从中心向四周渐变的效果,叫做放射渐变,也叫径向渐变,对应的 CSS 属性是radial-gradient
。
放射渐变的语法比较复杂。主要有以下几点:
首先,放射渐变也接受多组值,第一组可以指定放射渐变的类型(原型
circle
和椭圆形ellipse
)以及渐变的起始位置,渐变半径或者结束位置。默认的渐变类型是椭圆形。圆形放射渐变的射线半径只接受一个半径值,值类型为长度值,不能是百分比(这是因为盒子不是方的,百分比无法判断用盒子的宽还是高)。
椭圆形则可以接受 x 和 y 轴两个方向的半径值,值的类型可以是长度值和百分比。
除此之外,半径还可以使用关键字,
closest-side
表示最近的边,farthest-side
表示最远的边,closest-corner
表示最近的角,farthest-corner
表示最远的角(默认值)。渐变的起始位置类似于
backgound-positon
在第一组值中用at
表示,默认为居中。
除了第一组值(第一组值也可以省略),其后的值为色标,也可以像线性渐变一样指定不同的色标加位置。如果指定的色标位置大于上面的渐变半径,最后的渐变区域会变大,超过渐变半径。
具体的例子和效果如下。
1.2.3 重复渐变
为了便于大家进行创作,上面的两种渐变还有这对应的重复渐变。
重复渐变会自动重复给出的渐变色标组合,重复次数视其大小(由 background-size 决定)和盒子大小决定。
如下,我们可以使用重复线性渐变实现格子桌布的效果。
background-image: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 10px,
rgba(208, 65, 232, 0.3) 10px,
rgba(208, 65, 232, 0.3) 20px
),
repeating-linear-gradient(
to right,
transparent 0,
transparent 10px,
rgba(208, 65, 232, 0.3) 10px,
rgba(208, 65, 232, 0.3) 20px
);
使用重复放射渐变可以实现类似下面的效果:
background-image: repeating-radial-gradient(
circle closest-side,
transparent 0,
transparent 20px,
rgba(208, 65, 232, 0.3) 20px,
rgba(208, 65, 232, 0.3) 40px
);
上面这些都是基本操作,CSS 是充满想象力的,大家可以看一看 Lea Verou 的CSS3 Patterns Gallery[3],上面有很多更丰富的效果。下图仅供参考。
比如我们也把上面的放射渐变改吧改吧,就可以实现美国队长的盾牌的效果。
<div class="shield">
<span>★</span>
</div>
.shield {
width: 400px;
height: 400px;
text-align: center;
line-height: 400px;
border-radius: 50%;
margin: 50px auto;
background-image: radial-gradient(
circle closest-side,
#2930ae 0,
#2930ae 50px,
#c8143c 50px,
#c8143c 100px,
#fff 100px,
#fff 150px,
#c8143c 100px,
#c8143c 100px
);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5), 0 1px 5px rgba(0, 0, 0, 0.5),
1px 0 5px rgba(0, 0, 0, 0.5);
}
.shield > span {
top: 50%;
transform: translate(-50%, -50%);
font-size: 80px;
color: #ffffff;
text-shadow: 0px 0px 5px #333, 0px 1px 5px #333, 1px 0px 5px #333,
1px 1px 5px #333;
}
1.3 设置背景图片
说到设置背景图片,我们首先要想明白一个问题,什么时候图片应该用作背景图片,而不是<img>
。通常,如果把图片从网页中去掉,不会影响网页的意义,那么图片就可以用作背景图片。当然,如果为了实现特定效果,也可以稍微做一下妥协。
背景图片的语法格式比较简单,如下:backgroung-image: <url> | <gradient>
。渐变作为背景,上面我们已经说了。常见的 URL 形式的背景图片设置大家一定也用过。
如下我们简单的设置下背景图片:
.bg-iamge {
width: 1000px;
height: 600px;
margin: 40px auto;
border: 10px solid lightcoral;
background-image: url("https://p2.ssl.qhimg.com/t0127f74a63ca750596.png");
}
如果只是这么做的话,可能达不到你想要的效果,而是下面这样的。
我们会发现,图片重复平铺了整个元素,这是因为除了设置背景图片,我们还有很多属性来操作背景图片,从而达到我们想要的效果。
下面我们依次了解一下background-repeat
、background-position
、background-size
、background-clip
、background-origin
、background-attach
、background
的简写形式以及多重背景。
1.3.1 background-repeat
上面的背景图片之所以会重复是因为background-repeat
属性的默认值是repeat
。如果我们想要不重复,则可以设置no-repeat
。当然也可以设置repeat-x
和repeat-y
来指定图片沿着某个轴的方向重复。
除此之外,Backgrounds and Borders Level 3[4]进行了下面两个扩展:
支持以空格分隔来指定针对两个方向的关键字声明语法,如
background-repeat: repeat no-repeat;
增加了新的关键字:
space
如果图片可以在元素内重复两次以上,则重复,且图片之间填充空白。round
则图片会被缩放,从而重复整数次。
哈哈,这些新的特性感觉并没有太大用处,本文,我们先禁用图片的重复background-repeat: no-repeat;
,效果如下:
如上,我们虽然禁用了图片的重复,但是最后的效果并不好,这是因为背景图片的位置是在左上角。下面我们一起来看看如何调整背景图片的位置。
1.3.2 background-position
background-position
属性的值既可以使用关键字,也可以是像素、em
或百分比,可以指定两个值,分别表示相对于左侧的偏移量和相对于顶部的偏移量。关键字包括用于 x 轴的left
/cener
/right
和用于 y 轴的top
/center
/bottom
,规范没有约定两个值的先后顺序。不过歪马建议大家不管使用什么值,都先指定 x 轴,再指定 y 轴。
使用像素和em
与使用百分比进行背景定位时,计算方式是不一样的。使用像素和em
时,会一直以图片的左上角相对于父元素(左侧和顶部)来计算。使用百分比时,则是以图片中对应比例的点定位到父元素对应比例的点。百分比的定位效果如下:
此外,还需要注意,关键字和其他值不可以混用,否则会失效。
除此之外,在CSS Backgrounds and Borders Module Level 3[5]中,background-position
引入了新语法,可以先写边界关键字,再写长度值。写法如下:
background: url(https://p1.ssl.qhimg.com/t015bb5c7be246fb2af.jpg) no-repeat right center;
background-position: right 10px top 50%;
关于背景的定位,歪马前两天单独拎出了一篇相关的文章《CSS 实现背景图片右侧定位的 5 种小技巧》,没有看到的各位可以点击看一下。
本文,我们先将背景图片的位置设为居中,如下:
background-position: center;
这样看起来正常多了,但是背景图的大小和盒子的大小差距过大。下面我们来调整一下背景图的大小。
1.3.3 background-size
background-size
可以接受明确的长度值和百分比。可以指定两个值,第一个值是 x 轴的尺寸,第二个是 y 轴的尺寸,如果第二个省略,则值为auto
。
使用明确的长度值是,会将背景图片设为固定大小。使用百分比,可以让图片随着元素缩放,百分比是根据容器大小计算的。
由于图片是有固定尺寸的,比较推荐将其中一个设为指定值,另一个设为auto
。
除了指定值之外,background-size
还可以接受关键字作为值:
contain
: 保持图片最大化,同时不改变图片的宽高比,浏览器会自动决定哪一边撑满,哪一边使用auto
。cover
: 缩放图片直至图片覆盖整个元素,并且比例不变。
本文,我们将背景大小设为cover
,虽然会对元素进行一定的裁剪,但是会保证整个元素都有背景。效果如下:
1.3.4 background-clip
背景裁剪与background-origin
背景控制原点
现在背景图片是充满整个元素的,但是现在我们想要给内部留一点空白间隙,这时我们可以借助background-clip
背景裁剪来实现。
background-clip
支持的值有border-box
(默认值)、padding-box
、content-box
。这三个值的含义顾名思义,歪马就不多说了。指定不同的值,背景图片会被裁成不同的大小。本文,我们将background-clip
设为content-box
,效果如下(加了内边距):
background-clip
是在原有背景图片大小的基础上进行裁剪。除了这样,我们还可以借助background-origin
直接将背景元素限制在content-box
内容盒子以内。
background-origin
也支持border-box
、padding-box
、content-box
这三个值,但是默认值是padding-box
。同样,我们将其值设为content-box
,效果如下:
只是这样你会发现,内边距的空白间隙并不对,这是因为background-size: cover;
导致图片放大了,有一部分没有被裁剪,所以显示出来了。同时指定background-clip: content-box;
就可以了。和上面的区别就在于背景图被裁掉的区域减少了一点。
1.3.6 background
的简写
上面我们介绍了大部分背景相关的属性,还有一个可以实现背景附着的background-attachment
没有介绍,它可以实现背景随页面滚动固定,感兴趣的同学可以扩展一下。歪马不多做介绍了。
下面我们要看一看background
的简写形式,通过这个这个属性可以设置上述跟背景相关的所有属性,一般情况下属性的顺序值可以随意,浏览器会自动识别。但有以下两点特殊:
由于
background-position
和background-size
都支持长度值,所以要求声明时两者都要声明,以/
隔开,先声明background-position
,后声明background-size
。background-clip
和background-origin
都支持border-box
、padding-box
和content-box
。只存在一个值时,两者都使用该值
存在两个时,第一个用于
background-origin
,第二个用于background-clip
。
特别注意,使用简写属性时省略的值会使用默认值,可能会覆盖其他值,所以建议放在其他背景属性前面。
如果你也像歪马一样觉得这样的规则不好记的话,那就单独写吧。清晰明了,而且对新手友好。
1.3.7 多重背景
background
可以与linear-gradient
/radial-gradient
类似,可以支持逗号分隔的多组值,最先声明的背景在最上层,最后声明的在最下面。并且可以在最后设置纯色。
关于背景的内容就这么多了,下面我们来看看如何给元素设置圆角边框/图片边框。
二、设置圆角边框/图片边框
2.1 元素的边框
元素边框的属性比较简单。可以给某一边设置,也可以给四边设置。涉及到的属性如下:
border-width
:设置边框宽度,border-top-width
可以设置上边宽度,其他三边类似。border-color
: 设置边框颜色,border-top-color
可以设置上边颜色,其他三边类似。border-style
: 支持以下关键字solid
实线、dashed
虚线、dotted
点虚线、double
双平行线、groove
和inset
。后面三种比较不常用,主要是由于不能主动控制样式,会受到浏览器限制。单边样式设置与上面类似。border
: 简写属性可以同时指定上面三个属性,顺序不限。
2.2 圆角边框border-radius
圆角边框的普通用法与margin
/pading
类似,从左上角开始,顺时针指定四个值。如果缺少,则和对角的相同。如果只设定一个值,则四个角应用同一个值。
如下:
border-radius: 4em 8em;
除此之外,我们还以分别指定水平方向和垂直方向的垂直半径。中间用/
分隔。
如下所示:
border-radius: 4em 8em / 6em 4em;
除了上面同时指定多个角的圆角半径之外,我们还可以使用border-top-left-radius
、border-top-right-radius
等来分别设定某个角的圆角半径,如果要水平和垂直分开指定,则也以/
分隔。
通过设置不同的值,我们还可以实现椭圆、半椭圆、四分之一椭圆。
.ellipse-1 {
border-radius: 50%;
}
.ellipse-2 {
border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}
.ellipse-3 {
border-radius: 100% 0 0 0 / 100% 0 0 0;
}
.ellipse-4 {
border-radius: 50% 0 50% 0 / 100% 0 100% 0;
}
2.3 图片边框
图片边框歪马也单独拎出过一篇文章进行详细讲解,有兴趣朋友点过去看下吧。这里就不浪费篇幅详述了。链接如下:《玩转 CSS Border-Image》。
三、盒阴影box-shadow
在《第 4 章 网页排版》中,我们介绍过text-shadow
。box-shadow
与其类似,语法格式为box-shadow: <x偏移量> <y偏移量> <模糊半径> <扩展半径> <颜色值>
。其中,多了扩展半径,如果为正值则阴影向外扩大(扩大的部分不模糊),若为负值,则阴影向内缩小。
具体效果如下:
.spread-shadow {
box-shadow: 15px 15px 15px 10px #555;
}
.shrink-shadow {
box-shadow: 15px 15px 15px -10px #555;
}
此外,我们还可以使用inset
关键字将阴影变为内阴影。
最后与text-shadow
类似,我们也可以通过逗号分隔,指定多组阴影值。
总结
至此,歪马的《第 5 章 漂亮的盒子》云陪读内容就结束了,本文对原文的内容结构进行了一定的调整,并且将其中比较有意思的内容单独拎了出来,当然也存在部分的删减,但是整体的主题都是围绕如何美化盒子。
读完之后,相信你一定 get 到了以下几点:
如何给盒子指定纯色、渐变色背景、指定图片背景
如何给盒子设置圆角边框/图片边框
如何给盒子设置阴影
如果你 get 到了,那么再发散一下,美化你想实现的盒子吧。
文内链接
[1]
CodeSandbox: https://codesandbox.io/embed/jingtongcss-l8tye?fontsize=14&hidenavigation=1&theme=dark
[2]这份 PPT: https://ppt.baomitu.com/d/c887a533#/
[3]CSS3 Patterns Gallery: https://leaverou.github.io/css3patterns/
[4]Backgrounds and Borders Level 3: https://www.w3.org/TR/css-backgrounds-3/
[5]CSS Backgrounds and Borders Module Level 3: https://www.w3.org/TR/css-backgrounds-3/
关于奇舞周刊
《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。