Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use <picture> for g-image #212

Open
tomtev opened this issue Feb 22, 2019 · 16 comments · May be fixed by #1460
Open

Use <picture> for g-image #212

tomtev opened this issue Feb 22, 2019 · 16 comments · May be fixed by #1460
Assignees
Labels
feature request New feature or request

Comments

@tomtev
Copy link
Member

tomtev commented Feb 22, 2019

Summary

Now the <g-image> creates a small blurred <img> element before it changes into the lazy loaded image. It just replaces the image, so there is no smooth transition.

A <figure> element makes a wrapper around the image, so it's easy to, for example, fade in the image once loaded. We can also add a link to the image inside the <figure>.

Benefits:

  • Smooth fade-in of the image.
  • Canvas for the blurring of the small image (Like medium does)
  • Lightbox option (Or a link to a larger image).
  • Fig captions.

Basic example

<figure class="g-image g-image--loaded">
   <canvas /> <!-- The blurred small image -->
   <img src="picture.jpg" /> <!-- The loaded image -->
</figure>

With a link to the original / large image: (Can be used for lightboxes)

<figure class="g-image g-image--loaded">
   <a href="large-picture.jpg">
      <img src="picture.jpg" />
   </a>
</figure>

Learn more about the figure element:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure

@tomtev tomtev added the feature request New feature or request label Feb 22, 2019
@tomtev tomtev added this to the v0.6.0 milestone Feb 22, 2019
@hjvedvik
Copy link
Member

hjvedvik commented Feb 27, 2019

We can also let g-image have a few props for using it with externals images for lazy-loading and blur effect. Something like:

<g-image :thumb="miniUrl" :src="url" :srcset="srcSet" :width="width" sizes="..." />

@arttemiuss43
Copy link

It would be great if we could use g-image with external images. It sounds like a cool feature:)

@arifhussain353
Copy link

Hi @hjvedvik
Is there any way to stop just lazy-load and not to use for images?

@marcfilleul
Copy link

@hjvedvik, Here is the lazy loading script recommended by Google in their Google Dev Image Optimization post : lazysizes

I don't know if it's this one you use but it looks very interesting and flexible.
It's compatible with all the image optimizations you provide with <g-image> and have some plugins like lazysizes Blur Up which add a smooth blur transition.

+1 @arifhussain353, it could be useful to separate optimizations.

Default <g-image> component = responsive images with srcset and sizes (that we could set up too)

Add-on options could be:

  • LQIP (with Blur or TracedSVG)
  • Lazy Loading

@marcfilleul
Copy link

Hi,

Here are 2 very interesting loaders that could be used as a starting point to implement new placeholder's techniques.

I think these are maybe the 2 best techniques available now.

https://github.com/EmilTholin/sqip-loader

https://github.com/EmilTholin/image-trace-loader

@andrevandal
Copy link

Have you ever thought about use <picture> instead of <figure>?

With <picture>, we can use <source> and introduce many uses.

@hjvedvik hjvedvik modified the milestones: v0.6.0, v0.7.0 Apr 29, 2019
@tomtev
Copy link
Member Author

tomtev commented Apr 30, 2019

@derevandal You're right. I think we should use <picture>instead.

@tomtev tomtev changed the title Use <figure> for g-image Use <picture> for g-image Apr 30, 2019
@tomtev tomtev added this to To prioritize in Gridsome Roadmap via automation May 20, 2019
@tomtev tomtev moved this from To prioritize to Prioritized in Gridsome Roadmap May 20, 2019
@tomtev tomtev removed this from the v0.7.0 milestone Oct 15, 2019
@patrickcate
Copy link

You're right. I think we should use instead.

Keep in mind that the <picture> element should typically only be used for "art direction" use cases.
See: https://cloudfour.com/thinks/dont-use-picture-most-of-the-time/

@afenton90
Copy link

An idea here could be to allow for g-image to be used as a source element.
That way people can stay in control of whether it is used for a simple img element or for more advanced use cases addressing art direction inside a picture element.

Smooth fade-in of the image would be great, but as a 2nd to allowing for g-image to be used for other image use cases.

As an aside I'm using g-image with external images from sanity at the moment and it works pretty well when providing src as an object.

@Tragio
Copy link

Tragio commented May 4, 2020

