Gatsby: Apakah [gatsby-image] berfungsi dengan gambar latar?

Dibuat pada 16 Okt 2017  ·  22Komentar  ·  Sumber: gatsbyjs/gatsby

Mencintai Gatsby dan komponen [gatsby-image]!

Apakah ada cara untuk menggunakan [gatsby-image] untuk gambar latar juga? Saya sering membuat bagian halaman dengan gambar latar belakang ( background-size: cover ) dan ingin memanfaatkan fitur pengubahan ukuran dan pengoptimalan otomatis [gatsby-image] untuk kasus penggunaan ini.

(Jika [gatsby-image] tidak dapat digunakan untuk gambar latar, dapatkah itu digunakan untuk mensimulasikan background-size: cover ?)

Komentar yang paling membantu

Baiklah, saya telah melakukan beberapa percobaan dan telah menemukan solusi yang berfungsi untuk menggunakan gatsby-image untuk gambar latar. Saya ingin berbagi ini dengan siapa pun yang terjebak dalam masalah ini, karena fitur gatsby-image terlalu bagus untuk hanya digunakan untuk gambar sebaris!

Inilah yang berhasil untuk saya:

1. Tambahkan Gaya CSS

Sebelum kita menambahkan gaya, ada baiknya untuk mengetahui bahwa komponen gatsby-image mengeluarkan HTML berikut:

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

Gaya yang disetel langsung di gatsby-image akan diterapkan ke <div class="gatsby-image-wrapper> . Gaya yang ingin kita terapkan pada gambar itu sendiri perlu menggunakan pemilih anak untuk menargetkan tag <img> .

Untuk membuat gatsby-image bertindak seperti gambar latar CSS, tambahkan gaya berikut (saya telah menggunakan gatsby-plugin-styled-components di sini):

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

Berikut adalah versi komponen BgImage yang sama yang menggunakan props untuk menyetel nilai dinamis:

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

Penggunaan !important sini tidak ideal, tetapi perlu untuk mengganti gaya object-fit/object-position sebaris.

Perhatikan bahwa properti object-fit dan object-position tidak perlu disesuaikan kecuali gatsby-image mencakup area dengan ketinggian yang ditentukan. Untuk kasus penggunaan ini, object-fit: cover; biasanya masih berfungsi untuk saya dan saya hanya perlu mengubah nilai object-position (gatsby-image menyetelnya ke center center secara default).

2. Tambahkan IE9+ Polyfill untuk object-fit/object-position

Gaya di atas akan berfungsi di semua browser kecuali IE (lihat caniuse.com: object-fit/object-position ). Sayangnya, di IE, object-fit/object-position tidak berfungsi, dan gambar latar apa pun dengan ketinggian yang ditentukan akan meregang untuk mengisi wadahnya, mendistorsi gambar.

Untungnya, ada polyfill yang memperbaikinya di IE9+, yang dapat Anda temukan di sini . (Terima kasih kepada @fk karena telah menunjukkan hal ini.)

Berikut cara mengimplementasikan polyfill:

  1. Pastikan Anda telah menyertakan deklarasi font-family di CSS Anda (lihat di atas)
  2. Instal polyfill di proyek Anda: npm install —save object-fit-images
  3. Buat file gatsby-browser.js di root proyek Anda
  4. Tambahkan yang berikut ini ke gatsby-browser.js :
import objectFitImages from 'object-fit-images'

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

CATATAN: Saya mengaktifkan polyfill di onInitialClientRender karena instruksi polyfill adalah menempatkan panggilan aktivasi "sebelum </body> , atau _on DOM ready_". Di tempat lain, saya telah melihat @KyleAMthews merekomendasikan agar polyfill diimplementasikan di onClientEntry sebagai gantinya, jadi saya tidak yakin apakah itu akan lebih baik (ada komentar, Kyle?).

Semoga membantu!

Semua 22 komentar

Senang mendengarnya bekerja dengan baik untukmu!

Pada gambar latar belakang, lihat situs demo gatsby-image https://using-gatsby-image.gatsbyjs.org/

Apakah itu yang Anda inginkan?

Terima kasih atas balasan cepatnya!

Hanya untuk memastikan saya mengerti apa yang terjadi di situs demo gatsby-image...

  1. Alih-alih menggunakan background-image , gatsby-image selalu menggunakan <img /> dan gambar latar disimulasikan menggunakan position: absolute; ?
  2. Alih-alih menggunakan background-size/background-position untuk memposisikan gambar, gatsby-image selalu menggunakan object-fit/object-position ?

Saya sangat senang menggunakan gatsby-image dengan cara ini untuk semua gambar saya selama mereka ditampilkan dengan benar di semua browser modern... Apakah Gatsby menyertakan langkah-langkah untuk mendukung properti object-fit/object-position di IE 11 dan Edge ( lihat masalah dukungan browser di sini: caniuse.com )?

