Gatsby: [gatsby-image] fonctionne-t-il avec les images d'arrière-plan ?

Créé le 16 oct. 2017  ·  22Commentaires  ·  Source: gatsbyjs/gatsby

J'adore Gatsby et le composant [gatsby-image] !

Existe-t-il un moyen d'utiliser également [gatsby-image] pour les images d'arrière-plan ? Je crée fréquemment des sections de page avec une image d'arrière-plan ( background-size: cover ) et j'aimerais profiter des fonctionnalités de redimensionnement automatique et d'optimisation de [gatsby-image] pour ce cas d'utilisation.

(Si [gatsby-image] ne peut pas être utilisé pour les images d'arrière-plan, peut-il être utilisé d'une manière ou d'une autre pour simuler background-size: cover ?)

Commentaire le plus utile

D'accord, j'ai fait quelques expériences et j'ai trouvé une solution qui fonctionne pour utiliser gatsby-image pour les images d'arrière-plan. Je voulais partager cela avec toute autre personne bloquée sur ce problème, car les fonctionnalités de gatsby-image sont trop bonnes pour être utilisées uniquement pour les images en ligne !

Voici ce qui a fonctionné pour moi :

1. Ajouter un style CSS

Avant d'ajouter des styles, il est bon de savoir que le composant gatsby-image génère le code HTML suivant :

<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>

Les styles définis directement sur gatsby-image seront appliqués à <div class="gatsby-image-wrapper> . Les styles que nous souhaitons appliquer à l'image elle-même doivent utiliser un sélecteur enfant pour cibler les balises <img> .

Pour que gatsby-image agisse comme une image d'arrière-plan CSS, ajoutez les styles suivants (j'ai utilisé gatsby-plugin-styled-components ici) :

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

Voici une version du même composant BgImage qui utilise des accessoires pour définir les valeurs dynamiques :

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

L'utilisation de !important ici n'est pas idéale, mais nécessaire pour remplacer les styles object-fit/object-position .

Notez que les propriétés object-fit et object-position n'auront pas besoin d'être ajustées à moins que l'image gatsby ne couvre une zone avec une hauteur définie. Pour ces cas d'utilisation, object-fit: cover; généralement toujours pour moi et j'ai juste besoin de modifier la object-position (gatsby-image la définit sur center center par défaut).

2. Ajouter IE9+ Polyfill pour l'ajustement de l'objet/la position de l'objet

Les styles ci-dessus fonctionneront dans tous les navigateurs sauf IE (voir caniuse.com : object-fit/object-position ). Malheureusement, dans IE, object-fit/object-position ne fonctionnent pas, et toute image d'arrière-plan avec une hauteur définie s'étirera pour remplir son conteneur, déformant l'image.

