1.4 简写属性

简写属性(Shorthand properties 是可以一次性设置多个属性值的样式属性。例如, font 就是一个简写属性。它可以设置多个字体属性:font-stylefont-weightfont-sizeline-height 以及 font-family

font: italic bold 18px/1.2 "Helvetica", "Arial", sans-serif;

其他常见的简写属性还有:

  • background:可设置多个背景属性,如:background-colorbackground-imagebackground-sizebackground-repeatbackground-positionbackground-originbackground-clip 以及 background-attachment
  • border:边框样式的简写属性,可以设置:border-widthborder-style 以及 border-color,并且这几个属性也都是简写属性;
  • border-width:分别是上、右、下、左四个边框宽度的简写属性。

简写属性可以让代码简洁明了,但是也隐藏了一些怪异行为。


1.4.1 当心简写属性悄悄覆盖其他样式

大多数简写属性都可以省略一些值,而只设置我们关心的样式;但重要的是您必须清楚,这么做还是会影响到那些被省略的属性,它们会被隐式地设置为各自的初始值(initial value),从而悄悄覆盖其他地方设计好的样式。例如,在不指定字体粗细(font-weight)的情况下对标题使用简写属性,该标题的字体粗细仍会被赋上一个 normal 值(如图 1.11 所示)。

图 1.11 标题的字体粗细变为了初始值

图 1.11 简写样式 font: 32px sans-serif 将字体粗细和其他省略属性设为了初始值(initial value)

按如下代码更新样式表来验证上述过程。

代码清单 1.19 缩写属性指定所有关联值

h1 {
  font-weight: bold;
}
.title {
  font: 32px Helvetica, Arial, sans-serif;
}

乍一看, 似乎 <h1 class="title"> 会将标题加粗,但并非如此。代码清单 1.19 等价于以下代码:

代码清单 1.20 与代码清单 1.19 等价的展开后的简写属性

h1 {
  font-weight: bold;
}
.title {
  /* 这些属性的初始值都是 normal */
  font-style: normal;
  font-variant: normal;
  font-weight: normal;
  font-stretch: normal;
  line-height: normal;
  font-size: 32px;
  font-family: Helvetica, Arial, sans-serif;
}

这就意味着给 <h1> 元素设置简写样式得到的只是普通粗细的字体,并非粗体字。此外,它还会覆盖从某个祖先元素继承来的其他字体样式。在所有的简写属性中, font 的问题最为严重,因为受其干扰的样式属性实在是太多了。也正是这个原因,除非在 <body> 元素上设置通用样式,我一般都尽量避免用 font 来添加样式。其他简写样式可能也会遇到类似的问题,因此还请务必当心。


1.4.2 记住简写值的顺序

简写属性在指定样式的顺序上没那么严格。设置 border: 1px solid black 或者 border: black 1px solid 都是有效的。这是因为浏览器知道哪个值对应宽度、哪个值对应颜色、哪个值又对应边框样式。

但有不少属性的值是很容易混淆的。在这种情况下,理解并牢记这些样式值的顺序就显得至关重要了,尤其是那些会经常用到的简写属性。

1 上、右、下、左顺序

当遇到像 marginpadding 这样的属性、或者需要指定元素四条边上的边框样式时,开发人员尤其容易弄错这些简写样式的顺序。这些属性值是按顺时针方向、从顶部开始排列的。

记住这个顺序可以少走很多弯路。单词 TRouBLe 可以用作该顺序的记忆口诀:Top(上)、Right(右)、Bottom(下)、Left(左)。

下面就用这个口诀来设置元素各边的内边距。如图 1.12 所示,给导航链接分别指定 10px 的上内边距、15px 的右内边距、0 像素的下内边距、以及 5px 的左内边距。虽然看起来不太匀称,但足以说明这一排序规则:

图 1.12 每一侧的内边距都各不相同

图 1.12 声明 padding: 10px 15px 0 5px 后每一侧的内边距都不同

相应的 CSS 样式代码如下:

代码清单 1.21 给元素的每一边指定内边距

.nav a {
  color: white;
  background-color: #13a4a4;
  padding: 10px 15px 0 5px; /* 上、右、下、左内边距 */
  border-radius: 2px;
  text-decoration: none;
}

这种写法还可以再精简。如果声明结束时还有一个值没指定,则没有值的一边会和它对边的取值相同:指定三个值,左右两边用的是第二个值;指定两个值,则上下两边用第一个值,左右两边用第二个值;要是只有一个值,则将其应用到所有四个边。因此,下列声明都是等价的:

padding: 1em 2em;
padding: 1em 2em 1em;
padding: 1em 2em 1em 2em;

同理,以下声明也是等价的:

margin: 1em;
margin: 1em 1em;
margin: 1em 1em 1em;
margin: 1em 1em 1em 1em;

对许多开发人员而言,这当中最棘手的就是只有三个值的情形。请记住,三个值分别指定了上、右、下三个方向。因为左边方向的值缺失了,它的样式值与右侧相同,即左右两边的值皆为第二个值。因此,声明 padding: 10px 15px 0 会给左右两侧 15px 的内边距,与此同时顶部内边距为 10px,底部为 0。

但大多数情况下只需要设置两个值。尤其是像按钮或者本例中的导航链接这样较小的页面元素,左右两边的内边距最好比上下内边距更宽,这样显得更美观一些(如图 1.13 所示)。

图 1.13 很多元素增大水平内边距后会更好看些
图 1.13 很多元素增大水平内边距后会更好看些

按以下代码更新样式表。它利用简写属性先设置了垂直方向上的内边距,然后再设置水平方向的内边距。

代码清单 1.22 指定两个内边距

.nav a {
  color: white;
  background-color: #13a4a4;
  padding: 5px 15px; /* 先是上下内边距,再是左右内边距 */
  border-radius: 2px;
  text-decoration: none;
}

由于很多常见属性都遵循这个顺序,所以最好记住它。

2 先水平、再垂直的顺序

TRouBLe 口诀仅适用于给盒子四周设置简写属性的情形。其他一些属性最多只支持两个值,比如:background-positionbox-shadowtext-shadow(严格来讲它们并不算简写属性)。与 padding 这样需要四个值的属性相比,它们的属性值顺序恰巧是相反的。padding: 1em 2em 先指定垂直方向上的上/下属性值,再是水平方向的左/右属性值;而 background-position: 25% 75% 则先指定水平方向的属性值,然后才是垂直方向的值。

尽管这个看似相反的顺序有些违背人的直觉,但道理很简单:这两个值代表了一个笛卡尔网格(即平面直角坐标系)。笛卡尔网格的测量结果常按 x、y 的顺序给出(先水平再垂直)。打个比方,想要给如图 1.14 所示的元素添加一个阴影效果,就得首先指定 x(水平)值。

图 1.14 盒子的阴影位置为 10px 2px
图 1.14 盒子的阴影位置为 10px 2px

该元素对应的样式代码如下:

代码清单 1.23 box-shadow 先指定 x 值再指定 y 值

.nav .featured {
  background-color: orange;
  box-shadow: 10px 2px #6f9090; /* 阴影向右偏移 10px、向下偏移 2px */
}

第一个(较大的)值指定了水平偏移量,第二个(较小的)值指定了垂直偏移量。

如果属性需要指定相对某个位置出发的两个方向上的值,就多想想“笛卡尔网格”;如果属性需要指定元素四周环绕的每个方向上的值,则多想想“时钟”。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部