背景图片缩放

Avatar of Dylan Winn-Brown
Dylan Winn-Brown 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

以下是 Dylan Winn-Brown 的客座文章,他向我们展示了一种实现此设计效果的高性能方法。

最近在为客户的网站工作时,我被要求复制类似于 此效果

容器包含背景图片,鼠标悬停时在容器内缩放,显示更多信息。

这种效果通常用于作品集类型的场景,设计意图是展示视觉和信息细节。

有很多不同的方法

由于我以前从未创建过这样的效果,所以我开始研究不同的实现方式,并发现了许多不同的方法。

一种选择是使用 jQuery 插件。 这个插件的效果不是我想要的,而且肯定不轻量级。

另一种选择是在容器内放置一个 <img> 并用 CSS 操作它。 这可能有一些潜在的好处,比如能够使用 srcset 设置源 以使使用的图片适合性能和设备

在我的情况下,我想完全用 CSS 来管理这个效果,所以我选择了这种方法。

基本功能

为了获得最佳性能,我决定使用 CSS 的 transform 属性来处理图像的放大。(CSS 动画受益于硬件加速,因此看起来比其他动画方法更流畅。)

我没有使用 <img>,而是在父元素内部使用了额外的 <div> 作为图像。 结构如下:

<div class="parent">
  <div class="child"></div>
</div>

首先我们指定父元素的尺寸。 然后子元素可以使用 width: 100%height: 100%; 填充父元素,并设置背景图像,确保它缩放以覆盖区域。

.parent {
  width: 400px; 
  height: 300px;
}

.child {
  width: 100%;
  height: 100%;
  background-color: black; /* fallback color */
  background-image: url("images/city.jpg");
  background-position: center;
  background-size: cover;
}

然后我们向父元素添加悬停效果,这将影响我们的子元素。 焦点样式也对辅助功能很有用。

.parent:hover .child,
.parent:focus .child {
  transform: scale(1.2);
}

您可能希望使用 工具 添加前缀以获得最佳的浏览器支持。

要完成基本效果,我们可以向子元素的正常状态添加一些过渡。

transition: all .5s;

如果要添加颜色叠加层,可以使用伪元素,例如 ::before

.child::before {
  content: "";
  display: none;
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: rgba(52, 73, 94, 0.75);
}

.parent:hover .child:before,
.parent:focus .child:before {
  display: block;
}

现在,当我们悬停在父元素上时,子元素应该显示颜色叠加层!

最后,我们将介绍如何在叠加层上添加一些文本。 我们可以像这样向当前子元素添加一个元素

<div class="parent">
   <div class="child">
      <span>Hello</span>
   </div>
</div>

我们可以为我们的 <span> 设置一些样式

span {
  color: white; /* Good thing we set a fallback color! */
  font-family: sans-serif;
  padding: 25%;
  position: absolute;
}

并且我们可以在悬停在 .parent 上时才使其可见

.parent:hover span,
.parent:focus span {
  display: block;
}

在线演示

查看 CodePen 上 Dylan (@dwinnbrown) 的作品 鼠标悬停时图片缩放 - 作品集网站

移动设备支持

如果容器是链接,并且悬停状态没有显示任何重要信息,您可能只需将其保留。

如果悬停状态很重要,为了使其在触摸屏上正常工作,我们可以在 .parent 容器上使用空的 onclick="" 处理程序。 不幸的是,我没有找到其他方法,但如果您有,请在评论中告诉我!