《精通CSS》第5章 漂亮的盒子

是时候继续我的云陪读计划了 ????。

《精通 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表示垂直向上,增大角度值则沿顺时针旋转。

渐变线的示意图如下:

图片来源W3C

表示方向的值可以省略,默认是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-repeatbackground-positionbackground-sizebackground-clipbackground-originbackground-attachbackground的简写形式以及多重背景。

1.3.1 background-repeat

上面的背景图片之所以会重复是因为background-repeat属性的默认值是repeat。如果我们想要不重复,则可以设置no-repeat。当然也可以设置repeat-xrepeat-y来指定图片沿着某个轴的方向重复。

除此之外,Backgrounds and Borders Level 3[4]进行了下面两个扩展:

  1. 支持以空格分隔来指定针对两个方向的关键字声明语法,如background-repeat: repeat no-repeat;

  2. 增加了新的关键字: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时,会一直以图片的左上角相对于父元素(左侧和顶部)来计算使用百分比时,则是以图片中对应比例的点定位到父元素对应比例的点。百分比的定位效果如下:

百分比的定位效果(图片来源W3C)

此外,还需要注意,关键字和其他值不可以混用,否则会失效。

除此之外,在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-boxcontent-box。这三个值的含义顾名思义,歪马就不多说了。指定不同的值,背景图片会被裁成不同的大小。本文,我们将background-clip设为content-box,效果如下(加了内边距):

background-clip是在原有背景图片大小的基础上进行裁剪。除了这样,我们还可以借助background-origin直接将背景元素限制在content-box内容盒子以内。

background-origin也支持border-boxpadding-boxcontent-box这三个值,但是默认值是padding-box。同样,我们将其值设为content-box,效果如下:

只是这样你会发现,内边距的空白间隙并不对,这是因为background-size: cover;导致图片放大了,有一部分没有被裁剪,所以显示出来了。同时指定background-clip: content-box;就可以了。和上面的区别就在于背景图被裁掉的区域减少了一点。

1.3.6 background的简写

上面我们介绍了大部分背景相关的属性,还有一个可以实现背景附着的background-attachment没有介绍,它可以实现背景随页面滚动固定,感兴趣的同学可以扩展一下。歪马不多做介绍了。

下面我们要看一看background的简写形式,通过这个这个属性可以设置上述跟背景相关的所有属性,一般情况下属性的顺序值可以随意,浏览器会自动识别。但有以下两点特殊:

  • 由于background-positionbackground-size都支持长度值,所以要求声明时两者都要声明,以/隔开,先声明background-position,后声明background-size

  • background-clipbackground-origin都支持border-boxpadding-boxcontent-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双平行线、grooveinset。后面三种比较不常用,主要是由于不能主动控制样式,会受到浏览器限制。单边样式设置与上面类似。

  • border: 简写属性可以同时指定上面三个属性,顺序不限。

2.2 圆角边框border-radius

圆角边框的普通用法与margin/pading类似,从左上角开始,顺时针指定四个值。如果缺少,则和对角的相同。如果只设定一个值,则四个角应用同一个值。

如下:

border-radius: 4em 8em;

除此之外,我们还以分别指定水平方向和垂直方向的垂直半径。中间用/分隔。

如下所示:

border-radius: 4em 8em / 6em 4em;

除了上面同时指定多个角的圆角半径之外,我们还可以使用border-top-left-radiusborder-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-shadowbox-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公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值