【CSS in Depth2精译】1.4 简写属性

server/2024/10/20 3:57:33/

文章目录

    • 1.4 简写属性
      • 1.4.1 当心简写属性悄悄覆盖其他样式
      • 1.4.2 记住简写值的顺序
        • 1 上、右、下、左顺序
        • 2 先水平、再垂直的顺序

1.4 简写属性

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

css">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 缩写属性指定所有关联值

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

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

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

css">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 给元素的每一边指定内边距

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

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

css">padding: 1em 2em;
padding: 1em 2em 1em;
padding: 1em 2em 1em 2em;

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

css">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 指定两个内边距

css">.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 值

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

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

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


http://www.ppmy.cn/server/52837.html

相关文章

微型微控制器托管双直流/直流升压转换器

电池是便携式系统应用的典型电源&#xff0c;如今基于微控制器的便携式系统并不罕见。各种微控制器在低电源电压下运行&#xff0c;例如 1.8V。因此&#xff0c;您可以使用两节 AA 或 AAA 电池为电路供电。然而&#xff0c;如果电路需要更高的电压——例如&#xff0c;LCD 的 L…

ElasticSearch地理空间数据写入

目录 ElasticSearch地理空间数据写入思路介绍实现(geo_point)数据处理创建点的mappings使用Java将数据写入ES配置maven依赖项目配置ES数据写入查询数据实现(geo_shape)数据处理创建geo_shape的mappings使用Java将数据写入ES数据写入查询数据ElasticSearch地理空间数据写入 申明…

【深度学习驱动流体力学】计算流体力学openfoam-paraview与python3交互

目的1:配置 ParaView 中的 Python Shell 和 Python 交互环境 ParaView 提供了强大的 Python 接口,允许用户通过 Python 脚本来控制和操作其可视化功能。在 ParaView 中,可以通过 View > Python Shell 菜单打开 Python Shell 窗口,用于执行 Python 代码。要确保正确配置 …

Shell 获取Hive表的location 信息

用shell 获取建表语句&#xff1a; hive -e "show create table ods_job.ods_job_tb"得到结果&#xff1a; CREATE TABLE ods_job.ods_job_tb(id bigint COMMENT id, auto int COMMENT job开启/关闭&#xff1a;0-关闭&#xff1b;1-开启, ....timeout_kill string…

RAG应用要如何吃到大模型长上下文的红利?-LongRAG

去年底的时候&#xff0c;笔者写过&#xff0c;与其在RAG系统上雕花&#xff0c;可以重新思考一下&#xff0c;自己的业务场景是否非RAG不可吗&#xff1f;随着去年大模型的蓬勃发展&#xff0c;长度外推、更长的上下文模型&#xff0c;更厉害的中文底座大模型&#xff0c;都可…

C语言实现:贪心算法

算法基础原理 贪心算法是一种在求解问题时&#xff0c;总是做出在当前看来是最好的选择的算法。它不从整体最优上进行考虑&#xff0c;而是通过每一步的局部最优选择&#xff0c;希望达到全局的最优解. 贪心算法的特点:贪心算法在每一步都选择当前状态下的最优解&#xff0c;即…

Netty中Reactor线程的运行逻辑

Netty中的Reactor线程主要干三件事情&#xff1a; 轮询注册在Reactor上的所有Channel感兴趣的IO就绪事件。 处理Channel上的IO就绪事件。 执行Netty中的异步任务。 正是这三个部分组成了Reactor的运行框架&#xff0c;那么我们现在来看下这个运行框架具体是怎么运转的~~ 这…

Mysql 官方提供的公共测试数据集 Example Databases

数据集&#xff1a;GitHub - datacharmer/test_db: A sample MySQL database with an integrated test suite, used to test your applications and database servers 下载 test_db: https://github.com/datacharmer/test_db/releases/download/v1.0.7/test_db-1.0.7.tar.gz …