¡Amar a Gatsby y al componente [gatsby-image]!
¿Hay alguna forma de usar [gatsby-image] también para imágenes de fondo? Con frecuencia creo secciones de página con una imagen de fondo ( background-size: cover
) y me encantaría aprovechar las funciones de optimización y cambio de tamaño automático de [gatsby-image] para este caso de uso.
(Si [gatsby-image] no se puede usar para imágenes de fondo, ¿se puede usar de alguna manera para simular background-size: cover
?)
¡Es genial saber que está funcionando bien para ti!
En las imágenes de fondo, consulte el sitio de demostración de imágenes de gatsby https://using-gatsby-image.gatsbyjs.org/
¿Es eso lo que quieres?
¡Gracias por la rápida respuesta!
Solo para asegurarme de que entiendo lo que está sucediendo en el sitio de demostración de gatsby-image ...
background-image
, gatsby-image siempre usa <img />
y las imágenes de fondo se simulan usando position: absolute;
?background-size/background-position
para colocar imágenes, gatsby-image siempre usa object-fit/object-position
?Estoy perfectamente feliz de usar gatsby-image de esta manera para todas mis imágenes siempre que se muestren correctamente en todos los navegadores modernos ... ¿Gatsby incluye medidas para admitir las propiedades de ajuste de objeto / posición de objeto en IE 11 y Edge ( ver problemas de soporte del navegador aquí: caniuse.com )?
Si es así, ¿recomendaría que evitemos las imágenes de fondo CSS por completo (para aprovechar el procesamiento de imágenes automatizado de Gatsby)? Usando gatsby-image, ¿hay un enfoque recomendado para ajustar las propiedades de ajuste de objeto / posición de objeto?
Si no es así, ¿existe una forma recomendada en todos los navegadores de utilizar imágenes de fondo con background-size:cover
en Gatsby?
@ooloth, el componente es muy nuevo, así que mi respuesta a su pregunta es ... por favor, juegue con el uso de gatsby-image como desee e informe lo que encuentre :-)
Las imágenes de fondo de CSS son problemáticas porque no le permiten agregar (fácilmente) múltiples tamaños de miniaturas para dispositivos de diferentes tamaños. Pero podría solucionar este problema con consultas de medios.
Ja ja. Comprendido. Y lo haré. ¡Gracias por tu ayuda!
Si alguien más quiere compartir sus mejores prácticas para lo siguiente, estaría muy interesado:
object-fit/object-position
en IE 11 y Edge (¿Gatsby ya hace esto?)object-fit/object-position
?Con respecto a 1., eche un vistazo a https://github.com/bfred-it/object-fit-images
@fk ¡ Gracias por el polyfill! A partir del 16 de octubre, Edge admite object-fit/object-position
, pero IE11 aún necesita ayuda.
¿Puede aconsejarme sobre una cosa? Tengo claro cómo instalar e importar el polyfill ...
npm install --save object-fit-images
import objectFitImages from 'object-fit-images'
... pero no estoy seguro de dónde realizar la llamada de activación:
objectFitImages()
¿Puede recomendarme dónde colocar esta línea? Soy un poco nuevo tanto en React como en Gatsby.
(Por cierto, he descubierto cómo ajustar los valores de ajuste de objeto / posición de objeto y compartiré ese código tan pronto como haya resuelto agregar el polyfill y sus ajustes de CSS).
Muy bien, hice algunos experimentos y encontré una solución funcional para usar gatsby-image para imágenes de fondo. Quería compartir esto con cualquier otra persona que se quede atascada en este problema, ¡ya que las características de gatsby-image son demasiado buenas para usarlas solo para imágenes en línea!
Esto es lo que funcionó para mí:
Antes de agregar estilos, es bueno saber que el componente gatsby-image genera el siguiente 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>
Los estilos establecidos directamente en gatsby-image se aplicarán a <div class="gatsby-image-wrapper>
. Los estilos que queremos aplicar a la imagen en sí deben usar un selector secundario para apuntar a las etiquetas <img>
.
Para hacer que gatsby-image actúe como una imagen de fondo CSS, agregue los siguientes estilos (he usado gatsby-plugin-styled-components aquí):
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
Aquí hay una versión del mismo componente BgImage
que usa accesorios para establecer los valores dinámicos:
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
El uso de !important
aquí no es ideal, pero es necesario para anular los estilos object-fit/object-position
.
Tenga en cuenta que las propiedades object-fit
y object-position
no necesitarán ajustarse a menos que la imagen de gatsby cubra un área con una altura establecida. Para estos casos de uso, object-fit: cover;
generalmente todavía me funciona y solo necesito ajustar el object-position
(gatsby-image lo establece en center center
de forma predeterminada).
Los estilos anteriores funcionarán en todos los navegadores excepto IE (consulte caniuse.com: object-fit / object-position ). Desafortunadamente, en IE, object-fit/object-position
no funcionan, y cualquier imagen de fondo con una altura establecida se estirará para llenar su contenedor, distorsionando la imagen.
Afortunadamente, hay un polyfill que corrige esto en IE9 +, que puede encontrar aquí . (Gracias a @fk por señalar esto).
A continuación, se explica cómo implementar el polyfill:
font-family
en su CSS (ver arriba)npm install —save object-fit-images
gatsby-browser.js
en la raíz de su proyectogatsby-browser.js
:import objectFitImages from 'object-fit-images'
exports.onInitialClientRender = () => {
objectFitImages()
}
NOTA: Activé el polyfill en onInitialClientRender
porque las instrucciones del polyfill son colocar la llamada de activación "antes de </body>
, o _en DOM ready_". En otro lugar, he visto a @KyleAMathews recomendar que los polyfills se implementen en onClientEntry
lugar, así que no estoy seguro de si eso sería mejor (¿algún comentario, Kyle?).
¡Espero que ayude!
¡Maldita sea, perdón por no haber vuelto antes @ooloth! ¡Me alegro de que lo hayas descubierto!
¡Gracias por regresar y escribir sus hallazgos! 👍 ❤️
¡Mi placer!
@stolinski se encuentra con el mismo problema en uno de sus tutoriales. Lo hace de una manera diferente:
https://www.youtube.com/watch?v=zhM6C0P7VO0
<Img
sizes={dataSizes}
style={{
position: "absolute",
left: 0,
top: 0,
width: "100%",
height: "100%"
}}
/>
¡Mucho más sencillo! Gracias @ grod220.
@ grod220 eso fue fácil ... Gracias 😄
@enten Eso funcionaría, pero te perderías las ventajas de rendimiento de usar gatsby-image
para ofrecer una versión de la imagen con el tamaño adecuado en cada tamaño de ventana gráfica a través de srcset
y sizes
atributos.
Para mí, la capacidad de usar gatsby-image
para entregar fácilmente la copia óptima de cada imagen es la mejor característica de Gatsby. Esos beneficios no están disponibles cuando usa imágenes de fondo CSS.
@ooloth Gracias por cubrir esto. Aquí el novato de Gatsby. En sus instrucciones con el estilo, ¿dónde se menciona la imagen real?
@ fucata55 ¡ Mi placer!
La imagen real es algo que primero consulta a través de graphql y luego pasa como un accesorio a su gatsby-image
componente fluid
o fixed
prop (o si usa v1, su sizes
o resolutions
prop).
El componente gatsby-image
generará todas las copias de la imagen que necesitará también y agregará el complicado atributo sizes
al <img />
en el HTML resultante para usted.
Para obtener un tutorial sobre cómo usar gatsby-image
(y enviarle una imagen), consulte los documentos de gatsby-image
aquí para v2 o aquí para v1 (son geniales).
@ooloth tu trabajo ha sido de gran ayuda. Gracias.
¿Es posible utilizar "archivo adjunto de fondo: fijo"? Si es así, dónde exactamente. Puedo hacerlo funcionar, pero no con safari. Cuando lo hago funcionar, el comportamiento es que la imagen se ve bien hasta que agrego más componentes en la página. Cuantos más componentes se agreguen, más grande se vuelve la imagen. Entonces, hago polyfill para el problema del safari, pero luego el "archivo adjunto de fondo: fijo;" ya no es una opción, o eso parece. Cualquier ayuda muy apreciada.
@zachgaskin ¡Ojalá pudiera ayudar!
Esto parece que probablemente sea un problema de CSS (es decir, no relacionado con Gatsby o gatsby-image
) y me temo que no tengo mucha experiencia en el uso de background-attachment: fixed
y no he encontrado el problema. estoy describiendo. Sin embargo, si puede publicar un enlace a una reproducción mínima de este problema, me complacerá echarle un vistazo.
Según caniuse.com , iOS Safari no es compatible con background-attachment: fixed
, pero macOS Safari debería funcionar (debería ...).
Puede ser una verdadera molestia entender por qué ciertos navegadores tratan el mismo CSS de manera diferente, así que tiene mi simpatía. ¡Buena suerte!
@zachgaskin @ooloth También me he encontrado con esto. No es ideal, pero la solución que se me ocurrió es agregar position: 'fixed'
a la imagen. Aunque, esto significa que está en el fondo de toda la página. Debe asegurarse de tener un fondo especificado en todos los demás lugares. El z-index: -1
se asegurará de que esté oculto detrás de sus otros fondos.
<Img
sizes={dataSizes}
style={{
position: "fixed",
left: 0,
top: 0,
width: "100%",
height: "100%",
z-index: -1
}}
/>
La imagen de fondo de Gatsby es un paso adelante ...
Puede resultarle útil importar gatsby-image directamente con un polyfill de IE y aplicar objectFit y objectPosition como accesorios, en lugar de usar! Important en sus estilos
import Img from 'gatsby-image/withIEPolyfill'
<Img
fixed={heroImage.childImageSharp.fixed}
style={{ width: '100%', height: '100%' }}
objectFit="cover"
objectPosition="bottom left"
/>
Gracias, @AronBe
No estoy trabajando con Gatsby en este momento, así que no sé lo último; sin embargo, la imagen de fondo de Gatsby (mencionada anteriormente) realmente me ayudó en mi último proyecto.
Comentario más útil
Muy bien, hice algunos experimentos y encontré una solución funcional para usar gatsby-image para imágenes de fondo. Quería compartir esto con cualquier otra persona que se quede atascada en este problema, ¡ya que las características de gatsby-image son demasiado buenas para usarlas solo para imágenes en línea!
Esto es lo que funcionó para mí:
1. Agregar estilo CSS
Antes de agregar estilos, es bueno saber que el componente gatsby-image genera el siguiente HTML:
Los estilos establecidos directamente en gatsby-image se aplicarán a
<div class="gatsby-image-wrapper>
. Los estilos que queremos aplicar a la imagen en sí deben usar un selector secundario para apuntar a las etiquetas<img>
.Para hacer que gatsby-image actúe como una imagen de fondo CSS, agregue los siguientes estilos (he usado gatsby-plugin-styled-components aquí):
Aquí hay una versión del mismo componente
BgImage
que usa accesorios para establecer los valores dinámicos:El uso de
!important
aquí no es ideal, pero es necesario para anular los estilosobject-fit/object-position
.Tenga en cuenta que las propiedades
object-fit
yobject-position
no necesitarán ajustarse a menos que la imagen de gatsby cubra un área con una altura establecida. Para estos casos de uso,object-fit: cover;
generalmente todavía me funciona y solo necesito ajustar elobject-position
(gatsby-image lo establece encenter center
de forma predeterminada).2. Agregue IE9 + Polyfill para ajuste de objeto / posición de objeto
Los estilos anteriores funcionarán en todos los navegadores excepto IE (consulte caniuse.com: object-fit / object-position ). Desafortunadamente, en IE,
object-fit/object-position
no funcionan, y cualquier imagen de fondo con una altura establecida se estirará para llenar su contenedor, distorsionando la imagen.Afortunadamente, hay un polyfill que corrige esto en IE9 +, que puede encontrar aquí . (Gracias a @fk por señalar esto).
A continuación, se explica cómo implementar el polyfill:
font-family
en su CSS (ver arriba)npm install —save object-fit-images
gatsby-browser.js
en la raíz de su proyectogatsby-browser.js
:NOTA: Activé el polyfill en
onInitialClientRender
porque las instrucciones del polyfill son colocar la llamada de activación "antes de</body>
, o _en DOM ready_". En otro lugar, he visto a @KyleAMathews recomendar que los polyfills se implementen enonClientEntry
lugar, así que no estoy seguro de si eso sería mejor (¿algún comentario, Kyle?).¡Espero que ayude!