How to pass multiple lazyload placeholders to picture element? - html

We can implement lazyload into picture element within source tags. But we've got only one img tag and we can load lazyload placeholder image in this img tag's src attribute. So if I want to set seperate lazyload placeholders for each image that is lazyloaded, is there a way to achieve it? I need this because I want to set different picture frames for portable devices and desktops. Let's say one image with a higher height value for portable devices (and will be loaded if the viewport is smaller than 1200px) and the other image with a higher width value for the desktop viewports (1200px or above).
Ex:
<picture>
<!--[if IE 9]><video style="display: none"><![endif]-->
<source
data-srcset="640.jpg 640w,
990.jpg 990w,
1024.jpg 1024w"
media="(max-width: 1024px)" />
<source
data-srcset="1200.jpg 1200w" />
<!--[if IE 9]></video><![endif]-->
<img
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
data-src="1024.jpg"
class="lazyload"
alt="image with artdirection" />
</picture>
Code is taken from afarkas.github.io
Let's say the image in first source tag has got a width of 640px and a height of 900px and the image in the second source tag's got a size of 1200px width and 900px height. Here I'll need to load different low quality images for portable devices and desktops, but I can set only one img tag, and therefore only one image placeholder in it's src attribute. What can we do to resolve this issue?
Thanks in advance,
Emre

One way to do this is to make the picture element intrinsic and then control the picture element via CSS and media queries.
Like this:
picture.intrinsic {
display: block;
position: relative;
height: 0;
width: 100%;
padding-bottom: 100%; // Default to square
}
picture.intrinsic img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
And then add media-queries to .intrinsic that sets different padding-bottoms.

Related

Possible for Img srcset into background-image?

I have a responsive header section but I need to transfer the image from the <img> tag into background-image - is this possible?
Below is the current img tag:
<img src="img/images-header.jpg"
srcset="img/images-header#2x.jpg 2x,
img/images-header#3x.jpg 3x"
class="Images-Header">
And the CSS is
.Images-Header {
width: 320px;
height: 456px;
margin: 60px 0 0;
padding: 105px 29px;
object-fit: contain;
}
Basically, I need to have the image responsive across devices, is it possible to have the srcset into background-image or the same effect?
Many thanks,
No, that's not possible. But you can use media queries to load different versions/sizes of your background-image depending on screen dimensions or other #media parameters like pixel ratio or similar.

How set width and height attributes for <img> element within <picture> element to prevent layout shifts?

