CSS 零基础教程

CSS align-self 属性

上一章中,我们探索了 justify-contentalign-items 是如何控制弹性容器内所有项目的对齐方式的。这些属性将对齐规则作为一个整体应用到所有弹性项目上。

然而,有时候我们需要打破这些全局对齐设置,单独控制某一个特定的弹性项目。这就是 align-self 属性大显身手的地方。它提供了细粒度的控制,允许你在交叉轴上精确地定位特定的项目,完全无视容器上的 align-items 值。

掌握 align-self 是创建复杂且美观的、需要细微位置调整的布局的关键。

1. 理解 align-self

CSS 中的 align-self 属性允许你为单个弹性项目覆盖其父容器的 align-items 属性。

简而言之:align-items 设置的是所有子元素的默认对齐方式,而 align-self 让你能够为某个特殊的子元素“开小灶”,指定完全不同的对齐方式。当你希望某个特定元素脱颖而出,或者它的位置需要与其他项目不同时,这个属性非常有用。

2. align-self 的属性值

align-self 接受以下几个值(你会发现它们与 align-items 非常相似):

  • auto: 这是默认值。项目会继承其父容器的 align-items 值。如果该项目没有父容器,则表现为 stretch
  • stretch: 弹性项目在交叉轴方向拉伸以填满可用空间。项目的高度(或宽度,取决于主轴方向)将与弹性容器匹配,除非受到 min-heightmax-height 的限制。
  • center: 弹性项目在交叉轴的可用空间内居中对齐。
  • flex-start: 弹性项目对齐到交叉轴的起点。在行(row)布局中,这意味着项目靠顶部对齐;在列(column)布局中,意味着靠左对齐。
  • flex-end: 弹性项目对齐到交叉轴的终点。在行(row)布局中,这意味着项目靠底部对齐;在列(column)布局中,意味着靠右对齐。
  • baseline: 弹性项目根据其文本的基线进行对齐。只有在处理包含文本的内容时,这个值才有意义。
  • start: 将项目对齐到对齐容器交叉轴的起始边缘。它会尊重书写模式和方向。
  • end: 将项目对齐到对齐容器交叉轴的结束边缘。它会尊重书写模式和方向。
  • self-start: 将项目对齐到自身交叉轴的起始边缘。
  • self-end: 将项目对齐到自身交叉轴的结束边缘。

让我们通过代码示例来直观地理解这些值。

2.1 示例 1:覆盖全局的 align-items: center

设想一个导航栏的场景:大部分导航链接都是垂直居中的,但你希望左侧的网站 Logo 能够贴紧顶部对齐。

<div class="container">
  <div class="logo">网站 Logo</div>
  <div>项目 1</div>
  <div>项目 2</div>
  <div>项目 3</div>
</div>
.container {
  display: flex;
  align-items: center; /* 全局设置:垂直居中所有项目 */
  height: 200px;
  background-color: #f0f0f0;
}

.logo {
  align-self: flex-start; /* 独立设置:覆盖 Logo 的对齐方式,使其靠顶部 */
}

div {
  padding: 20px;
  border: 1px solid black;
}

在这个例子中,.container 设置了 align-items: center,把所有项目垂直居中。但是,.logo 类使用了 align-self: flex-start,成功覆盖了默认的居中对齐,将 Logo 单独拉到了容器的顶部。

2.2 示例 2:使用 align-self: stretch 强制拉伸

假设你有一排盒子,虽然其他盒子的高度由它们自己的内容决定,但你希望其中某一个盒子能够强制拉伸,填满整个容器的高度。

<div class="container">
  <div>项目 1</div>
  <div class="stretch">项目 2 (被拉伸)</div>
  <div>项目 3</div>
</div>
.container {
  display: flex;
  height: 150px;
  background-color: #f0f0f0;
}

.stretch {
  align-self: stretch; /* 单独拉伸这个项目以填满高度 */
}

div {
  padding: 20px;
  border: 1px solid black;
  margin: 5px;
}

这里,带有 .stretch 类的元素会在垂直方向上膨胀,填满容器定义的 150px 高度,而另外两个项目则保持它们基于内容的默认高度不变。

2.3 示例 3:在列布局 (Column) 中使用 flex-end

如果弹性容器使用了 flex-direction: column(垂直排列),那么 align-self 控制的就是水平方向的对齐。

<div class="container">
  <div>项目 1</div>
  <div class="end">项目 2 (靠右)</div>
  <div>项目 3</div>
</div>
.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 300px;
  background-color: #f0f0f0;
  align-items: flex-start; /* 全局设置:默认将所有项目靠左对齐 */
}

.end {
  align-self: flex-end; /* 单独设置:将这个项目靠右对齐 */
}

div {
  padding: 10px;
  border: 1px solid black;
  margin: 5px;
}

在这种情况下,align-items: flex-start 把所有项目都整齐地排在左侧。而在 .end 元素上添加的 align-self: flex-end则打破了规则,把这一个特定的项目推到了容器的右侧。

2.4 示例 4:使用 align-self: baseline 进行基线对齐

这个例子展示了如何结合使用全局的基线对齐和个别的覆盖。baseline 会根据文本的底部基线来对齐元素。

<div class="container">
  <div class="item1">短字</div>
  <div class="item2">很高的<br>文字</div>
  <div class="item3">中等</div>
</div>
.container {
  display: flex;
  height: 100px;
  background-color: #f0f0f0;
  align-items: baseline; /* 全局设置:尝试按文本基线对齐所有项目 */
}

.item2 {
  font-size: 2em; /* 故意让这个项目的字号更大、更高 */
}

div {
  padding: 10px;
  border: 1px solid black;
  margin: 5px;
}

在这个场景下,所有的项目都是基于文字的底部基线对齐的。尽管“很高的文字”占据了更大的高度,但它里面的文字基线会和“短字”、“中等”的文字基线保持在同一条水平线上。如果你现在给 .item2 加上 align-self: flex-start,它就会立刻脱离基线对齐的队伍,直接贴到容器的最顶部。