文章目录
- 1.4 简写属性
- 1.4.1 当心简写属性悄悄覆盖其他样式
- 1.4.2 记住简写值的顺序
- 1 上、右、下、左顺序
- 2 先水平、再垂直的顺序
1.4 简写属性
简写属性(Shorthand properties) 是可以一次性设置多个属性值的样式属性。例如, font
就是一个简写属性。它可以设置多个字体属性:font-style
、font-weight
、font-size
、line-height
以及 font-family
:
font: italic bold 18px/1.2 "Helvetica", "Arial", sans-serif;
其他常见的简写属性还有:
background
:可设置多个背景属性,如:background-color
、background-image
、background-size
、background-repeat
、background-position
、background-origin
、background-clip
以及background-attachment
;border
:边框样式的简写属性,可以设置:border-width
、border-style
以及border-color
,并且这几个属性也都是简写属性;border-width
:分别是上、右、下、左四个边框宽度的简写属性。
简写属性可以让代码简洁明了,但是也隐藏了一些怪异行为。
1.4.1 当心简写属性悄悄覆盖其他样式
大多数简写属性都可以省略一些值,而只设置我们关心的样式;但重要的是您必须清楚,这么做还是会影响到那些被省略的属性,它们会被隐式地设置为各自的初始值(initial value),从而悄悄覆盖其他地方设计好的样式。例如,在不指定字体粗细(font-weight
)的情况下对标题使用简写属性,该标题的字体粗细仍会被赋上一个 normal
值(如图 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 上、右、下、左顺序
当遇到像 margin
、padding
这样的属性、或者需要指定元素四条边上的边框样式时,开发人员尤其容易弄错这些简写样式的顺序。这些属性值是按顺时针方向、从顶部开始排列的。
记住这个顺序可以少走很多弯路。单词 TRouBLe 可以用作该顺序的记忆口诀:Top(上)、Right(右)、Bottom(下)、Left(左)。
下面就用这个口诀来设置元素各边的内边距。如图 1.12 所示,给导航链接分别指定 10px 的上内边距、15px 的右内边距、0 像素的下内边距、以及 5px 的左内边距。虽然看起来不太匀称,但足以说明这一排序规则:
图 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.22 指定两个内边距
.nav a {color: white;background-color: #13a4a4;padding: 5px 15px; /* 先是上下内边距,再是左右内边距 */border-radius: 2px;text-decoration: none;
}
由于很多常见属性都遵循这个顺序,所以最好记住它。
2 先水平、再垂直的顺序
TRouBLe 口诀仅适用于给盒子四周设置简写属性的情形。其他一些属性最多只支持两个值,比如:background-position
、box-shadow
和 text-shadow
(严格来讲它们并不算简写属性)。与 padding
这样需要四个值的属性相比,它们的属性值顺序恰巧是相反的。padding: 1em 2em
先指定垂直方向上的上/下属性值,再是水平方向的左/右属性值;而 background-position: 25% 75%
则先指定水平方向的属性值,然后才是垂直方向的值。
尽管这个看似相反的顺序有些违背人的直觉,但道理很简单:这两个值代表了一个笛卡尔网格(即平面直角坐标系)。笛卡尔网格的测量结果常按 x、y 的顺序给出(先水平再垂直)。打个比方,想要给如图 1.14 所示的元素添加一个阴影效果,就得首先指定 x(水平)值。
图 1.14 盒子的阴影位置为 10px 2px
该元素对应的样式代码如下:
代码清单 1.23 box-shadow
先指定 x 值再指定 y 值
.nav .featured {background-color: orange;box-shadow: 10px 2px #6f9090; /* 阴影向右偏移 10px、向下偏移 2px */
}
第一个(较大的)值指定了水平偏移量,第二个(较小的)值指定了垂直偏移量。
如果属性需要指定相对某个位置出发的两个方向上的值,就多想想“笛卡尔网格”;如果属性需要指定元素四周环绕的每个方向上的值,则多想想“时钟”。