如何用CSS flexbox创建一个响应式的图片库

481 阅读9分钟

图库提供了一种有效的方式来展示高质量的图片集。在网络项目中,开发人员创建图片库,以网格状的布局显示图片,使用户更容易浏览它们

有几种方法可以创建这种类型的布局。在本教程中,我们将介绍如何使用CSS灵活盒式布局模块(flexbox)来创建一个在所有设备上看起来都很好的响应式图片库。

我们将使用三个示例项目来演示Flexbox如何让我们创建各种布局。

在本教程中。

第一个和第二个项目无需使用CSS媒体查询就能自然响应,这是flexbox的好处之一。然而,第二和第三个项目通过保持图像长宽比提供了更准确的图像预览。

在本教程的最后,我们将了解如何应用flexbox来建立三种类型的响应式图片库布局。

要学习本教程,需要有HTML和CSS的基本知识。

CSS Flexbox概述

Flexbox是一种模型,旨在一次创建一个维度的布局(即行或列)。它提供了对属性的访问,允许你在柔性容器内对准和校正柔性项目

此外,flexbox可以将项目包裹到多行上,以实现类似网格的结构,正如下面的项目示例中所看到的。

当flexbox包装项目时,它将每一行都视为flex容器中的一个单独的flex行。因此,它根据这些项目的大小和该柔性行的可用空间来证明其合理性。在下一节,我们将开始使用。

具有统一图像尺寸的响应式图片库

第一个项目使用一个简单的布局,如下图所示。

Flexbox Project 1 Showing Nine Images Of Equal Dimensions In A Grid Layout

这种画廊布局是统一图像尺寸的理想选择。

为了创建这个第一个flexbox项目,让我们创建一个HTML文件并添加以下标记。

<div class="container">
  <!-- heading text -->
  <ul class="image-gallery">
    <li>
      <img src="https://source.unsplash.com/VWcPlbHglYc/640x416" alt="" />
      <div class="overlay"><span>Image title</span></div>
    </li>
    <!-- other items here -->
  </ul>
</div>

我们使用了一个ul 元素来分组位于li 的图片集合。我们也可以使用另一个元素,例如div 。为了简洁起见,上面的代码块只显示ul 容器中的一个项目。请参阅CodeSandbox上的完整标记

每个li 元素都包含一个img 元素以及一个div 元素,每当我们将鼠标悬停在一个图片上时,就会显示一个叠加。在这个项目中,我们使用免费的图片,并在源URL上附加相等的尺寸以获得相同大小的图片。

目前,没有应用任何样式,所以图片将默认为堆叠在彼此之上。

用flexbox定制响应式图片库布局

现在,我们可以引入flexbox来布置我们的图片。重点是容纳所有图片项目的ul 包装元素。

首先,我们必须通过将display 属性设置为flex ,使ul 包装器成为一个柔性容器。一旦我们这样做,它的直接子元素(li 元素)就会变成柔性项目。

.image-gallery {
  display: flex;
}

现在,所有的柔性项目都立即在主轴上排成一排。默认情况下,主轴是行的尺寸。这种行为是flexbox作为一个单维布局模型的结果。

目前,我们的图片会溢出视口,因为它们无法容纳。我们将通过更新应用于flex容器的样式来解决这个问题。这些样式规则将自动适用于柔性容器的项目。

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

.image-gallery > li {
  flex-basis: 350px; /* width: 350px; */
}

.image-gallery li img {
  object-fit: cover;
  width: 100%;
  height: 100%;
  vertical-align: middle;
  border-radius: 5px;
}

让我们仔细看看应用在flex容器中的样式。

  • flex-wrap 属性确保柔性项目将被包裹到另一行上
  • 值为centerjustify-content 属性将使项目在主轴上居中。
  • gap 属性将在行和列之间设置一个间隙(在本例中,10px )。

我们也给每个弹性项目的初始长度为350px 。对一个图片应用object-fit ,可以保持它的长宽比,并确保它的剪辑适合。最后,布局看起来是这样的。

Last Row Of Flexbox Project 1 Without Image Alignment

最后一行用flexbox对齐

如上所示,最后一行的项目没有与前一行对齐。这是flexbox的一个常见问题。

我们之前提到,当柔性项目被包裹时,每一行都是一个新的柔性行,项目会根据该柔性行的可用空间进行调整。在这种情况下,最后一行的项目是居中的,因为我们将justify-content: center; 到flex container。

一个快速的解决方案是使用::after ,在flex容器中创建一个伪元素。然后,我们可以将flex-basis CSS属性的大小设置为与flex项目的大小相等。

.image-gallery::after {
  content: "";
  flex-basis: 350px;
}

这种方法效果很好。另一种方法是使用CSS网格,一个二维的布局系统

在悬停时显示叠加

假设我们想在用户悬停在图片上时显示一些叠加文本。为了实现这一点,首先更新li ,包括以下样式声明。

.image-gallery > li {
  /* ... */
  position: relative;
  cursor: pointer;
}

然后,更新CSS文件,使其包括以下规则。

