Gatsby: [gatsby-image] 是否适用于背景图像?

创建于 2017-10-16  ·  22评论  ·  资料来源: gatsbyjs/gatsby

爱 Gatsby 和 [gatsby-image] 组件!

有没有办法将 [gatsby-image] 也用于背景图像? 我经常使用背景图像 ( background-size: cover ) 创建页面部分,并且很乐意在此用例中利用 [gatsby-image] 的自动调整大小和优化功能。

(如果 [gatsby-image] 不能用于背景图像,是否可以以某种方式用于模拟background-size: cover ?)

最有用的评论

好的,我已经做了一些实验,并找到了一个使用 gatsby-image 作为背景图像的可行解决方案。 我想与其他陷入这个问题的人分享这个,因为 gatsby-image 的功能太好了,不能只用于内联图像!

这是对我有用的:

1. 添加 CSS 样式

在我们添加样式之前,最好知道 gatsby-image 组件输出以下 HTML:

<div class="gatsby-image-outer-wrapper">
  <div class="gatsby-image-wrapper">
    <div></div>
    <!-- Placeholder (hidden after main image loads) -->
    <img style="...object-fit: cover; object-position: center center;">
    <!-- Main image -->
    <img style="...object-fit: cover; object-position: center center;">
  </div>
</div>

直接在 gatsby-image 上设置的样式将应用于<div class="gatsby-image-wrapper> 。 我们要应用于图像本身的样式需要使用子选择器来定位<img>标签。

要使 gatsby-image 像 CSS 背景图像一样,请添加以下样式(我在这里使用了gatsby-plugin-styled-components ):

import React from 'react'
import Image from 'gatsby-image'
import styled from 'styled-components'

const BgImage = styled(Image)`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: -1;
  height: 100vh; // or whatever

  // Adjust image positioning (if image covers area with defined height) and add font-family for polyfill
  & > img {
    object-fit: cover !important; // or whatever
    object-position: 0% 0% !important; // or whatever
    font-family: 'object-fit: cover !important; object-position: 0% 0% !important;' // needed for IE9+ polyfill
  }
`

export default BgImage

这是使用 props 设置动态值的相同BgImage组件的一个版本:

import React from 'react'
import Image from 'gatsby-image'
import styled from 'styled-components'

const BgImage = styled(Image)`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: -1;
  height: ${props => props.height || 'auto'};

  // Adjust image positioning (if image covers area with defined height) and add font-family for polyfill
  & > img {
    object-fit: ${props => props.fit || 'cover'} !important;
    object-position: ${props => props.position || '50% 50%'} !important;
    font-family: 'object-fit: ${props => props.fit || 'cover'} !important; object-position: ${props => props.position || '50% 50%'} !important;'
  }
`

export default BgImage

此处使用!important并不理想,但必须覆盖内联object-fit/object-position样式。

请注意,除非 gatsby-image 覆盖具有设置高度的区域,否则不需要调整object-fitobject-position属性。 对于这些用例, object-fit: cover;通常仍然适用于我,我只需要调整object-position值(默认情况下 gatsby-image 将其设置为center center )。

2. 添加IE9+ Polyfill for object-fit/object-position

上述样式适用于除 IE 之外的所有浏览器(请参阅caniuse.com:object-fit/object-position )。 不幸的是,在 IE 中, object-fit/object-position不起作用,任何具有设置高度的背景图像都会拉伸以填充其容器,从而扭曲图像。

幸运的是,IE9+ 中有一个 polyfill 修复了这个问题,你可以在这里找到。 (感谢@fk指出这一点。)

以下是实现 polyfill 的方法:

  1. 确保您在 CSS 中包含了额外的font-family声明(见上文)
  2. 在你的项目中安装 polyfill: npm install —save object-fit-images
  3. 在项目的根目录中创建一个gatsby-browser.js文件
  4. 将以下内容添加到gatsby-browser.js
import objectFitImages from 'object-fit-images'

exports.onInitialClientRender = () => {
  objectFitImages()
}

注意:我在onInitialClientRender激活了 polyfill,因为 polyfill 的说明是将激活调用“放在</body> ,或者 _on DOM ready_”。 在其他地方,我看到@KyleAMathews建议在onClientEntry实现polyfill ,所以我不确定这是否会更好(任何评论,Kyle?)。

希望有帮助!

所有22条评论

很高兴听到它对你有用!

关于背景图片,请查看 gatsby-image 演示站点https://using-gatsby-image.gatsbyjs.org/

那是你要的吗?

感谢您的快速回复!

只是为了确保我了解 gatsby-image 演示站点上发生的事情......

  1. gatsby-image 始终使用<img />而不是使用background-image ,并且使用position: absolute;模拟背景图像?
  2. gatsby-image 总是使用object-fit/object-position而不是使用background-size/background-position来定位图像?

