MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

CSS 深入探索justify-content与align-items的作用

2022-04-292.6k 阅读

1. 理解 CSS 布局模式与弹性盒模型

在现代前端开发中,CSS 布局模式是构建网页结构的核心技术之一。传统的布局模式如基于盒子模型的布局,虽然能实现基本的页面排版,但在处理复杂且响应式的布局时存在局限性。弹性盒模型(Flexbox)应运而生,它为我们提供了一种更灵活、高效的方式来处理页面元素的排列和分布。

弹性盒模型通过一系列属性来控制弹性容器(Flex Container)及其子元素(Flex Items)的布局。其中,justify-contentalign-items 是两个非常重要的属性,它们分别用于控制弹性容器主轴(main axis)和交叉轴(cross axis)上的对齐和分布方式。

要深入理解 justify-contentalign-items,首先需要明确弹性盒模型中主轴和交叉轴的概念。主轴是弹性容器内子元素排列的主要方向,默认情况下,水平方向(从左到右)是主轴方向,但可以通过 flex-direction 属性改变。交叉轴则是与主轴垂直的方向。例如,当主轴为水平方向时,交叉轴就是垂直方向。

2. justify-content 属性深入剖析

2.1 justify-content 的作用

justify-content 属性定义了弹性容器主轴上子元素的对齐方式和分布规则。它决定了子元素在主轴上如何分配剩余空间,从而实现不同的布局效果,如左对齐、居中对齐、两端对齐等。

2.2 justify-content 的取值

  • flex-start:这是默认值,子元素在主轴上从起始位置开始排列,起始位置取决于 flex-direction 的值。例如,当 flex-direction: row(水平排列)时,子元素从容器的左侧开始排列;当 flex-direction: column(垂直排列)时,子元素从容器的顶部开始排列。