.overlay {
  position: absolute;
  width: 100%;
  height: 100%;
  background: rgba(57, 57, 57, 0.502);
  top: 0;
  left: 0;
  transform: scale(0);
  transition: all 0.2s 0.1s ease-in-out;
  color: #fff;
  border-radius: 5px;
  /* center overlay text */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* hover */
.image-gallery li:hover .overlay {
  transform: scale(1);
}

让我们保存并测试我们的项目,以确保它按预期工作。这就是第一个项目的全部内容。请看这里的演示CodeSandbox上的完整代码

保持图像长宽比的响应式图片库

在第二个和第三个示例项目中,我们将创建能保持图像长宽比的布局。

第二个项目的布局将保持图片的长宽比,如下图所示。

Flexbox Project 2 Showing Nine Images With Different Aspect Ratios In A Grid Layout

第二个项目的标记与第一个项目的标记基本相同。不同的是,我们不会像这样将固定尺寸附加到图片的URL上。

<div class="container">
  <!-- heading text -->
  <ul class="image-gallery">
    <li>
      <img src="https://source.unsplash.com/VWcPlbHglYc" alt="" />
      <div class="overlay"><span>Image title</span></div>
    </li>
    <!-- other items here -->
  </ul>
</div>

接下来,我们通过在CSS文件中添加以下内容来引入flexbox和对齐规则。

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.image-gallery > li {
  height: 300px;
  cursor: pointer;
  position: relative;
}

.image-gallery li img {
  object-fit: cover;
  width: 100%;
  height: 100%;
  vertical-align: middle;
  border-radius: 5px;
}

让我们将上述规则与第一个项目进行比较。首先,我们没有在li 弹性项目上定义width ,而是定义了height 。另外,注意我们没有用justify-content 属性来对齐项目。有了这个,布局看起来就像这样。

Images In Flexbox Project 2 Without Justification, Leaving White Space At Top Right

现在,我们可以通过使项目从最初的长度开始增长并填补可用空间来按比例分配图像。让我们更新我们的代码,包括具有正值的flex-grow ,像这样。

.image-gallery > li {
  flex-grow: 1;
  /* ... */
}

默认情况下,flex项目的值为flex-grow: 0,flex-shrink: 1, 和flex-basis: auto 。换句话说,如果没有定义其他尺寸,它们将使用其自然内容尺寸。它们也会从它们的flex-basis 缩减,并且永远不会从它增长。

我们也可以使用flex 简称来实现同样的行为。

.image-gallery > li {
  flex: 1 1 auto; /* or flex: auto; */
  /* ... */
}

现在,柔性项目已经填满了可用空间,我们又遇到了柔性框的最后一行对齐问题。在这种情况下,最后一行的两个项目将增长到占满三列的空间。

为了补救这一行为,我们将再次在flex container上使用::after 伪元素,就像这样。

.image-gallery::after {
  content: "";
  flex-grow: 999;
}

我们可以发挥flex-grow 的价值,以确定适合我们布局的输出。让我们保存我们的文件,并确保它按预期工作。请看这里的演示这里的完整代码。这使我们来到了第二个项目的结尾。

在三栏式布局中保持图像的纵横比

在第二个项目中,我们学习了如何创建一个响应式图片库布局,在不使用媒体查询的情况下保持图片长宽比。然而,使用flexbox与媒体查询,我们可以实现特定的布局,同时仍然保持图像的纵横比。

为了证明这一点,我们将创建第三个响应式图片库项目,它将保持图片长宽比,但采用三栏式布局,像这样。

Flexbox Project 3 Showing Images With Different Dimensions Laid Out In Three Columns

这个响应式图片库将在大屏幕上显示三栏,在小屏幕上显示一栏。为了实现这一点,我们将创建一个包含三列元素的标记,像这样。

<div class="container">
  <!-- heading text -->
  <div class="image-gallery">
    <div class="column">
      <div class="image-item">
        <img src="https://source.unsplash.com/VWcPlbHglYc" alt="" />
        <div class="overlay"><span>Image title</span></div>
      </div>
      <!-- other items here -->
    </div>
    <div class="column">
      <!-- other items here -->
    </div>
    <div class="column">
      <!-- other items here -->
    </div>
  </div>
</div>

每一列都应该包含一个你想显示的图片的列表。为了简洁起见,上面的代码块只显示一张图片。请看CodeSandbox上的完整标记

正如我们从迄今为止使用flexbox的经验中得知的那样,这些列可以成为包含在其中的图像或flex项目的flex容器。同样地,这些列本身也可以是包装元素中的柔性项目。

出于这个原因,我们将应用以下风格规则。

.image-gallery {
  /* Mobile first */
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.image-gallery .column {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.image-item img {
  width: 100%;
  border-radius: 5px;
  height: 100%;
  object-fit: cover;
}

@media only screen and (min-width: 768px) {
  .image-gallery {
    flex-direction: row;
  }
}

从移动布局开始,我们确保所有项目都显示为一个列。与先前的项目不同,我们添加了一个flex-direction 属性,将默认的行对齐方式改为列。

然后,对于大屏幕(min-width: 768px),我们将外部flex容器的方向改为行。

让我们保存我们的文件并确保它的工作。请看CodeSandbox上的完整代码

总结

Flexbox有可能对容器中的项目进行包装、对齐和调整。这使得它在创建类似网格结构的响应式布局时非常方便。

在本教程中,我们用它创建了三个响应式图片库项目,在所有设备上看起来都很不错。