我很高兴以这种方式将 gatsby-image 用于我的所有图像,只要它们在所有现代浏览器中都能正确显示...... Gatsby 是否包含支持 IE 11 和 Edge 中的对象适合/对象位置属性的措施(在此处查看浏览器支持问题: caniuse.com )?

如果是这样,您是否建议我们完全避免使用 CSS 背景图像(以利用 Gatsby 的自动图像处理)? 使用 gatsby-image,是否有推荐的方法来调整对象适合/对象位置属性?

如果没有,是否有推荐的跨浏览器方式在 Gatsby 中使用带有background-size:cover背景图像?

@ooloth该组件非常新,所以我对您问题的回答是……请随意使用 gatsby-image 并报告您的发现:-)

css 背景图像是有问题的,因为它们不允许您(轻松)为不同尺寸的设备添加多个缩略图尺寸。 但是您可以使用媒体查询来解决这个问题。

哈哈。 明白了。 并且会做。 谢谢你的帮助!

如果其他人想分享他们以下方面的最佳实践,我会非常感兴趣:

  1. 如何在 IE 11 和 Edge 中支持object-fit/object-position (Gatsby 已经这样做了吗?)
  2. 如何调整object-fit/object-position值?

@fk感谢您的object-fit/object-position ,但 IE11 仍然需要一些帮助。

你能就一件事提出建议吗? 我很清楚如何安装和导入 polyfill...
npm install --save object-fit-images
import objectFitImages from 'object-fit-images'

..但我不确定在哪里放置激活调用:
objectFitImages()

你能推荐一下把这条线放在哪里吗? 我对 React 和 Gatsby 都有些陌生。

(顺便说一句,我已经找到了如何调整 object-fit/object-position 值的方法,并且会在我整理好添加 polyfill 及其 CSS 调整后立即共享该代码。)

好的,我已经做了一些实验,并找到了一个使用 gatsby-image 作为背景图像的可行解决方案。 我想与其他陷入这个问题的人分享这个,因为 gatsby-image 的功能太好了,不能只用于内联图像!

这是对我有用的:

1. 添加 CSS 样式

在我们添加样式之前,最好知道 gatsby-image 组件输出以下 HTML:

<div class="gatsby-image-outer-wrapper">
  <div class="gatsby-image-wrapper">
    <div></div>
    <!-- Placeholder (hidden after main image loads) -->
    <img style="...object-fit: cover; object-position: center center;">
    <!-- Main image -->
    <img style="...object-fit: cover; object-position: center center;">
  </div>
</div>

直接在 gatsby-image 上设置的样式将应用于<div class="gatsby-image-wrapper> 。 我们要应用于图像本身的样式需要使用子选择器来定位<img>标签。

要使 gatsby-image 像 CSS 背景图像一样,请添加以下样式(我在这里使用了gatsby-plugin-styled-components ):

import React from 'react'
import Image from 'gatsby-image'
import styled from 'styled-components'

const BgImage = styled(Image)`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: -1;
  height: 100vh; // or whatever

  // Adjust image positioning (if image covers area with defined height) and add font-family for polyfill
  & > img {
    object-fit: cover !important; // or whatever
    object-position: 0% 0% !important; // or whatever
    font-family: 'object-fit: cover !important; object-position: 0% 0% !important;' // needed for IE9+ polyfill
  }
`

export default BgImage

这是使用 props 设置动态值的相同BgImage组件的一个版本:

import React from 'react'
import Image from 'gatsby-image'
import styled from 'styled-components'

const BgImage = styled(Image)`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: -1;
  height: ${props => props.height || 'auto'};

  // Adjust image positioning (if image covers area with defined height) and add font-family for polyfill
  & > img {
    object-fit: ${props => props.fit || 'cover'} !important;
    object-position: ${props => props.position || '50% 50%'} !important;
    font-family: 'object-fit: ${props => props.fit || 'cover'} !important; object-position: ${props => props.position || '50% 50%'} !important;'
  }
`

export default BgImage

此处使用!important并不理想,但必须覆盖内联object-fit/object-position样式。

请注意,除非 gatsby-image 覆盖具有设置高度的区域,否则不需要调整object-fitobject-position属性。 对于这些用例, object-fit: cover;通常仍然适用于我,我只需要调整object-position值(默认情况下 gatsby-image 将其设置为center center )。

2. 添加IE9+ Polyfill for object-fit/object-position

上述样式适用于除 IE 之外的所有浏览器(请参阅caniuse.com:object-fit/object-position )。 不幸的是,在 IE 中, object-fit/object-position不起作用,任何具有设置高度的背景图像都会拉伸以填充其容器,从而扭曲图像。

幸运的是,IE9+ 中有一个 polyfill 修复了这个问题,你可以在这里找到。 (感谢@fk指出这一点。)

