使用 Flexbox 设计产品页面布局

Avatar of Levin Mejia
Levin Mejia

DigitalOcean 提供适用于您旅程各个阶段的云产品。立即开始使用 价值 200 美元的免费积分!

我每天都在 Shopify合作伙伴 交谈,他们不断突破电商设计领域的界限。最近,我注意到许多设计师都在他们的商店中尝试使用 Flexbox。作为网页设计师和开发人员,我们的主要目标之一是将重点放在内容上,并让访问者轻松浏览这些内容。为了实现这一目标,我们需要一个有效的布局,让技术退居幕后,让内容成为主角。

Flexbox 可以帮助我们创建灵活的布局,这些布局针对网页和移动设备进行了优化。但我们真的在使用它吗?我们中的许多人仍然在使用浮动和内联块进行布局。当然,您最了解您的受众,因此,如果您有大量用户使用 IE 9 及更低版本,并且没有准备创建可接受的回退体验,您可能会被困在浮动世界中。但是,如今 Flexbox 已经获得了大量的支持(支持)。

我相信实践出真知的理念。本文将带您了解最近发布的名为 Venture 的免费 Shopify 主题,以及使用 Flexbox 重新创建以下产品布局的步骤。

如果您想在本文中使用示例,请 查看完整的 Pen

在本教程文章中,我将演示如何使用 Flexbox 创建灵活且响应式的产品布局,该布局将根据视窗宽度以独特的方式将重点放在产品上。此外,我们将在不到 100 行 CSS 代码内完成所有操作。

这是基于“Venture”主题的

Shopify 的主题设计团队最近为 Shopify 商家发布了一个非常棒的模板,名为 Venture。该布局针对最佳购物体验进行了优化,并清晰地突出了产品。虽然该布局是为适应多种业务案例而开发的,但在此教程示例中,我们将重点关注布局的核心,并使用 Flexbox 重新创建它。在以下步骤中,我们将学习如何水平居中对齐元素、设置完美的粘性页脚、根据视窗和设备优先显示某些产品、使用媒体查询定位 Flexbox 元素,以及学习有关 Flexbox 的基础知识,以便您可以在下一个 Web 项目中开始实施 Flexbox 布局。

如果您想在 Shopify 商店(包含真实产品)上使用本文中的代码示例,请注册成为 Shopify 合作伙伴并设置一个免费的开发商店。开发商店为您提供了访问 Shopify 商店所有付费功能的权限,因此您可以将其用作沙盒环境来进行实验或为客户制作主题。

页眉布局

我们要做的第一件事是设置我们的筛选导航,其中包含我们的标题和两个带有标签的筛选元素(下拉菜单)。

让我们从设置一个带有其内容的 Flexbox 容器开始。

<nav class="product-filter">

  <h1>Jackets</h1>

  <div class="sort">

    <div class="collection-sort">
      <label>Filter by:</label>
      <select>
        <option value="/">All Jackets</option>
      </select>
    </div>

    <div class="collection-sort">
      <label>Sort by:</label>
      <select>
        <option value="/">Featured</option>
      </select>
    </div>

  </div>

</nav>

我们的 .product-filter 将成为我们的 Flex 容器,因此我们可以相应地对齐 Flex 项目子元素。我们如下声明 Flex 容器:

.product-filter {
  display: flex;
}

我们的 <h1> 元素的 flex-grow 值为 1,因此它既扩展 Flex 容器以使其充满整个宽度,又扩展自身以充满剩余空间(这会将排序下拉菜单右对齐)。

.product-filter h1 {
  flex-grow: 1;
}

要水平对齐 .sort container 的子元素,我们也将其设置为 Flex 容器。您可以嵌套 Flex 容器!

.sort {
  display: flex;
}

排序容器(<div>)默认情况下会堆叠在一起。

默认情况下,display: flex; 会水平对齐子元素。我们将对排序容器使用它来水平对齐它们。我们还将使每个单独的排序容器成为 Flex 容器(第三个嵌套 Flex 容器!),并也使用 flex-direction: column; 来对筛选器进行垂直对齐。

.collection-sort {
  display: flex;
  flex-direction: column;
}

在几行 CSS 代码中,我们的标题和筛选器就以我们想要的方式设计好了。现在,凭借我们目前对 Flexbox 的了解,我们将着手设计产品的网格布局。

产品布局

我们将使用以下 HTML 来创建 Flexbox 布局。

<section class="products">

  <!-- It's likely you'll need to link the card somewhere. You could add a button in the info, link the titles, or even wrap the entire card in an <a href="..."> -->

  <div class="product-card">
    <div class="product-image">
      <img src="assets/img/coat-01.jpeg">
    </div>
    <div class="product-info">
      <h5>Winter Jacket</h5>
      <h6>$99.99</h6>
    </div>
  </div>

  <!-- more products -->

</section>

与之前一样,我们需要一个 Flex 容器。在本例中,我们将使用 .products 作为我们的 Flex 容器。我们将添加两个新属性,这些属性将允许 Flex 子元素水平对齐,并在视窗宽度扩展和收缩时换行到新行。

.products {
  display: flex;
  flex-wrap: wrap;
}

默认情况下,display: flex; 会从左侧开始水平排列子元素,但我们添加了 flex-wrap: wrap;,以便在视窗宽度不足以容纳同一行上的所有元素时,将子元素换行到新行。