Running Lighthouse in Chrome DevTools it says CLS (Cumulative Layout Shift) needs improvement.
I’m aware that modern browsers now set the default aspect ratio of images based on an image's width and height attributes. Hence best practice is that width and height attributes should be set to prevent layout shifts.
Despite this, I have omitted setting the width and height attributes since this is the only way I can get it to work the way I want (please see my code below).
Because I’m having images in WebP format (with png fallbacks) I’m forced to use the <picture> element (so that the browsers not supporting WebP get the png version of the image). Please note I’m using differently-sized versions of the same image.
Hence if I didn't have used WebP format I would go along with <img> solely and not <picture>. The problem would then have been solved thanks to the aspect ratio.
As you can see in the code snippet below there are two versions of the same image in this particular example. Setting width="245" and height="600" in <img> result in both my two differently-sized versions of the same image getting the maximum size of 245 x 600px (it will of course scale down in accordance with smaller viewports). For wider viewports (min-width: 813px) according to my media query I'm serving the larger version of the same image but setting width and height in <img> the image scales down to 245 x 600px.
Now to my question/s; If possible, what can I do to be able to set the width and height attributes for my <img> element within my <picture> element to prevent layout shifts (and also get other benefits for doing so such as faster load times)? Hence, how do I get the browsers to make use of the aspect ratio to show my images the correct way?
I would really appreciate someone’s guidance with this.
Thanks / Carl
<picture>
<source
media="(max-width: 812px)"
srcset="image-245w.webp"
type="image/webp"
>
<source
media="(min-width: 813px)"
srcset="image-332w.webp"
type="image/webp"
>
<source
media="(max-width: 812px)"
srcset="image-245w.png"
type="image/png"
>
<source
media="(min-width: 813px)"
srcset="image-332w.png"
type="image/png"
>
<img class="img-fluid" src="image-245w.png" alt="image">
</picture>
Allowing width and height attributes on <source> elements is now in the spec and browsers are beginning to adopt it.
GitHub Issue
I have done some testing and I came to the conclusion that using width and height (as you should) on the image element cancels out the sizes attribute. You can't get your responsive image to work properly anymore if you set the width and height.
I have created a small repo that shows different combinations: https://www.gijsvandam.nl/responsive-picture-element/
The solution to this is to not use sizes if you use width and height but instead depend on css for setting the correct width and height.
<picture>
<source
srcset="image-245w.webp 245w, image-332w.webp 332w"
type="image/webp"
>
<img
srcset="image-245w.png 245w, image-332w.png 332w"
class="img-fluid"
src="image-245w.png"
alt="image"
width="245"
height="600">
</picture>
#media (max-width: 812px) {
.img-fluid {
width: 245px;
height: auto;
}
}
#media (min-width: 813px) {
.img-fluid {
width: 332px;
height: auto;
}
}
It is important to understand that the srcSet in combination with sizes (or in combination with the css above) doesn't necessarily force the browser to use one image or the other. Depending on the device pixel ratio the browser may choose to load the bigger image to show in the 245px wide image slot. You just have to trust the browser that it will choose the best file for the job. There is not a one to one relationship between 'sizes' and srcSet. That's why you can provide more (or less) files in a srcSet than there are options in the sizes attribute.
ex-
img.d-blocks,img.d-block_w-100,img.d-block-w-100{
max-width :20%
}
#media (max-width: 812px) {
.img-fluid {
width: 245px;
height: auto;
}
}
#media (min-width: 813px) {
.img-fluid {
width: 332px;
height: auto;
}
}
/* displays the image at 245x600px for small screens */
#media only screen
and (max-width: /*enter a width in px */) {
.img-fluid {
height: 245px;
width: 600px;
}
}
/* displays the image at 332x812px for small screens */
#media only screen
and (min-width: /*enter a width of max-width +1px*/) {
.img-fluid {
height: 332px;
width: 812px;
}
}
<img class="img-fluid" src="image-245w.png" alt="image">
What ever you try to do, its way to complicated thatw ay you try to accoplish it. You can use the very same image and resize it with CSS. Use media queries to declare different sizes of the image depending on the screen width like shown below.
/* displays the image at 245x600px for small screens */
#media only screen
and (max-width: /*enter a width in px */) {
.img-fluid {
height: 245px;
width: 600px;
}
}
/* displays the image at 332x812px for small screens */
#media only screen
and (min-width: /*enter a width of max-width +1px*/) {
.img-fluid {
height: 332px;
width: 812px;
}
}
<img class="img-fluid" src="image-245w.png" alt="image">

How can i change the width and height of an image inside a <source> element?

For example:
<picture>
<source media="(min-width:650px)" srcset="mycat.jpg">
<source media="min-width:460px)" srcset="burncar.jpg">
<img src="burncar2.jpg" style="width:auto;">
</picture>
Now, the srcset image loads in full size. How do i change its size? I tried adding "width" and "height" within the element, but it doesn't work. I tried adding a Class inside the element and then target it in CSS to change the size, but again it didn't work. Why? And how do i change the size of the pictures?
You can achieve this with #media in CSS matching your source media min-width. Look at what I did in this example. Here's the jsfiddle for you to play around with the screen size. https://jsfiddle.net/ukwhn8p1/4/
#media (min-width: 460px) {
.pictures {
width: 25%;
}
}
#media (min-width: 650px) {
.pictures {
width: auto;
}
}
<picture>
<source media="(min-width:650px)" srcset="https://www.w3schools.com/tags/img_white_flower.jpg">
<source class="flower" media="(min-width:460px)" srcset="https://www.w3schools.com/tags/img_pink_flowers.jpg">
<img class="pictures" src="https://www.w3schools.com/html/img_girl.jpg" style="">
</picture>
What i tend to do to size images is to put a <div class="image_container"> around the image. Setting the width for the container makes the picture to always load at that width.
Sometimes 'weird' behavior can turn up due to weird image heights, but that tends to only be the case with images you can't control the source of (aka. some internet image from a link to it, or some upload). Same is obviously true if you only set the height.
Setting both the width and height can distort an image, as it is made to fit the size of the parent (aka. the image_container).
Cool thing about this though, is that you can set min and max widths for the container and get pretty decent control over the reactivity of the design based upon view or window size.
If you can control the actual source of the image (aka. you control the initial width and height), or you can account for deviations in either width or the height in your design. This works satisfactory.

A better responsive image with 1x1 px PNG?