以下是实现 polyfill 的方法:

  1. 确保您在 CSS 中包含了额外的font-family声明(见上文)
  2. 在你的项目中安装 polyfill: npm install —save object-fit-images
  3. 在项目的根目录中创建一个gatsby-browser.js文件
  4. 将以下内容添加到gatsby-browser.js
import objectFitImages from 'object-fit-images'

exports.onInitialClientRender = () => {
  objectFitImages()
}

注意:我在onInitialClientRender激活了 polyfill,因为 polyfill 的说明是将激活调用“放在</body> ,或者 _on DOM ready_”。 在其他地方,我看到@KyleAMathews建议在onClientEntry实现polyfill ,所以我不确定这是否会更好(任何评论,Kyle?)。

希望有帮助!

该死的,抱歉没有早点回来@ooloth! 恭喜你弄明白了!
感谢您回来写下您的发现! 👍❤️

我的荣幸!

@stolinski在他的一个教程中遇到了同样的问题。 他以不同的方式处理它:
https://www.youtube.com/watch?v=zhM6C0P7VO0

<Img
  sizes={dataSizes}
  style={{
    position: "absolute",
    left: 0,
    top: 0,
    width: "100%",
    height: "100%"
  }}
/>

简单多了! 谢谢@grod220。

@grod220这很容易...谢谢你😄

@enten那会起作用,但是您会错过使用gatsby-image通过srcsetsizes在每个视口大小提供适当调整大小的图像版本的性能优势

对我来说,能够使用gatsby-image轻松交付每个图像的最佳副本是 Gatsby 的最佳功能。 当您使用 CSS 背景图像时,这些好处不可用。

@ooloth感谢您的报道。 盖茨比新手在这里。 在您的样式说明中,实际图像在哪里提到?

@fucata55我的荣幸!

实际图像是你首先通过 graphql 查询的东西,然后作为道具传递给你的gatsby-image组件的fluidfixed道具(或者如果使用 v1,它的sizesresolutions道具)。

然后gatsby-image组件将生成您需要的所有图像副本,并将复杂的sizes属性添加到生成的 HTML 中的<img />中。

有关如何使用gatsby-image (并向其发送图像)的演练,请在此处查看 v2 的gatsby-image文档或 v1 的此处(它们很棒)。

@ooloth你的工作非常有帮助。 谢谢你。

是否可以使用“背景附件:固定;”? 如果有,具体在哪里。 我可以让它工作,但不能用 safari。 当我让它工作时,行为是图像看起来不错,直到我在页面中添加更多组件。 添加的组件越多,图片就越大。 所以,然后我为 safari 问题进行了 polyfill,但随后“背景附件:固定;”不再是一个选项,或者看起来如此。 非常感谢任何帮助。

@zachgaskin我希望我能帮忙!

这听起来可能是 CSS 问题(即与 Gatsby 或gatsby-image无关),恐怕我没有太多使用background-attachment: fixed ,也没有遇到您的问题重新描述。 不过,如果您能够发布指向此问题的最小副本的链接,我很乐意查看。

根据caniuse.com ,iOS Safari 不支持background-attachment: fixed ,但 macOS Safari 应该可以工作(应该......)。

弄清楚为什么某些浏览器会以不同的方式处理相同的 CSS 可能真的很痛苦,所以你有我的同情。 祝你好运!

@zachgaskin @ooloth我也遇到过这个。 这并不理想,但我提出的解决方案是将position: 'fixed'到图像中。 虽然,这意味着它在整个页面的背景中。 您需要确保在其他任何地方都指定了背景。 z-index: -1将确保它隐藏在您的其他背景后面。

<Img
  sizes={dataSizes}
  style={{
    position: "fixed",
    left: 0,
    top: 0,
    width: "100%",
    height: "100%",
    z-index: -1
  }}
/>

盖茨比背景图片向前迈进了一步......

您可能会发现使用 IE polyfill 直接导入 gatsby-image 并将 objectFit 和 objectPosition 作为道具应用于它很有用,而不是在您的样式中使用 !important

import Img from 'gatsby-image/withIEPolyfill'

<Img
      fixed={heroImage.childImageSharp.fixed}
      style={{ width: '100%', height: '100%' }}
      objectFit="cover"
      objectPosition="bottom left"
   />

谢谢, @AronBe

我目前不在与 Gatsby 合作,所以我不知道最新的; 然而,盖茨比背景图片(上面提到的)确实在我的上一个项目中为我解决了问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

KyleAMathews picture KyleAMathews  ·  3评论

3CordGuy picture 3CordGuy  ·  3评论

andykais picture andykais  ·  3评论

signalwerk picture signalwerk  ·  3评论

brandonmp picture brandonmp  ·  3评论