Heureusement, il existe un polyfill qui corrige cela dans IE9+, que vous pouvez trouver ici . (Merci à @fk pour l'avoir signalé.)

Voici comment implémenter le polyfill :

  1. Assurez-vous d'avoir inclus la déclaration supplémentaire font-family dans votre CSS (voir ci-dessus)
  2. Installez le polyfill dans votre projet : npm install —save object-fit-images
  3. Créez un fichier gatsby-browser.js à la racine de votre projet
  4. Ajoutez ce qui suit à gatsby-browser.js :
import objectFitImages from 'object-fit-images'

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

REMARQUE : j'ai activé le polyfill dans onInitialClientRender car les instructions du polyfill sont de placer l'appel d'activation "avant </body> , or _on DOM ready_". Ailleurs, j'ai vu @KyleAMathews recommander que les polyfills soient implémentés dans onClientEntry place, donc je ne sais pas si ce serait mieux (un commentaire, Kyle ?).

J'espère que cela pourra aider!

Tous les 22 commentaires

Super d'entendre que ça marche bien pour toi !

Sur les images d'arrière-plan, consultez le site de démonstration de gatsby-image https://using-gatsby-image.gatsbyjs.org/

Est-ce que c'est ce que tu veux?

Merci pour la réponse rapide!

Juste pour être sûr de comprendre ce qui se passe sur le site de démonstration de gatsby-image...

  1. Au lieu d'utiliser background-image , gatsby-image utilise toujours <img /> et les images d'arrière-plan sont simulées avec position: absolute; ?
  2. Au lieu d'utiliser background-size/background-position pour positionner les images, gatsby-image utilise toujours object-fit/object-position ?

Je suis parfaitement heureux d'utiliser gatsby-image de cette façon pour toutes mes images tant qu'elles s'affichent correctement dans tous les navigateurs modernes... Gatsby inclut-il des mesures pour prendre en charge les propriétés object-fit/object-position dans IE 11 et Edge ( voir les problèmes de prise en charge du navigateur ici : caniuse.com ) ?

Si tel est le cas, recommanderiez-vous d'éviter complètement les images d'arrière-plan CSS (pour profiter du traitement d'image automatisé de Gatsby) ? En utilisant gatsby-image, existe-t-il une approche recommandée pour ajuster les propriétés object-fit/object-position ?

Sinon, existe-t-il un moyen recommandé et multi-navigateurs d'utiliser des images d'arrière-plan avec background-size:cover dans Gatsby ?

@ooloth le composant est très nouveau donc ma réponse à votre question est… s'il vous plaît jouez avec l'utilisation de gatsby-image comme vous le souhaitez et rapportez ce que vous trouvez :-)

Les images d'arrière-plan css sont problématiques car elles ne vous permettent pas d'ajouter (facilement) plusieurs tailles de vignettes pour des appareils de différentes tailles. Mais vous pouvez contourner ce problème avec des requêtes multimédias.

Haha. Entendu. Et fera l'affaire. Merci pour ton aide!

Si quelqu'un d'autre souhaite partager ses meilleures pratiques pour les éléments suivants, je serais très intéressé :

  1. Comment prendre en charge object-fit/object-position dans IE 11 et Edge (Gatsby le fait-il déjà ?)
  2. Comment modifier les valeurs de object-fit/object-position ?

Concernant 1., jetez un œil à https://github.com/bfred-it/object-fit-images

@fk Merci pour le polyfill ! Depuis le 16 octobre, Edge prend en charge object-fit/object-position , mais IE11 a toujours besoin d'aide.

Pouvez-vous s'il vous plaît conseiller sur une chose? Je suis clair sur la façon d'installer et d'importer le polyfill...
npm install --save object-fit-images
import objectFitImages from 'object-fit-images'

..mais je ne sais pas où passer l'appel d'activation :
objectFitImages()

Pouvez-vous s'il vous plaît recommander où placer cette ligne? Je suis un peu nouveau sur React et Gatsby.

(Au fait, j'ai compris comment ajuster les valeurs d'ajustement de l'objet/de position de l'objet et je partagerai ce code dès que j'aurai terminé d'ajouter le polyfill et ses ajustements CSS.)

D'accord, j'ai fait quelques expériences et j'ai trouvé une solution qui fonctionne pour utiliser gatsby-image pour les images d'arrière-plan. Je voulais partager cela avec toute autre personne bloquée sur ce problème, car les fonctionnalités de gatsby-image sont trop bonnes pour être utilisées uniquement pour les images en ligne !

Voici ce qui a fonctionné pour moi :

1. Ajouter un style CSS

Avant d'ajouter des styles, il est bon de savoir que le composant gatsby-image génère le code HTML suivant :

<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>

Les styles définis directement sur gatsby-image seront appliqués à <div class="gatsby-image-wrapper> . Les styles que nous souhaitons appliquer à l'image elle-même doivent utiliser un sélecteur enfant pour cibler les balises <img> .

Pour que gatsby-image agisse comme une image d'arrière-plan CSS, ajoutez les styles suivants (j'ai utilisé gatsby-plugin-styled-components ici) :

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

Voici une version du même composant BgImage qui utilise des accessoires pour définir les valeurs dynamiques :

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

L'utilisation de !important ici n'est pas idéale, mais nécessaire pour remplacer les styles object-fit/object-position .

Notez que les propriétés object-fit et object-position n'auront pas besoin d'être ajustées à moins que l'image gatsby ne couvre une zone avec une hauteur définie. Pour ces cas d'utilisation, object-fit: cover; généralement toujours pour moi et j'ai juste besoin de modifier la object-position (gatsby-image la définit sur center center par défaut).

2. Ajouter IE9+ Polyfill pour l'ajustement de l'objet/la position de l'objet

Les styles ci-dessus fonctionneront dans tous les navigateurs sauf IE (voir caniuse.com : object-fit/object-position ). Malheureusement, dans IE, object-fit/object-position ne fonctionnent pas, et toute image d'arrière-plan avec une hauteur définie s'étirera pour remplir son conteneur, déformant l'image.

