使用 CSS 网格布局创建的 3 个热门网站英雄 1:营销号召性用语 (CTA) 和图片 2:背景图片上的文本叠加 3:包含副本和表单的两列

2025-05-25

使用 CSS 网格布局创建的 3 个热门网站英雄

1:营销号召性用语(CTA)和图像

2:背景图片上的文本叠加

3:包含副本和表格的两列布局

这是系列文章的第十六篇,该系列文章探讨了过去 13 多年来我作为前端开发者所遇到的各种问题,并提出了相应的解决方案。访问ModernCSS.dev可以查看整个系列文章及其他资源

本集探讨了如何创建网站英雄(又名“标题”),其中一种方式是使用 CSS 网格布局:将其变成画布。


支持通知:这些技术中使用的基本属性 -grid-template-areasobject-fit- 在 IE 16 以下不受支持。好消息 - 这仍然意味着它们大约有 96% 受到支持!

受我多年营销经验的启发,我们将创建以下三种布局:

1:营销号召性用语(CTA)和图像

营销英雄预览

2:背景图片上的文本叠加

文本叠加英雄预览

3:包含副本和表格的两列布局

双列英雄预览

基本 HTML 和 CSS 网格设置

在不久的过去,实现大多数此类布局的方法都需要使用position: absolute

有了电网,我们可以从该解决方案升级并获得响应迅速、动态定位的超能力!

以下是我们的 HTML 起点:

<header>
  <div class="hero__content">
    <h1>Product</h1>
    <p>You really need this product, so hurry and buy it today!</p>
    <a href="#" class="button">Buy Now</a>
  </div>
  <img src="http://placecorgi.com/600" alt="">
</header>
Enter fullscreen mode Exit fullscreen mode

然后,我们将其转变header为网格容器,并创建一个名为“hero”的模板区域:

header {
  display: grid;
  grid-template-areas: "hero";
}
Enter fullscreen mode Exit fullscreen mode

使用模板区域会创建一个单独的命名网格单元。然后,我们创建一条规则,将所有任何类型的子项(得益于通用选择器*)分配到此区域:

header {
  // ...existing styles

  > * {
    grid-area: hero;
  }
}
Enter fullscreen mode Exit fullscreen mode

这是什么魔法?

使用 CSS 网格布局模板区域意味着我们可以获得网格定位的所有优点,这是绝对定位的一大升级!

这指示所有子项共享相同的网格单元,从而有效地将其变成画布。

我们现在可以定义项目居中或相对于彼此和容器的其他位置,而不必进行数学计算百分比,或者遇到媒体查询难​​题来解决绝对定位干扰内容的响应式增长和缩小。

请继续阅读以获取有关我们的标题示例的更多背景信息!

英雄#1:营销号召性用语(CTA)和图像

营销英雄预览

除了基础样式之外,还没有其他样式,所以我们的样式如下:元素左上角对齐,图像层叠在元素上.hero__content

基础营销英雄的初始状态

我们首先要解决的是在标题上设置一些尺寸预期:

header {
  // ...existing styles
  height: 65vh;
  max-height: 600px;
}
Enter fullscreen mode Exit fullscreen mode

诸如此类的视口单位vh是我调整 Hero 尺寸的常用方法。它可以根据设备尺寸动态地调整 Hero 的尺寸,使其与用户的可视区域保持比例。

我们正在限制这个特定的值,以防止图像分辨率过度拉伸max-height,但这是可选的,并且取决于所使用的图像。

接下来,我们需要对img行为提供一些指导。

您可能想知道为什么我们没有使用背景图片。第一个答案是,这样图片就可以保留其语义(包括alt属性),以便辅助技术能够发现。

其次,将其保留为图像可以让我们在设计和定位方面拥有更大的灵活性。

我们将object-fit一起使用object-position,这实际上使其初始行为与背景图像非常相似:

img {
  object-fit: cover;
  object-position: 5vw -5vmin;
  height: min(65vh, 600px);
  width: 60%;
}
Enter fullscreen mode Exit fullscreen mode

很重要,因为它指示它根据这两个值中的“最小值”height: min(65vh, 600px)来填充 的高度,这个“最小值”来自我们在底边 上设置的高度。在给出明确的尺寸参数后,接管并缩放图像内容以“覆盖”包括 在内的尺寸headerheaderobject-fitwidth: 60%

新手 object-fit?查看第 3 集(关于响应式图像)第 6 集(关于动画图像标题)以获取更多示例。

最后,我们将添加justify-selfimg定义它应该放置在end容器的 - 这是我们第一次使用网格来实现这个解决方案的魔力:

img {
  // ...existing styles
  justify-content: end;
}
Enter fullscreen mode Exit fullscreen mode

以下是我们的进展:

营销英雄的形象风格进步

现在对于.hero__content,第一个改进是给它一个宽度定义,并且给它与视口边缘的一些空间:

.hero__content {
  margin-left: 5%;
  max-width: 35%;
  min-width: 30ch;
}
Enter fullscreen mode Exit fullscreen mode