.container {
  display: flex;
  justify-content: flex-start;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

在上述代码中,三个 .item 元素会从容器的左侧开始排列,因为 justify-content: flex-startflex-direction: row

  • flex-end:子元素在主轴上从结束位置开始排列。同样以 flex-direction: row 为例,子元素会从容器的右侧开始排列;若 flex-direction: column,则从容器底部开始排列。
.container {
  display: flex;
  justify-content: flex-end;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

这里,三个 .item 元素会从容器右侧开始排列。

  • center:子元素在主轴上居中排列。在水平主轴方向上,子元素会在容器水平中心位置排列;在垂直主轴方向上,子元素会在容器垂直中心位置排列。
.container {
  display: flex;
  justify-content: center;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

此代码中,三个 .item 元素会在容器水平方向的中心位置排列。

  • space-between:子元素在主轴上均匀分布,两端的子元素与容器边缘贴合。在水平主轴方向上,子元素之间的间隔相等,且第一个子元素靠左侧,最后一个子元素靠右侧;垂直主轴方向同理。
.container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

三个 .item 元素会均匀分布在容器内,两端的元素分别贴合容器左右边缘。

  • space-around:子元素在主轴上均匀分布,每个子元素两侧的间隔相等。这意味着两端的子元素与容器边缘的间隔是子元素之间间隔的一半。
.container {
  display: flex;
  justify-content: space-around;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

在这种情况下,三个 .item 元素两侧间隔相等,使得它们均匀分布在容器内。

  • space-evenly:子元素在主轴上均匀分布,每个子元素之间的间隔以及子元素与容器边缘的间隔都相等。
.container {
  display: flex;
  justify-content: space-evenly;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

这里,三个 .item 元素以及它们与容器边缘的间隔都完全相等,实现了更加均匀的分布。

3. align-items 属性深入剖析

3.1 align-items 的作用

align-items 属性定义了弹性容器交叉轴上子元素的对齐方式。它决定了子元素在交叉轴上如何对齐,例如顶部对齐、居中对齐、底部对齐等,这对于创建复杂且美观的布局至关重要。

3.2 align-items 的取值

  • stretch:这是默认值,子元素在交叉轴方向上拉伸以填满容器。当子元素在交叉轴方向上没有设置明确的高度(对于水平主轴)或宽度(对于垂直主轴)时,会自动拉伸以适应容器大小。
.container {
  display: flex;
  align-items: stretch;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

在上述代码中,由于 align-items: stretch 且子元素未设置明确高度,三个 .item 元素在垂直方向(交叉轴)上会拉伸至与容器高度相同。

  • flex-start:子元素在交叉轴上从起始位置开始对齐。当主轴为水平方向时,子元素在容器顶部对齐;当主轴为垂直方向时,子元素在容器左侧对齐。
.container {
  display: flex;
  align-items: flex-start;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 50px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

这里,三个 .item 元素在垂直方向(交叉轴)上会从容器顶部开始对齐。

  • flex-end:子元素在交叉轴上从结束位置开始对齐。对于水平主轴,子元素在容器底部对齐;对于垂直主轴,子元素在容器右侧对齐。
.container {
  display: flex;
  align-items: flex-end;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 50px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

三个 .item 元素在垂直方向(交叉轴)上会从容器底部开始对齐。

  • center:子元素在交叉轴上居中对齐。在水平主轴情况下,子元素在容器垂直方向中心对齐;在垂直主轴情况下,子元素在容器水平方向中心对齐。
.container {
  display: flex;
  align-items: center;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  height: 50px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

此代码中,三个 .item 元素在垂直方向(交叉轴)上会在容器中心位置对齐。

  • baseline:子元素根据它们的基线在交叉轴上对齐。基线是文本在一行中所处的假想线,字母大多都坐落在这条线上。当多个子元素包含文本时,使用 baseline 对齐可以使它们的文本基线对齐。
.container {
  display: flex;
  align-items: baseline;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.item {
  width: 100px;
  padding: 10px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">短文本</div>
  <div class="item">较长的文本较长的文本</div>
  <div class="item">更更长的文本更更长的文本更更长的文本</div>
</div>

在这个例子中,三个 .item 元素内的文本基线会对齐,即使它们的高度因文本长度不同而有所差异。

4. justify-content 与 align-items 的组合使用

在实际开发中,justify-contentalign-items 通常会组合使用,以实现各种复杂且精确的布局效果。例如,要创建一个水平和垂直方向都居中的按钮组,可以这样写:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
  border: 1px solid black;
  width: 300px;
  height: 150px;
}
.button {
  width: 80px;
  height: 40px;
  background-color: lightgreen;
  margin: 10px;
}
<div class="container">
  <button class="button">按钮1</button>
  <button class="button">按钮2</button>
  <button class="button">按钮3</button>
</div>

在上述代码中,justify-content: center 使按钮在水平方向(主轴)上居中,align-items: center 使按钮在垂直方向(交叉轴)上居中。

再比如,创建一个商品展示列表,商品图片在顶部左对齐,商品名称在图片下方左对齐,价格在商品名称下方右对齐,可以使用如下代码:

.product-container {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  border: 1px solid gray;
  width: 200px;
  padding: 10px;
  margin: 10px;
}
.product-image {
  width: 100%;
  height: 150px;
  background-color: lightblue;
  margin-bottom: 10px;
}
.product-name {
  width: 100%;
  text-align: left;
  margin-bottom: 5px;
}
.product-price {
  width: 100%;
  text-align: right;
}
<div class="product-container">
  <div class="product-image"></div>
  <span class="product-name">商品名称</span>
  <span class="product-price">99元</span>
</div>

这里,flex-direction: column 设置主轴为垂直方向,justify-content: flex-start 使子元素在垂直主轴上从顶部开始排列,align-items: flex-start 使子元素在水平交叉轴上从左侧开始排列,从而实现了特定的布局效果。

5. 在响应式布局中的应用

随着移动设备的普及,响应式布局成为前端开发的重要需求。justify-contentalign-items 在响应式布局中发挥着关键作用。通过媒体查询(Media Queries),可以根据不同的设备屏幕尺寸动态调整布局。

例如,在一个导航栏布局中,当屏幕宽度大于 768px 时,导航项水平排列且均匀分布,垂直方向居中;当屏幕宽度小于等于 768px 时,导航项垂直排列且左对齐,垂直方向从顶部开始排列。代码如下:

.navbar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  background-color: lightgray;
  padding: 10px;
}
.nav-item {
  padding: 10px 20px;
  text-decoration: none;
  color: black;
}
@media (max - width: 768px) {
 .navbar {
    flex - direction: column;
    justify-content: flex-start;
    align-items: flex-start;
  }
}
<nav class="navbar">
  <a href="#" class="nav-item">首页</a>
  <a href="#" class="nav-item">产品</a>
  <a href="#" class="nav-item">关于我们</a>
  <a href="#" class="nav-item">联系我们</a>
</nav>

在大屏幕上,justify-content: space-aroundalign-items: center 使导航项均匀分布且垂直居中;在小屏幕上,通过媒体查询改变 flex-direction 为垂直方向,并调整 justify-contentalign-items 的值,实现导航项的垂直排列和左对齐。

6. 与其他 CSS 布局属性的关系

justify-contentalign-items 虽然是弹性盒模型中的重要属性,但它们并不是孤立存在的。它们与其他 CSS 布局属性,如 flex-wrapalign-content 等密切相关,共同构建出复杂多样的布局。

6.1 flex-wrap

flex-wrap 属性决定了弹性子元素在弹性容器内是否换行。默认情况下,子元素会在一行(或一列,取决于 flex-direction)内排列,如果空间不足,子元素会收缩以适应容器。通过设置 flex-wrap: wrap,子元素在空间不足时会换行排列。这与 justify-contentalign-items 相互影响,例如当子元素换行后,justify-content 在每一行(或列)上依然起作用,而 align-items 决定了换行后各行(或列)在交叉轴上的对齐方式。

.container {
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
  border: 1px solid black;
  width: 300px;
  height: 200px;
}
.item {
  width: 100px;
  height: 80px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>

在这个例子中,由于容器宽度有限,flex-wrap: wrap 使子元素换行排列,justify-content: space-around 确保每行的子元素均匀分布,align-items: center 使每行子元素在垂直方向居中。

6.2 align-content

align-content 属性用于多根轴线(当 flex-wrap: wrap 时会产生多根轴线)的对齐方式,它与 align-items 的作用类似,但 align-items 作用于单个子元素在交叉轴上的对齐,而 align-content 作用于多根轴线在交叉轴上的对齐。例如,当设置 align-content: space-between 且子元素换行时,各轴线之间的间隔会均匀分布,两端的轴线与容器边缘贴合。

.container {
  display: flex;
  justify-content: space-around;
  align-content: space-between;
  flex-wrap: wrap;
  border: 1px solid black;
  width: 300px;
  height: 200px;
}
.item {
  width: 100px;
  height: 80px;
  background-color: lightblue;
  margin: 10px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>

在这个代码中,当子元素换行后,align-content: space-between 使各行在垂直方向上均匀分布,上下两端的行分别贴合容器的上下边缘。

7. 兼容性与优化

虽然弹性盒模型已经得到了广泛支持,但在实际开发中,仍需考虑兼容性问题。不同浏览器对弹性盒模型的支持程度和语法略有差异。为了确保在各种浏览器中都能呈现预期的布局效果,通常需要添加浏览器前缀。例如:

.container {
  display: -webkit - flex; /* Safari */
  display: -moz - flex; /* Firefox */
  display: -ms - flex; /* IE */
  display: -o - flex; /* Opera */
  display: flex;
  justify-content: center;
  align-items: center;
}

此外,在使用 justify-contentalign-items 时,为了优化页面性能,应尽量避免过度复杂的布局嵌套。过多的弹性容器嵌套可能会导致浏览器渲染性能下降,尤其是在移动设备上。尽量采用简洁明了的布局结构,合理利用弹性盒模型的属性,既能实现美观的页面布局,又能保证良好的性能体验。

同时,在进行响应式布局时,通过合理设置断点(Breakpoints),根据不同设备尺寸调整布局,可以避免在小屏幕上出现元素拥挤或布局错乱的情况,提高用户体验。

综上所述,深入理解 justify-contentalign-items 的作用,结合其他 CSS 布局属性,充分考虑兼容性和性能优化,能够帮助前端开发者构建出高效、美观且响应式的网页布局。在实际项目中,不断实践和探索这些属性的应用场景,将有助于提升前端开发的技能和水平。