Best practice for responsive images?
-
Hello all
I was wondering if there are accepted best practices for responsive images?
I have a custom component like so:
Vue.component('responsive-image', { template: '<img :srcset="imgsrc" />', props: { src: { type: String, required: true }, w: { type: Number, required: true } }, computed: { imgsrc: function () { return `~assets/img/lg/${this.src}.jpg w${this.w}, ~assets/img/md/${this.src}.jpg w${this.w * 0.5}, ~assets/img/sm/${this.src}.jpg w${this.w * 0.25}` } } })
Which is used like so:
<div> <responsive-image src="my-image" w="800" /> </div>
I have a grunt task to generate the 50% and 25% images automatically
Any better ideas? Thanks!
-
looks cool to me.
a few rough ideas to improve on it:- what about making it a vue single file component ?
- what about high-dpi displays ?
- what about sizing by height instead of width? (as an alternative)
I could very well see a polished version of this getting into quasar as
q-img
… -
@spectrolite Having it like this makes it available globally, but at the moment I am using it as a single file component
Regarding Hight dpi and sizing by height: this uses the
srcset
property, notsrc
That means that I simply tell the browser what image widths are available and where, the browser figures out the best one and gets that one. So at no point am I deciding witch image width a client getsCheers
-
The problem with
srcset
is that it is not supported by IE and (current) Edge versions (http://caniuse.com/#feat=srcset). So we would need a polyfill for these.
https://github.com/scottjehl/picturefill/blob/master/dist/picturefill.min.jsAnd without having used it, but shouldn’t the template be:
<picture> <source :srcset="imgsrc"> <img :src="fallbackSrc"> </picture>
Also, did you test if webpack inserts the correct path if you return the string?
But a
q-img
components seems like a great idea. Maybe we could even extend the webpack config to automatically generate smaller versions of images and insert these instead on relying on another build system.
I found this loader which looks promising: https://github.com/herrstucki/responsive-loader -
@rstoenescu please consider this for 0.15. Do you need it to be a github issue?
-
Yes, make it a github ticket pls. Accepting a PR if someone is willing. Thanks!
-
Here is the link to the issue on Github: https://github.com/quasarframework/quasar/issues/777
At the moment I do not have time for a PR, but maybe I will experiment with it later on. -
Here is a proposal. Also posted this on #777
<template lang="html"> <img :src="`/img/md/${src}`" :alt="alt" :srcset="imgsrc" :sizes="imgsize" > </template> <script> const xsBreakpoint = '576px', smBreakpoint = '768px', mdBreakpoint = '992px', lgBreakpoint = '1200px' export default { props: { src: { required: true, type: String }, w: { // Width, in pixels, of our original image. required: true, type: Number }, alt: { type: String }, size: { type: Number }, xsSize: { type: Number }, smSize: { type: Number }, mdSize: { type: Number }, lgSize: { type: Number } }, computed: { imgsrc () { let imgsrc = '' imgsrc += `/img/lg/${this.src}.jpg ${this.w}w, ` imgsrc += `/img/md/${this.src}.jpg ${this.w * 0.5}w, ` imgsrc += `/img/sm/${this.src}.jpg ${this.w * 0.25}w` return imgsrc }, imgsize () { let imgsize = '' if (this.xsSize !== undefined) imgsize += `(max-width: ${xsBreakpoint}) ${this.xsSize}vw, ` if (this.smSize !== undefined) imgsize += `(max-width: ${smBreakpoint}) ${this.smSize}vw, ` if (this.mdSize !== undefined) imgsize += `(max-width: ${mdBreakpoint}) ${this.mdSize}vw, ` if (this.lgSize !== undefined) imgsize += `(max-width: ${lgBreakpoint}) ${this.lgSize}vw, ` imgsize += `${this.size}vw` return imgsize } } } </script>
-
Thank you @benoitranque for specifying this!
The only change I would make is to let webpack generate theimgsrc
strings during the build and also actually build the smaller images.