Heureusement, il existe un polyfill qui corrige cela dans IE9+, que vous pouvez trouver ici . (Merci à @fk pour l'avoir signalé.)

Voici comment implémenter le polyfill :

  1. Assurez-vous d'avoir inclus la déclaration supplémentaire font-family dans votre CSS (voir ci-dessus)
  2. Installez le polyfill dans votre projet : npm install —save object-fit-images
  3. Créez un fichier gatsby-browser.js à la racine de votre projet
  4. Ajoutez ce qui suit à gatsby-browser.js :
import objectFitImages from 'object-fit-images'

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

REMARQUE : j'ai activé le polyfill dans onInitialClientRender car les instructions du polyfill sont de placer l'appel d'activation "avant </body> , or _on DOM ready_". Ailleurs, j'ai vu @KyleAMathews recommander que les polyfills soient implémentés dans onClientEntry place, donc je ne sais pas si ce serait mieux (un commentaire, Kyle ?).

J'espère que cela pourra aider!

Argh putain, désolé de ne pas être revenu plus tôt @ooloth ! Je suis content que vous l'aillez compris!
Merci d'être revenu et d'avoir écrit vos découvertes ! 👍 ❤️

Mon plaisir!

@stolinski rencontre le même problème dans l'un de ses tutoriels. Il s'y prend autrement :
https://www.youtube.com/watch?v=zhM6C0P7VO0

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

Beaucoup plus simple ! Merci @grod220.

@grod220 c'était facile... Merci

@enten Cela fonctionnerait, mais vous termes de performances d'utiliser gatsby-image pour fournir une version correctement redimensionnée de l'image à chaque taille de fenêtre via les srcset et sizes attributs.

Pour moi, la possibilité d'utiliser gatsby-image pour fournir facilement la copie optimale de chaque image est la meilleure fonctionnalité de Gatsby. Ces avantages ne sont pas disponibles lorsque vous utilisez des images d'arrière-plan CSS.

@ooloth Merci d'avoir couvert cela. Gatsby débutant ici. Dans vos instructions avec le style, où l'image réelle est-elle mentionnée ?

@fucata55 Mon plaisir !

L'image réelle est quelque chose que vous première requête via graphql puis passez comme un accessoire à votre gatsby-image composante fluid ou fixed l'accessoire (ou si vous utilisez v1, son sizes ou resolutions accessoire).

Le composant gatsby-image générera ensuite toutes les copies de l'image dont vous aurez besoin et ajoutera pour vous l'attribut compliqué sizes au <img /> dans le code HTML résultant.

Pour une procédure pas à pas sur la façon d'utiliser gatsby-image (et d'y envoyer une image), consultez les gatsby-image docs ici pour la v2 ou ici pour la v1 (ils sont géniaux).

@ooloth votre travail a été très utile. Merci.

Est-il possible d'utiliser "background-attachment: fixed; " ? Si oui, où exactement. Je peux le faire fonctionner mais pas avec Safari. Lorsque je le fais fonctionner, le comportement est que l'image semble bonne jusqu'à ce que j'ajoute plus de composants dans la page. Plus il y a de composants ajoutés, plus l'image s'agrandit. Donc, alors je polyfill pour le problème de safari mais alors le "background-attachment: fixed; " n'est plus une option, du moins c'est ce qu'il semble. Toute aide grandement appréciée.

@zachgaskin J'aimerais pouvoir aider !

Cela ressemble à un problème CSS (c'est-à-dire non lié à Gatsby ou à gatsby-image ) et je crains de ne pas avoir beaucoup d'expérience avec background-attachment: fixed et de ne pas avoir rencontré le problème que vous re décrire. Si vous êtes en mesure de publier un lien vers une reproduction minimale de ce problème, je serais heureux d'y jeter un coup d'œil, cependant.

Selon caniuse.com , iOS Safari ne prend pas en charge background-attachment: fixed , mais macOS Safari devrait fonctionner (devrait...).

Il peut être très difficile de comprendre pourquoi certains navigateurs traitent le même CSS différemment, alors vous avez toute ma sympathie. Bonne chance!

@zachgaskin @ooloth J'ai rencontré ça aussi. Ce n'est pas idéal, mais la solution que j'ai trouvée consiste à ajouter position: 'fixed' à l'image. Bien que cela signifie qu'il est à l'arrière-plan de toute la page. Vous devez vous assurer que vous avez un arrière-plan spécifié partout ailleurs. Le z-index: -1 s'assurera qu'il est caché derrière vos autres arrière-plans.

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

L'image de fond de Gatsby est un pas en avant...

Vous pourriez trouver utile d'importer gatsby-image directement avec un polyfill IE et de lui appliquer objectFit et objectPosition comme accessoires, au lieu d'utiliser !important dans vos styles

import Img from 'gatsby-image/withIEPolyfill'

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

Merci @AronBe

Je ne travaille pas avec Gatsby pour le moment, donc je ne connais pas la dernière ; cependant, Gatsby Background Image (mentionné ci-dessus) a vraiment fait l'affaire pour moi sur mon dernier projet.

Cette page vous a été utile?
0 / 5 - 0 notes