I love the way img tags work in responsive design. It resizes proportionally and expands the div that contains it. The problem is that the image is the same pixel count in every size, which is terrible for mobile devices.
I thought of a way to use a 1x1 pixel PNG image with a width and height attribute in the markup to define the proportion. This way, your div will resize proportionally, based on the PNG, and you can swap out the backgrounds with media queries. And you can use it multiple times throughout your page, with only one http request.
Are there any issues with this way of attacking responsive images?
.container {
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat: no-repeat;
border: 1px solid blue;
background-image: url(large.png)
}
#media screen and (max-width: 968px) {
.container {
background-image: url(small.png)
}
}
img {
width: 100%;
height: auto;
}
<div class="container">
<img src="1x1.png" width="5" height="1">
</div>
If your goal is to minimize HTTP requests, HTML5 provides the <picture> element:
4.8.2 The picture
element
The picture element is a container which provides multiple sources
to its contained img element to allow authors to declaratively
control or give hints to the user agent about which image resource to
use, based on the screen pixel density, viewport size, image format,
and other factors.
With this element you can allow the browser to select the appropriate image based on a media query:
<picture>
<source srcset="large.png" media="(min-width: 1000px)">
<source srcset="standard.png" media="(min-width: 600px) and (max-width: 999px)">
<source srcset="small.png" media="(max-width: 599px)">
<img src="standard.png" alt="accessibility text here"><!-- graceful degradation -->
</picture>
Just note that this element does not yet enjoy universal browser support: http://caniuse.com/#search=picture
Here's a polyfill if necessary: https://scottjehl.github.io/picturefill/
References:
The <picture> element ~ MDN
Better Responsive Images With the picture Element ~ envatotuts+
Built-in Browser Support for Responsive Images ~ HTML5 Rocks
Yes, there's a problem with accessibility. Images in html are mean to be… Well, meaningfull. So you're putting unmeaningfull images in html and meaningfull images in CSS, where they have absolutely no intereset for a screen reader (for example).
Moreover, I guess you're planning to load big images to handle retina displays, on devices that do not need them, and just "resize down"?
You have better ways to handle mobile devices pixel-size, like srcset: https://developer.mozilla.org/en/docs/Web/HTML/Element/Img#Example_3_Using_the_srcset_attribute
Or the picture element: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture
http://caniuse.com/#feat=srcset
http://caniuse.com/#feat=picture

How to set an image as background for different mobile screen resolutions?

How can I set an image as background to work with multiple mobile different screen resolutions? For example if I am using it on iPhone4 which has a smaller resolution than iPhone6 without stretch it or crop it and show half of the image. I wish to know if there is any chance to show de middle of the image instead of coping it and show half of the image and half white.
.landing-page{
background: url(../img/landing-portrait.jpg);
background-size: cover;
background-repeat: no-repeat;
width: 100%;
height: 80%;
margin: 0;
}
If I use this then will show like almost half of the image and then everything is white in bottom. If I use height: 100%; then the white space in the bottom is getting lower and the image is getting larger in right side and the content is not in middle anymore.
Use background-size: 100%; to achieve what you are looking for.
background-size: 100%; stretches the background image independently in
both directions to completely cover the content area - W3.org
For instance,
.landing-page{
background: url(../img/landing-portrait.jpg);
background-size: 100%;
background-repeat: no-repeat;
width: 100%;
height: 80%;
margin: 0;
}
You can refer more for the same HERE
Hope this helps.
This answer does not answer your question directly. But it gives you
an alternative and can direct you to a new approach.
I suggest you could use the figure and the source tags. Please read upon those tags. I believe they might be used more often in the future in regard to responsive design.
For portable media devices often you don't need high resolution, and you can speed up the load process by loading/displaying images with smaller memory footprint.
Example:
<figure>
<picture>
<source media="(min-width: 750px)" srcset="images/still_life-800_large_1x.jpg 1x, images/still_life-1600_large_2x.jpg 2x" type="image/jpeg">
<source media="(min-width: 500px)" srcset="images/still_life-1000_medium.jpg" type="image/jpeg">
<img src="images/still_life-500_small.jpg" alt="Still Life">
<figcaption>Still Life</figcaption>
</picture>
</figure>
This example is a bit advanced (use of srcset), but support for the
srcset is expected to come in the future (I learned that from the
instructor of Responsive Design course on Udacity). You would probably
simply use the src attribute.
Basically what you specify here is a media query (the size of the viewport) and the corresponding source(s). The srcset can choose dynamically the image to load depending on the device pixel ratio of the screen (for iPad2 for example you can display more crispy images then).
You can use the usual img tag to fail gracefully in case a browser does not support the source tag.