Jika demikian, apakah Anda menyarankan agar kami menghindari gambar latar CSS sama sekali (untuk memanfaatkan pemrosesan gambar otomatis Gatsby)? Menggunakan gatsby-image, apakah ada pendekatan yang disarankan untuk menyesuaikan properti objek-fit/posisi-objek?

Jika tidak, apakah ada cara lintas-browser yang direkomendasikan untuk menggunakan gambar latar belakang dengan background-size:cover di Gatsby?

@ooloth komponennya sangat baru jadi jawaban saya untuk pertanyaan Anda adalah ... silakan bermain-main dengan menggunakan gatsby-image sesuka Anda dan laporkan kembali apa yang Anda temukan :-)

gambar latar belakang css bermasalah karena tidak memungkinkan Anda untuk (dengan mudah) menambahkan beberapa ukuran thumbnail untuk perangkat berukuran berbeda. Tetapi Anda dapat mengatasi ini dengan kueri media.

Ha ha. Dipahami. Dan akan melakukannya. Terima kasih atas bantuan Anda!

Jika ada orang lain yang ingin membagikan praktik terbaik mereka untuk hal-hal berikut, saya akan sangat tertarik:

  1. Bagaimana cara mendukung object-fit/object-position di IE 11 dan Edge (apakah Gatsby sudah melakukan ini?)
  2. Bagaimana cara mengubah nilai object-fit/object-position ?

@fk Terima kasih untuk polyfillnya! Pada 16 Oktober, Edge mendukung object-fit/object-position , tetapi IE11 masih membutuhkan bantuan.

Bisakah Anda memberi saran tentang satu hal? Saya jelas tentang cara menginstal dan mengimpor polyfill...
npm install --save object-fit-images
import objectFitImages from 'object-fit-images'

..tapi saya tidak yakin di mana harus menempatkan panggilan aktivasi:
objectFitImages()

Bisakah Anda merekomendasikan di mana menempatkan baris ini? Saya agak baru dalam React dan Gatsby.

(Btw, saya telah menemukan cara untuk menyesuaikan nilai objek-fit/object-position dan akan membagikan kode itu segera setelah saya menyelesaikan penambahan polyfill dan penyesuaian CSS-nya.)

Baiklah, saya telah melakukan beberapa percobaan dan telah menemukan solusi yang berfungsi untuk menggunakan gatsby-image untuk gambar latar. Saya ingin berbagi ini dengan siapa pun yang terjebak dalam masalah ini, karena fitur gatsby-image terlalu bagus untuk hanya digunakan untuk gambar sebaris!

Inilah yang berhasil untuk saya:

1. Tambahkan Gaya CSS

Sebelum kita menambahkan gaya, ada baiknya untuk mengetahui bahwa komponen gatsby-image mengeluarkan HTML berikut:

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

Gaya yang disetel langsung di gatsby-image akan diterapkan ke <div class="gatsby-image-wrapper> . Gaya yang ingin kita terapkan pada gambar itu sendiri perlu menggunakan pemilih anak untuk menargetkan tag <img> .

Untuk membuat gatsby-image bertindak seperti gambar latar CSS, tambahkan gaya berikut (saya telah menggunakan gatsby-plugin-styled-components di sini):

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

Berikut adalah versi komponen BgImage yang sama yang menggunakan props untuk menyetel nilai dinamis:

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

Penggunaan !important sini tidak ideal, tetapi perlu untuk mengganti gaya object-fit/object-position sebaris.

Perhatikan bahwa properti object-fit dan object-position tidak perlu disesuaikan kecuali gatsby-image mencakup area dengan ketinggian yang ditentukan. Untuk kasus penggunaan ini, object-fit: cover; biasanya masih berfungsi untuk saya dan saya hanya perlu mengubah nilai object-position (gatsby-image menyetelnya ke center center secara default).

2. Tambahkan IE9+ Polyfill untuk object-fit/object-position

Gaya di atas akan berfungsi di semua browser kecuali IE (lihat caniuse.com: object-fit/object-position ). Sayangnya, di IE, object-fit/object-position tidak berfungsi, dan gambar latar apa pun dengan ketinggian yang ditentukan akan meregang untuk mengisi wadahnya, mendistorsi gambar.

Untungnya, ada polyfill yang memperbaikinya di IE9+, yang dapat Anda temukan di sini . (Terima kasih kepada @fk karena telah menunjukkan hal ini.)

Berikut cara mengimplementasikan polyfill:

  1. Pastikan Anda telah menyertakan deklarasi font-family di CSS Anda (lihat di atas)
  2. Instal polyfill di proyek Anda: npm install —save object-fit-images
  3. Buat file gatsby-browser.js di root proyek Anda
  4. Tambahkan yang berikut ini ke gatsby-browser.js :
import objectFitImages from 'object-fit-images'

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

