本文介绍 css 属性值 position 的定义与解析。内容来源于 drafts.csswg.org/css-values-…
<position> 值用于指定对齐主体(如背景图片)在对齐容器(如背景定位区域)内的位置,通过指定边缘之间的偏移量对(默认为左侧和顶部)来实现。其语法如下:
<position> = <position-one> | <position-two> | <position-four>
<position-one> = [ left | center | right | top | bottom | x-start | x-end | y-start | y-end | block-start | block-end | inline-start | inline-end | <length-percentage>]
<position-two> = [ [ left | center | right | x-start | x-end ] &&
[ top | center | bottom | y-start | y-end ]
|
[ left | center | right | x-start | x-end | <length-percentage> ]
[ top | center | bottom | y-start | y-end | <length-percentage> ]
|
[ block-start | center | block-end ] &&
[ inline-start | center | inline-end ]
|
[ start | center | end ]{2}
]
<position-four> = [ [ [ left | right | x-start | x-end ] <length-percentage> ] &&
[ [ top | bottom | y-start | y-end ] <length-percentage> ]
|
[ [ block-start | block-end ] <length-percentage> ] &&
[ [ inline-start | inline-end ] <length-percentage> ]
|
[ [ start | end ] <length-percentage> ]{2}
]
语法说明
-
如果只指定一个值(
<position-one>),第二个值默认为center。 -
如果指定两个值(
<position-two>):- 第一个
<length-percentage>值表示水平位置,即对齐主体和对齐容器左边缘之间的偏移量 - 第二个
<length-percentage>值表示垂直位置,即对齐主体和对齐容器顶部边缘之间的偏移量
- 第一个
块轴和内联轴是 CSS 中用于描述文本布局方向的两个重要概念。它们的方向取决于书写模式:
- 水平书写模式(默认)(中文、英文):块轴是垂直方向(上下);内联轴是水平方向(左右)
- 垂直书写模式(日文竖排、蒙古文):块轴是水平方向(左右);内联轴是垂直方向(上下)
- 如果指定四个值(
<position-four>),每个<length-percentage>表示由前面关键字指定的边缘之间的偏移量。例如:background-position: bottom 10px right 20px;表示从底部边缘向上偏移 10px,从右侧边缘向左偏移 20px。
值说明
position 的值是一对偏移量(水平和垂直),每个偏移量作为计算的 <length-percentage> 值给出,表示对齐主体和对齐容器的左边缘和上边缘(分别)之间的距离。
<length-percentage>
<length-percentage> 值指定了对齐主体和对齐容器的指定边缘之间的偏移量大小。
length 的正值表示从对齐容器边缘向内偏移;负值表示从对齐容器边缘向外偏移。以下声明给出了从左上角开始的(水平,垂直)偏移量:
background-position: left 10px top 15px; /* 10px, 15px */
background-position: left top ; /* 0px, 0px */
background-position: 10px 15px; /* 10px, 15px */
background-position: left 15px; /* 0px, 15px */
background-position: 10px top ; /* 10px, 0px */
percentage 的水平偏移的百分比相对于(对齐容器宽度 - 对齐主体宽度);垂直偏移的百分比相对于(对齐容器高度 - 对齐主体高度)。例如:
0% 0%:对齐主体的左上角与对齐容器的左上角对齐100% 100%:对齐主体的右下角与对齐容器的右下角对齐75% 50%:对齐主体上 75% 宽 与对其容器上 75%宽的点对齐;对齐主体上 50% 高的点与对齐容器上 50% 高的点对齐。
下面是 background-position: 75% 50% 的例子
<style>
.container {
width: 300px;
height: 200px;
background-color: #f0f0f0;
/* 背景图片尺寸为 100x100px */
background-image: url('https://picsum.photos/100/100');
background-repeat: no-repeat;
/* 背景图片位置:水平方向 75%,垂直方向 50% */
background-position: 75% 50%;
position: relative;
}
/* 添加标记点来显示对齐位置 */
.container::before,
.container::after {
content: '';
position: absolute;
border-radius: 50%;
}
/* 容器上的对齐点 */
.container::before {
width: 15px;
height: 15px;
background: red;
left: 75%;
top: 50%;
transform: translate(-50%, -50%);
}
/* 背景图片上的对齐点 */
.container::after {
width: 10px;
height: 10px;
background: blue;
left: 75%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="container"></div>
在这个示例中:
- 容器尺寸为 300x200px
- 背景图片尺寸为 100x100px
background-position: 75% 50%表示:- 水平方向:背景图片上 75% 宽度的点与容器上 75% 宽度的点对齐
- 垂直方向:背景图片上 50% 高度的点与容器上 50% 高度的点对齐
- 红色圆点表示容器上的对齐点
- 蓝色圆点表示背景图片上的对齐点
关键字说明
top、right、bottom、left:分别偏移对齐主体和对齐容器的上/右/下/左边缘y-start、y-end、x-start、x-end:计算方式与对应的物理边缘再 x/y 轴的关键字相同block-start、block-end、inline-start、inline-end:计算方式与对应的物理边缘在 block/inline 轴关键字相同center:在对应轴上计算为 50% 的偏移量
解析与序列化
解析 <position>
当在语法中,<position> 与其他关键字 <length> 或 <percentage> 一起使用时,<position> 会被贪婪解析;它会尽可能多地消耗组件。
例如,transform-origin 定义了一个 3D 位置,实际上是 <position> <length>?。其中:<position> 定义 x 和 y 轴的位置,<length>? 是可选的 z 轴位置。像 left 50px 这样的值会被解析为 2 值的 <position>,省略了 z 分量;而像 top 50px 这样的值会被解析为单值的 <position> 后跟一个 <length>。
这种解析方式的区别在于,当第一个值是水平方向的关键字(如 left、right)时,后面的值会被解析为 y 轴位置;当第一个值是垂直方向的关键字(如 top、bottom)时,后面的值会被解析为 z 轴位置。
序列化 <position>
当序列化 <position> 的指定值时:
如果只指定了一个组件:
- 添加隐含的
center关键字,并序列化为 2 组件值。
/* 原始值 */
background-position: left; /* 单组件 */
/* 序列化后 */
background-position: left center; /* 添加隐含的 center */
如果指定了两个组件:
- 关键字序列化为关键字。
<length-percentage>序列化为<length-percentage>。- 组件先序列化水平方向,然后是垂直方向。
/* 原始值 */
background-position: left top; /* 两个关键字 */
background-position: 50px 30px; /* 两个长度值 */
background-position: 50% 30%; /* 两个百分比 */
/* 序列化后保持不变 */
background-position: left top; /* 关键字保持为关键字 */
background-position: 50px 30px; /* 长度值保持为长度值 */
background-position: 50% 30%; /* 百分比保持为百分比 */
如果指定了四个组件:
- 关键字和偏移量都会被序列化。
- 组件先序列化水平方向,然后是垂直方向;或者先序列化块轴,然后是内联轴。
/* 原始值 */
background-position: left 10px top 20px; /* 四个组件 */
/* 序列化后 */
background-position: left 10px top 20px; /* 保持关键字和偏移量 */
注意:<position> 值永远不会序列化为单个值,即使单个值会产生相同的行为。这是为了避免在某些语法中(如 transform-origin)当 <position> 后面跟着 <length> 时产生解析歧义。
<position> 的计算值序列化为一对 <length-percentage>,表示从左边缘和上边缘的偏移量,按此顺序。
<position> 的组合
<position> 的插值定义为每个组件(x, y)的独立插值,这些组件被规范化为从左上角开始的 <length-percentage> 偏移量。
例如:
/* 例如在动画中从 left top 到 right bottom */
@keyframes move {
from {
background-position: right top; /* 0% 0% */
}
to {
background-position: left bottom; /* 100% 100% */
}
}
在这个动画中:
- x 轴:从 100% 到 0%
- y 轴:从 0% 到 100%