At the moment is there any hack that we could fade in from the blurred image to the full image? I already looked to the vue-lazy-image and it works but g-image is nice cause it generates other image sizes. As a hack maybe with some JS that detects the change of the src and activates a CSS class with blur property and a transition time?

EDIT: Turns out that Gridsome is awesome and already have a .g-image--loading and .g-image--loaded classes, so it was easy to create a nice transition 😄

@pv-g
Copy link

pv-g commented Jun 12, 2020

@Kulcanhez could you share your solution please?
It could be nice to show some possible workarounds before this issue gets solved.

The simplest solution I came up with was that kind of thing.

// (SASS style)
.g-image-container
    overflow: hidden
.g-image--lazy
    transition: filter .8s ease-out
.g-image--loading
    filter: blur(10px)
.g-image--loaded
    filter: none

But it's not perfect. It's just applying another blur to the image, and requires a container if you don't want the blurred borders.

It would be ideal to fade out the loaded image on top of the blurred one (which means 2 <img> elements), but I'm not sure it's easily possible at the moment without being hacky.

@Tragio
Copy link

Tragio commented Jun 14, 2020

@Kulcanhez could you share your solution please?
It could be nice to show some possible workarounds before this issue gets solved.

The simplest solution I came up with was that kind of thing.

// (SASS style)
.g-image-container
    overflow: hidden
.g-image--lazy
    transition: filter .8s ease-out
.g-image--loading
    filter: blur(10px)
.g-image--loaded
    filter: none

But it's not perfect. It's just applying another blur to the image, and requires a container if you don't want the blurred borders.

It would be ideal to fade out the loaded image on top of the blurred one (which means 2 <img> elements), but I'm not sure it's easily possible at the moment without being hacky.

Eheh, of course, I can share ❤️

This one was a funny one to find a workaround, but from my side is working nicely.

// Lazyload Images Transition
.g-image--loading {
  filter: blur(40px);
}
.g-image--loaded {
  animation: blur 0.3s;
}
@keyframes blur {
  0% {
    filter: blur(40px);
  }
  100% {
    filter: blur(0px);
  }
}

Let me know if there's any improvement to make.

Happy to help 😄

@pv-g
Copy link

pv-g commented Jun 15, 2020

Hey @Kulcanhez, thanks for sharing :)
So it looks like we have the same workaround ;)

I'm still not very satisfied with it, and the best improvement to me is something like @tomtev suggested, with 2 HTML elements, one for the blurred image and 1 for the loaded image ...at least during the transition.

@hjvedvik
Copy link
Member

@philoozushi I think we might end up with markup that looks something like this:

<figure class="g-image">
  <div class="g-image--blur">
    <img class="g-image--fallback" src="">
  </div>
  <img class="g-image--image" src="">
  <noscript>...</noscript>
  <slot />
</figure>

That will allow Gridsome to show a nicer looking blurred image + fade in the original image once it's loaded.

@Tragio
Copy link

Tragio commented Jun 15, 2020

@philoozushi I think we might end up with markup that looks something like this:

<figure class="g-image">

  <div class="g-image--blur">

    <img class="g-image--fallback" src="">

  </div>

  <img class="g-image--image" src="">

  <noscript>...</noscript>

  <slot />

</figure>

That will allow Gridsome to show a nicer looking blurred image + fade in the original image once it's loaded.

Seems good to me. Do you think it will come in the 0.8? 😁

@Tragio
Copy link

Tragio commented Jul 28, 2020

@Kulcanhez could you share your solution please?
It could be nice to show some possible workarounds before this issue gets solved.

The simplest solution I came up with was that kind of thing.

// (SASS style)
.g-image-container
    overflow: hidden
.g-image--lazy
    transition: filter .8s ease-out
.g-image--loading
    filter: blur(10px)
.g-image--loaded
    filter: none

But it's not perfect. It's just applying another blur to the image, and requires a container if you don't want the blurred borders.

It would be ideal to fade out the loaded image on top of the blurred one (which means 2 <img> elements), but I'm not sure it's easily possible at the moment without being hacky.

@philoozushi after some testing I noticed that both of our codes are really slow on Firefox for Android and for Mac. There are a lot of issues that you can find on Google but I haven't the solution for our case. For now, I'll remove the transition. Let me know if you have any ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
Gridsome Roadmap
Prioritized
Development

Successfully merging a pull request may close this issue.

10 participants