CATATAN: Saya mengaktifkan polyfill di onInitialClientRender karena instruksi polyfill adalah menempatkan panggilan aktivasi "sebelum </body> , atau _on DOM ready_". Di tempat lain, saya telah melihat @KyleAMthews merekomendasikan agar polyfill diimplementasikan di onClientEntry sebagai gantinya, jadi saya tidak yakin apakah itu akan lebih baik (ada komentar, Kyle?).

Semoga membantu!

Argh sial, maaf karena tidak kembali lebih awal @ooloth! Senang Anda mengetahuinya!
Terima kasih telah kembali dan menulis temuan Anda! 👍 ❤️

Dengan senang hati!

@stolinski mengalami masalah yang sama di salah satu tutorialnya. Dia melakukannya dengan cara yang berbeda:
https://www.youtube.com/watch?v=zhM6C0P7VO0

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

Jauh lebih sederhana! Terima kasih @grod220.

@grod220 itu mudah... Terima kasih

@enten Itu akan berhasil, tetapi Anda akan kehilangan keuntungan kinerja menggunakan gatsby-image untuk memberikan versi gambar yang diubah ukurannya dengan tepat di setiap ukuran viewport melalui srcset dan sizes atribut

Bagi saya, kemampuan untuk menggunakan gatsby-image untuk mengirimkan salinan optimal setiap gambar dengan mudah adalah fitur terbaik Gatsby. Manfaat tersebut tidak tersedia saat Anda menggunakan gambar latar CSS.

@ooloth Terima kasih telah meliput ini. Gatsby pemula di sini. Dalam instruksi Anda dengan penataan, di mana gambar yang sebenarnya disebutkan?

@fucata55 Dengan senang hati!

Gambar sebenarnya adalah sesuatu yang pertama kali Anda kueri melalui graphql dan kemudian diteruskan sebagai prop ke prop gatsby-image komponen fluid atau fixed (atau jika menggunakan v1, sizes atau resolutions prop).

Komponen gatsby-image kemudian akan menghasilkan semua salinan gambar yang Anda perlukan juga dan menambahkan atribut sizes rumit ke <img /> dalam HTML yang dihasilkan untuk Anda.

Untuk panduan tentang cara menggunakan gatsby-image (dan mengirim gambar ke sana), lihat dokumen gatsby-image sini untuk v2 atau di sini untuk v1 (bagus).

@ooloth pekerjaan Anda sangat membantu. Terima kasih.

Apakah mungkin menggunakan "background-attachment: fixed; " ? Jika demikian, di mana tepatnya. Saya bisa membuatnya bekerja tetapi tidak dengan safari. Ketika saya membuatnya berfungsi, perilakunya adalah gambar terlihat bagus sampai saya menambahkan lebih banyak komponen di halaman. Semakin banyak komponen yang ditambahkan, semakin besar gambar yang didapat. Jadi, saya polyfill untuk masalah safari tetapi kemudian "background-attachment: fixed; " tidak lagi menjadi pilihan, atau sepertinya begitu. Setiap bantuan sangat dihargai.

@zachgaskin Saya berharap saya bisa membantu!

Ini terdengar seperti masalah CSS (yaitu tidak terkait dengan Gatsby atau gatsby-image ) dan saya khawatir saya tidak memiliki banyak pengalaman menggunakan background-attachment: fixed dan belum menemukan masalah yang Anda' kembali menggambarkan. Jika Anda dapat memposting tautan ke reproduksi minimal masalah ini, saya akan dengan senang hati melihatnya.

Menurut caniuse.com , iOS Safari tidak mendukung background-attachment: fixed , tetapi macOS Safari seharusnya berfungsi (harus...).

Sangat sulit untuk memilah mengapa browser tertentu memperlakukan CSS yang sama secara berbeda, jadi saya bersimpati. Semoga beruntung!

@zachgaskin @ooloth Saya juga menemukan ini. Ini tidak ideal tetapi solusi yang saya buat adalah menambahkan position: 'fixed' ke gambar. Meskipun, ini berarti berada di latar belakang seluruh halaman. Anda perlu memastikan bahwa Anda memiliki latar belakang yang ditentukan di tempat lain. z-index: -1 akan memastikannya tersembunyi di balik latar belakang Anda yang lain.

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

Gambar Latar Belakang Gatsby adalah langkah maju...

Anda mungkin merasa berguna untuk mengimpor gatsby-image secara langsung dengan IE polyfill dan menerapkan objectFit dan objectPosition sebagai props, daripada menggunakan !important dalam gaya Anda

import Img from 'gatsby-image/withIEPolyfill'

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

Terima kasih, @AronBe

Saya tidak bekerja dengan Gatsby saat ini, jadi saya tidak tahu yang terbaru; namun, Gambar Latar Belakang Gatsby (disebutkan di atas) benar-benar membantu saya pada proyek terakhir saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

totsteps picture totsteps  ·  3Komentar

ferMartz picture ferMartz  ·  3Komentar

signalwerk picture signalwerk  ·  3Komentar

theduke picture theduke  ·  3Komentar

ghost picture ghost  ·  3Komentar