I want my responsive Webpage to load the appropriately sized images. I currently have an HTML template that looks like:
<picture>
<source media="(min-width: 950px)" srcset="{{ .Cover.Large }}">
<source media="(min-width: 600px)" srcset="{{ .Cover.Medium }}">
<source media="(min-width: 300px)" srcset="{{ .Cover.Small }}">
<source media="(min-width: 150px)" srcset="{{ .Cover.Xsmall }}">
<img src="{{ .Cover.Medium }}" alt="{{ .Title }} poster">
</picture>
Large = 950x400
Medium = 600x252
Small = 300x126
Xmall = 150x63
Now I'm thinking this min-width is not going to work very well if the pictures are in a row or flexed. Isn't it best to define the dimensions of the image and let the browser download the most suitable source?
https://html.spec.whatwg.org/multipage/embedded-content.html#valid-source-size-list
What's the cleanest way to do this? Confusingly in my own responsive experiments, the Large size is always loaded:
Picture element
Img srcset
First of all, are you using the same image for each scenario but only in different sizes? If so, you can probably just use the srcset attribute rather than the <picture> element.
The <picture> element is used when you require art direction-based selection, like if you're using a wide shot for the large screen and a portrait crop on a narrow screen, for example. The thing about the <picture> element is that it's used in situations where we want a specific image to display at a specific breakpoint, hence there is no ambiguity in terms of image selection when using the <picture> element.
Which links back to my original question, are you using the same image for each screen width but simply in different sizes? If so, a normal img element with the srcset attribute would serve you much better.
For fluid-width images, srcset will be used with the w descriptor and sizes attribute. There are two values in the sizes attribute. The first is a media condition. The second is the source-size-value, which determines the width of the image given that particular media condition. Below is an example of the srcset syntax:
<img srcset="uswnt-480.jpg 480w,
uswnt-640.jpg 640w,
uswnt-960.jpg 960w,
uswnt-1280.jpg 1280w"
sizes="(max-width: 400px) 100vw,
(max-width: 960px) 75vw,
640px"
src="uswnt-640.jpg" alt="USWNT World Cup victory">
Here, I’m telling the browser that for viewport widths up to 400 pixels, make the image 100% of the viewport width. At viewport widths up to 960 pixels, make the image 75% of the viewport width. And for everything above 960 pixels, make the image 640 pixels. The browser utilises the information from srcset and sizes to serve the image that best matches the stated conditions.
Full disclosure: I lifted a lot of this from an article I wrote previously on this topic
This is what I wanted, 4 images flexed across a screen that are backed with multiple renditions of the JPG in order to save client bandwidth. Note the code is missing a src= attribute to make it valid.
body {
display: flex;
align-items: flex-start;
}
picture {
margin: 1em;
}
<picture>
<img
srcset="https://placeholdit.imgix.net/~text?txtsize=89&txt=XSmall&w=150&h=63 150w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Small&w=300&h=126 300w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Medium&w=600&h=252 600w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Large&w=950&h=400 950w" sizes="calc(25vw - 2em)">
</picture>
<picture>
<img
srcset="https://placeholdit.imgix.net/~text?txtsize=89&txt=XSmall&w=150&h=63 150w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Small&w=300&h=126 300w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Medium&w=600&h=252 600w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Large&w=950&h=400 950w" sizes="calc(25vw - 2em)">
</picture>
<picture>
<img
srcset="https://placeholdit.imgix.net/~text?txtsize=89&txt=XSmall&w=150&h=63 150w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Small&w=300&h=126 300w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Medium&w=600&h=252 600w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Large&w=950&h=400 950w" sizes="calc(25vw - 2em)">
</picture>
<picture>
<img
srcset="https://placeholdit.imgix.net/~text?txtsize=89&txt=XSmall&w=150&h=63 150w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Small&w=300&h=126 300w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Medium&w=600&h=252 600w, https://placeholdit.imgix.net/~text?txtsize=89&txt=Large&w=950&h=400 950w" sizes="calc(25vw - 2em)">
</picture>
So I learnt several things:
How to flex images
picture.img is fine, you don't need to use the source element
learnt about vw the view port size width, which is like a percentage of the screen, but you must you absolute values when calculating margins, e.g. calc(25vw - 2em). 25vw = 1/4 of screen with the picture margins 1em+1em either side
this stuff is really complicated, this example doesn't even use break points, which I would suggest you avoid for your sanity!
It does exactly what I want it to do. It loads the appropriately sized and bandwidth efficient image. If resizing down, it doesn't load a smaller image, which I want. And when it scales up, it does fetch a larger higher resolution image, which I do want in order to avoid any ugly artefacts.
Result: Efficient transfer of several JPG renditions
Related
I prefer to use the <picture> element to srcset because I can use WebP with a fallback to JPG. I cannot do this with srcset which is a shame.
However, I prefer srcset because it has the ability to change image by resolution e.g. 2x, 3x
Is there a way to combine these two options so I can get the best of both worlds.
Why wouldn't I be able to use srcset for art direction as this is often used as the main reason to use <picture> but I don't see why I couldn't do this with srcset.
You can in fact combine srcset with the picture element and use both features as so
<picture>
<source
media="(min-width: 650px)"
srcset="images/kitten-stretching.png,
images/kitten-stretching#1.5x.png 1.5x,
images/kitten-stretching#2x.png 2x">
</picture>
I still don't know why you wouldn't use srcset for art direction as it seems possible.
How can we construct a responsive image tag to insure that the browser chooses the image with the lowest file size that will fill its container, rather than choosing a higher resolution version?
I'm building a website with many images per page. We are more concerned about fast page load than we are with image quality. On a phone with a high resolution screen, we would rather the browser use the low resolution image than selecting a 2x image, for example, even if there is a bit of pixelation evident.
How would we construct an img tag or picture tag to accomplish this?
I've tried this:
<img
src="//placehold.it/992x662"
srcset="//placehold.it/1024x683 1024w,
//placehold.it/992x662 992w,
//placehold.it/768x512 768w,
//placehold.it/544x363 544w"
sizes="(min-width: 1200px) 1024px,
(min-width: 992px) 992px,
(min-width: 768px) 768px,
(min-width: 544px) 544px,
calc(100vw - 30px)"
/>
but Retina phones choose the largest file where we want them to use the smallest one.
I think you need to use <picture> for this:
<picture>
<source media="(min-width: 1024px)" srcset="//placehold.it/1024x683">
<source media="(min-width: 992px)" srcset="//placehold.it/992x662">
<source media="(min-width: 768px)" srcset="//placehold.it/768x512">
<source media="(min-width: 544px)" srcset="//placehold.it/544x363">
<img src="//placehold.it/992x662" />
</picture>
I am using polyfill for Art Directing two different different kinds of logos - one for desktop and the second one for mobile devices.
<picture>
<source media="(max-width: 25em)"
srcset="logo_mobile.svg">
<source media="(max-width: 48em)"
srcset="logo.svg">
<img src="logo.svg">
</picture>
As I am doing various types of CSS3 Animations (drawing effect and moving gradient) to these Logos, I would like to use the SVG Code Inline.
Is this possible? Thanks.
I am trying to switch a responsive image when it gets down to mobile, at the moment I'm using picturefill.js and also srcset and sizes to do the switching, however the images are not switching from the code used bellow.
<img srcset="/images/marketing/large.png 1190w, /images/marketing/mobile.png 320w"
sizes="(min-width: 767px), (max-width: 768px)"
alt="A rad wolf"
class="img-responsive" />
Your sizes attribute is invalid. With the sizes attribute, you define the display width of your image element. And you can use media conditions to define different breakpoints. You are only using media conditions, but don't add a size.
Example:
sizes="(min-width: 767px) 760px, 100vw"
Which means if the viewport is larger than 767 the image is displayed at 760px otherwise it has the full viewport.
Additionally the first media condition that matches is taken, therefore you don't need to mix min-width and max-width. It is much easier to either use max-width or min-width.
sizes="(min-width: 980px) 980px, 100vw"
The same sizes described with max-width:
sizes="(max-width: 980px) 100vw, 980px"
You can also try to use lazySizes which adds the sizes automatically for you.
How do I resize the visible portion of my image inside postbox-inner? How do I resize the overall box of postbox-outer?
I'm basically looking for smaller images because a lot of them are invariably low-res and tend to pixelate in ugly ways, or alternately a way to resize my grid.
Preferably both.
<!--{block:Photo}-->
<div class="postbox-outer">
<div class="postbox-inner"
<a href="{Permalink}">
<img src="{PhotoURL-500}" alt="{PhotoAlt}" border="0" />
{block:Caption}<span class="desc">{Caption}</span>{/block:Caption}
</a>
</div>
</div>
<!--{/block:Photo}-->
As I understand it, you want the images to be displayed at it's best possible size. If it's a huge image you want it constrained within the div. If it's a small image you don't want it to fill the div. The best thing I could suggest is to set the max-width for the image to 100%. Here's the CSS rule:
img { max-width: 100%; }
Hopefully this should work out fine. Do let me know if this answers your question.