由于我们的img允许宽度为 60%,我们不希望我们的组合margin超过width40%,以避免重叠。

我们还提供了一个功能,min-width以便在视口缩小时为内容保留合理的空间。

现在我们可以再次利用网格,并返回到我们的header规则来添加对齐属性:

header {
  // ...existing styles
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

这会将内容与图片垂直对齐。由于图片的header高度设置为 100%,因此从视觉上来说,这会将内容垂直居中,从而得到适合桌面端的英雄页面:

营销英雄桌面最终定稿

为了使其能够在最小的屏幕上继续工作,我们需要进行一些调整。

首先,我们将图片宽度默认设置为 80%,并将 60% 的缩减量封装在媒体查询中。我们还将添加一个过渡效果,以便在视口调整大小时使其更加平滑:

img {
  // ...existing styles
  width: 80%; // < update
  transition: 180ms width ease-in;

  @media (min-width: 60rem) {
    width: 60%;
  }
}
Enter fullscreen mode Exit fullscreen mode

然后在内容上,我们将使用一些技巧将背景设置为英雄背景的 alpha,以便它只有在开始与图像重叠时才可见,并包括边距的更新,一些填充和一点点border-radius

.hero__content {
  // ...existing styles
  margin: 1rem 0 1rem 5%; // < update
  z-index: 1;
  background-color: rgba(mix(#fff, $primary, 97%), 0.8);
  border-radius: 1rem;
  padding: 0.5rem 0.5rem 0.5rem 0;
}
Enter fullscreen mode Exit fullscreen mode

我们确实需要在那里添加一点,z-index以使其高于img,但这并不是太痛苦!😊

这是最终的移动尺寸视口结果:

营销英雄移动版已完成

英雄 #1 的技术总结

  • object-fit用于控制img尺寸
  • align-items: center用于垂直对齐网格子项

英雄 #1 演示

主角 #2:背景图片上的文字叠加

文本叠加英雄预览

对于具有我们的基本 HTML 和 CSS 样式的此版本,图像完全遮挡了内容,因为它是 jpg,因此没有 alpha。

因此,第一步:将内容置于图像上方:

.hero__content {
  z-index: 1;
}
Enter fullscreen mode Exit fullscreen mode

接下来,我们将定义标题尺寸:

header {
  // ...existing styles
  height: 60vh;
  max-height: 600px;
}
Enter fullscreen mode Exit fullscreen mode

再次,我们将使用它object-fit来控制我们的img。这次的不同之处在于我们希望它跨越 100% 的宽度高度,以便完全覆盖标题:

img {
  object-fit: cover;
  height: min(60vh, 600px);
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

在展示进度镜头之前,让我们先调整一下网格子项的对齐方式:

header {
  // ...existing styles
  place-items: center;
}
Enter fullscreen mode Exit fullscreen mode

目前的结果如下:

英雄#2 的进展

很明显,文本与背景图像的对比度不够。一种常见的方法是给图像添加彩色滤光,既能增强品牌形象,又能帮助解决对比度问题。

以下是我们实现此目的的一个小技巧 - 首先,header接收background-color包含 alpha 透明度的:

$primary: #3c87b3;

header {
  // ...existing styles
  background-color: rgba($primary, 0.7);
}
Enter fullscreen mode Exit fullscreen mode

然后,我们用 控制图片滑到页眉后面z-index。在我的测试中,这仍然可以img让辅助技术发现图片,但如果您发现任何问题,请与我们联系!

img {
  // ...existing styles
  z-index: -1;
}
Enter fullscreen mode Exit fullscreen mode

结果是:

英雄二号基地竣工

为了进一步演示使用网格可以实现的功能,让我们创建一个:before:after元素来header保存 SVG 模式。

需要注意的是,还要将伪元素赋值给grid-area: hero。否则,它们会根据默认网格流作为新的“行”插入,从而破坏我们的画布。

&::before {
  content: "";
  grid-area: hero;
  width: 50vmin;
  height: 50vmin;
  border-radius: 50%;
  transform: translate(-10%, -10%);
  background-image: url("data:image/svg+xml,%3Csvg width='14' height='14' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='#{svgColor($support)}' fill-opacity='0.6' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
}

&::after {
  content: "";
  grid-area: hero;
  width: 30vmin;
  height: 60vmin;
  transform: translate(20%, 40%) rotate(45deg);
  background-image: url("data:image/svg+xml,%3Csvg width='14' height='14' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='#{svgColor($support)}' fill-opacity='0.6' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
}
Enter fullscreen mode Exit fullscreen mode

根据place-items: center定义,结果如下:

添加了伪元素的英雄

要解决的第一个问题是溢出,我们将使用以下方法修复它:

header {
  // ...existing styles
  overflow: hidden;
}
Enter fullscreen mode Exit fullscreen mode

接下来,网格提供了self一些属性来控制特定项目是否可以重新定位,这打破了它与网格父级的定义。因此,我们将相应地更新伪元素:

&::before {
  // ...existing styles
  place-self: start;
}

&::after {
  // ...existing styles
  place-self: end;
}
Enter fullscreen mode Exit fullscreen mode

这样,我们就完成了第二个英雄!测试一下 demo,看看小视口版本是否还能正常工作:

完成英雄#2

英雄 #2 的技术总结

  • img通过定义background-color添加到将其滑到后面,header上方创建了一个彩色屏幕rgbaz-index: -1imgheader
  • 使用伪元素来增加设计感,并将它们与父网格定义分开放置place-self

英雄 #2 演示

英雄#3:带有副本和表格的双列布局

双列英雄预览

对于第三个示例,我们的基础 HTML 稍作修改以添加到表单中。我们还包含一个围绕主要内容的包装器,稍后我们将对其进行解释:

<header>
  <div class="hero__wrapper">
    <div class="hero__content">
      <h1>Product</h1>
      <p>You really need this product, so hurry and buy it today!</p>
    </div>
    <div class="hero__form">
      <h2>Subscribe to Our Updates</h2>
      <form action="/">
        <label for="email">Enter your email:</label>
        <input id="email" name="email" type="email" />
        <button class="button" type="submit">
          Subscribe
        </button>
      </form>
    </div>
  </div>
</header>
Enter fullscreen mode Exit fullscreen mode

这里是我们开始的外观,使用了我们已经学过的东西:headerSVG 模式伪元素已经使用place-self: end,表单样式已经完好无损(剧透:那也是使用网格!),并且溢出也已经被控制:

首发英雄#3出场

让我们从创建类开始解决这个问题.hero__wrapper。一个重要的更新是设置它的宽度,100vw以便它作为包含元素完全覆盖标题。我们还将继续将其创建为网格容器:

.hero__wrapper {
  width: 100vw;
  display: grid;
}
Enter fullscreen mode Exit fullscreen mode

接下来,是时候定义网格列了。我们将使用我最喜欢的技术,该技术已在多集节目中介绍过,用于实现内在响应式网格列:

.hero__wrapper {
  // ...existing styles
  grid-template-columns: repeat(auto-fit, minmax(30ch, auto));
  grid-gap: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

在第 8 集中了解有关此技术的更多信息:替换 12 列网格的解决方案

我们使用auto来表示最大允许宽度,而不是 ,1fr因为我们不希望列宽相等,而是希望列根据其相对大小按比例扩展。这样做是为了在文本内容和表单之间实现更好的视觉平衡,并且可以根据个人喜好进行调整。如果您希望列宽相等,请使用1fr而不是auto

应用了 grid-template-columns 的英雄 #3

让我们花一点时间来讨论一下底部渐变边框 - 它是如何定位的?

它是:after上的元素header,也是我们使用包装器包裹主标题内容的主要原因。它被定位在 上place-self: end,其宽度由自然拉伸行为决定。查看演示,了解其样式的极简性。

好的,现在我们需要在内容周围添加一些间距。在其他 Heroes 中,我们应用了 ,height但这并不能完全满足我们的需求,因为在较小的视口中,表单和内容会垂直堆叠。

相反,这对于好老 来说是一个更好的工作padding。我们将它放在 上,.hero__wrapper以免影响 SVG 图案或渐变边框的位置:

.hero__wrapper {
  // ...existing styles
  padding: 10vmin 2rem;
}
Enter fullscreen mode Exit fullscreen mode

使用视口单位vmin作为顶部和底部填充意味着将使用“view-width”或“view-height”中较小的一个作为该值。这样做的好处是,有助于确保 Hero 不会覆盖较小视口的整个屏幕,这可能会使页面看起来没有额外的内容。这是因为在这种情况下,将使用“view-width”,使其值较小,而在较大的桌面视口中,将使用“view-height”,使其值较大。

为了完成大视口的外观,我们将向包装器添加两个定位值:

.hero__wrapper {
  // ...existing styles
  align-items: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

其中align-items提供垂直对齐,并justify-content提供水平对齐。

完成了英雄#3的大视口外观

在较小的视口中,我们唯一的调整就是确保内容在 SVG 图案上仍然清晰可读。我们将使用与英雄 #1 类似的技术:

.hero__wrapper {
  // ...existing styles
  z-index: 1;
}

.hero__content {
  background-color: rgba(scale-color($primary, $lightness: 90%), 0.8);
  border-radius: 8px;
}
Enter fullscreen mode Exit fullscreen mode

移动端风格调整后的英雄#3

英雄#3 技巧总结

  • 使用包装器为内容与header设计元素提供辅助网格布局
  • 创建自动宽度列grid-template-columns
  • 利用vmin最小化较小视口的填充,并增加较大视口的填充

英雄#3 演示

奖励:使用clamp缩小段落副本以适应视口大小,从而缩小段落副本以适应较小的视口。

文章来源:https://dev.to/5t3ph/3-popular-website-heroes-created-with-css-grid-layout-4fdl
PREV
面向所有 Web 开发者的 Hacktoberfest 项目:Style Stage
NEXT
如何使用 JavaScript 创建 NFT