要开始控制 Flex 项目的宽度,我们将添加 flex: 1;,以便所有 Flex 项目在行中占据相同的空间。在我们的示例中,我们有 10 件夹克产品,添加 flex: 1; 将使所有产品都排列在一行上。

对于我们的设计,我们希望每行 5 个项目,并根据需要将剩余项目换行到新行。要实现每行 5 个项目,它们的宽度需要为 20%(5 * 20 = 100)。设置 flex-basis: 20% 可以解决问题,但当我们考虑填充时,它会超过 100%,我们只会得到每行 4 个项目。使用 2% 的两侧填充和 16% 的 flex-basis 则刚刚好。

.products {
  display: flex;
  flex-wrap: wrap;
}

.product-card {
  padding: 2%;
  flex-grow: 1;
  flex-basis: 16%;

  display: flex; /* so child elements can use flexbox stuff too! */
}

我们也可以使用以下简写形式来实现:

.product-card {
  flex: 1 16%;
}

为产品设置 flex-grow 为 1 将确保产品行始终填满整个空间。

要确保内部图像完美地拟合:

.product-image img {
  max-width: 100%;
}

底部对齐产品页脚

有时设置固定页脚或将内容设置为容器底部可能会很棘手。Flexbox 也可以帮助我们解决这个问题。如果您一直在逐步关注代码,您会发现我们的夹克标签没有完全对齐到夹克图像下方。

由夹克图像的可变高度生成的阶梯效果。

这种情况很常见:我们无法控制内容的高度或长度,但希望另一个元素完全位于容器底部。Flexbox 已经帮助我们保持容器本身在每行具有相同的高度,但图像仍然具有可变高度。

底部对齐的常用方法可能需要使用绝对定位甚至 JavaScript。幸运的是,使用 Flexbox,只需将以下 CSS 添加到我们的 .product-info 容器即可完成这项复杂的任务。

.product-info {
  margin-top: auto;
}

就是这样!Flexbox 足够聪明,可以将元素放置到 Flex 容器的底部。通过几行样式,我们获得了以下结果。

底部对齐效果很好。

响应式 Flexbox

随着可用的水平空间越来越少,我们希望减少每行的产品数量。例如,如果最大视窗为 920 像素,我们希望每行的项目数量限制为 4 个,我们可以通过以下方式实现。

@media (max-width: 920px) {
  .product-card {
    flex: 1 21%;
  }
}

(请记住,它不是 25%(100% / 4),因为我们必须对之前添加的填充进行补偿。我们可以使用 box-sizing: border-box 来避免这种情况,但这取决于您自己的选择。)

之前的 CSS 代码几乎给我们带来了想要的结果,因为我们得到了每行 4 个项目。但是,最后一行有 2 个大项目。

Flexbox 足够聪明,可以填补任何可用空间,这在我们使用其他布局方法时不必担心。为了改善此视窗的布局,我们更希望在顶部而不是底部显示更大的夹克图像,以更好地突出显示产品。

我们可以将第一个而不是最后两个变大的一种方法是选择它们并直接更改其大小。

/* Select the first two */
.products .product-card:first-child, 
.products .product-card:nth-child(2) {
  flex: 2 46%;
}

现在,应用了 CSS 后,我们获得了非常棒的布局,该布局针对较小的视窗(例如纵向模式下的 iPad)进行了优化。

对于更小的视窗,我们更希望使用两列布局来显示夹克。我们可以使用以下媒体查询来实现这种布局。

@media (max-width: 600px) {
  .product-card {
    flex: 1 46%;
  }
}

如果我们现在在较小的视窗(例如 iPhone 6)上查看我们的页面,我们会发现筛选导航栏与我们的标题重叠。

出现这种情况的原因是我们的.product-filter被设置为将所有 flex 项目包含在水平线上,无论它包含多少个项目(不换行)。使用以下代码,我们可以通过媒体查询轻松改变这一点,使我们的内容垂直排列。

@media (max-width: 480px) {
  .product-filter {
    flex-direction: column;
  }
}

我们的标题和过滤器不再重叠,但我们可以通过将过滤器浮动到左侧进一步改进布局。之前,我们使用align-self: flex-end;属性将元素浮动到右侧。现在,我们想要添加align-self: flex-start;

@media (max-width: 480px) {
  .product-filter {
    flex-direction: column;
  }
  .sort {
    align-self: flex-start;
  }
}

就这样,我们现在拥有了产品灵活且响应式的布局。

兼容性

Flexbox 最大的阻力始终是浏览器支持。但正如我们在这篇文章开头提到的,现在的支持已经相当不错了。不再支持 Flexbox 的旧 IE 版本甚至已经不再被微软支持

就像你参与的每一个网页项目一样,你应该始终进行彻底的测试,以确保你的访问者体验优化,并且你的布局满足你的项目需求。

总结

在上面的教程中,我们使用 flexbox 为显示一组产品构建了一个强大的响应式布局。与其他并非旨在构建布局的 CSS 方法不同,flexbox 是一款强大的工具,专注于此目标,你应该充分利用它。Flexbox 布局可以使我们的网站和应用程序更加灵活和稳健。

关于 flexbox,还有很多东西需要了解,所以一定要参考Flexbox 完整指南