使用内联图像实现固定背景效果的探索

Avatar of Alex Lazar
Alex Lazar 发布

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

几天前,我在为一个客户项目工作,想要在<img>上创建特定的效果。你看,背景图像可以通过background-attachment: fixed;轻松实现我想要的效果。有了它,背景图像会保持在原位,即使页面滚动也不会移动。它并不经常使用,因此这种效果看起来可能不寻常且醒目,尤其是在谨慎使用时。

目录

我花了一些时间才弄清楚如何仅使用内联图像而不是 CSS 背景图像来实现相同的效果。这是一个演示效果的视频

上面演示的代码 在此 Git 仓库中可用。请注意,这是一个 Next.js 项目。稍后我们会提供一个使用原始 HTML 的 CodePen 示例。

为什么使用<img>而不是background-image

在我的项目中,我想要这样做的原因有很多

  • 更容易延迟加载(例如 <img loading="lazy"… >)。
  • 由于alt文本,它提供了更好的 SEO(更不用说可访问性了)。
  • 可以 使用srcset/sizes 来提高加载性能。
  • 可以 使用<picture>标签 为用户的浏览器选择最佳图像尺寸和格式。
  • 它允许用户下载保存图像(无需使用 DevTools)。

总的来说,在可以使用的情况下最好使用图像标签,特别是如果图像可以被视为内容而不是装饰。因此,我最终使用了一种使用 CSS clip-path 的技术。我们稍后会讲到这一点,在我们首先查看background-image方法以对这两种方法进行并排比较之后。

1. 使用 CSS background-image

这是实现固定滚动效果的“原始”方法。这是 CSS 代码

.hero-section {
  background-image: url("nice_bg_image.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center; 
  background-attachment: fixed;
}

但正如我们刚刚看到的,这种方法在某些情况下并不理想,因为它依赖于 CSS background-image 属性来调用和加载图像。这意味着图像在技术上不被视为内容,因此屏幕阅读器无法识别。如果我们使用的是作为内容一部分的图像,那么我们确实应该使其可访问,以便将其像内容一样而不是像装饰一样使用。

否则,此技术效果很好,但仅在图像跨越视口的整个宽度和/或居中时才有效。如果您在页面右侧或左侧有一个图像(如示例所示),您会遇到很多定位问题,因为background-position相对于视口中心。

修复它需要一些媒体查询来确保它在所有设备上都正确定位。

2. 对内联图像使用clip-path技巧

StackOverflow 上的某人 分享了这个clip-path技巧,它能很好地完成工作。您还可以继续使用<img>标签,如上所述,这在某些情况下可能是有利的,尤其是在图像作为内容的一部分而不是纯装饰的情况下。

这是技巧

.image-container {
  position: relative;
  height: 200px;
  clip-path: inset(0);
}

.image {
  object-fit: cover;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

查看实际效果

现在,在我们急于将此代码片段粘贴到任何地方之前,它也存在自身的一些缺点。例如,对于如此简单的效果,我觉得代码有点冗长。但更重要的是,使用clip-path也有一些影响。例如,我不能像在前面的示例中那样简单地添加border-radius: 10px;来圆化图像的角。这行不通,它需要从裁剪路径本身创建圆角。

另一个例子:我不知道如何在clip-path中定位图像。同样,这可能是非常了解clip-path并将其绘制到所需位置,或根据需要提前裁剪图像本身的问题。

还有更好的方法吗?

就我个人而言,我放弃了在内联图像上使用固定滚动效果,并回到了使用 CSS 背景图像,我知道这有点限制性。

您是否尝试过实现这一点,特别是使用内联图像,并很好地管理它?我很乐意听到您的想法!