Prevent upscaling with scrset? - html

Is it possible to prevent upscaling when using scrset?
Here's a jsbin showing what I'm talking about:
https://jsbin.com/bukupuq
The browsers (Firefox, Chrome, Safari) are using the largest image to fill the container, even though its width (500px) is smaller. I would expect that it would intelligently use the best image given the viewport width, but not upscale the image.
Is there a way to prevent this without having to write an inline style="max-width:500px"?

It looks like images with srcset will always upscale, even if supplied with a low-res image. It's hard to search for documentation on this because all of the examples people use assume that you already have high-res images on hand. In my case, I'm building a 'responsive image' React component that is handling images supplied by a user from a CMS. Not all of their images are high-res, though.
My solution involves a little CSS balancing of width and max-width, both on the image itself and its wrapping <figure> tag. (This of course could be a div or anything else)
CSS:
img {
max-width: 100%;
}
figure {
width: 100%;
}
HTML:
This is generated according to how many sizes of an image are available. On the CMS side, I am creating thumbnails at 2400px, 1600px, 1200px, 800px, and 400px wide, but only if the source image is larger than that. The <figure> tag then gets all of the resized images, as well as the original one. Then, to prevent the image from scaling up, the figure tag gets a max-width of the largest image available.
So, if the source image is only 500px wide:
<figure class="" style="max-width: 500px;">
<img src="http://example.com/images/img_7804a_web.jpg"
srcset="http://example.com/images/img_7804a_web-400x600.jpg 400w,
http://example.com/images/img_7804a_web.jpg 500w"
sizes="100vw"
alt="alt text">
</figure>
If the source image is 1125px wide, it gets a few more sources:
<figure class="" style="max-width: 1125px;">
<img src="http://stephanie.standard-quality.biz/content/projects/18-2016/3-cargo-cults/cargocults_basketwoman_web.jpg"
srcset="http://stephanie.standard-quality.biz/thumbs/projects/2016/cargo-cults/cargocults_basketwoman_web-400x533.jpg 400w,
http://stephanie.standard-quality.biz/thumbs/projects/2016/cargo-cults/cargocults_basketwoman_web-800x1067.jpg 800w,
http://stephanie.standard-quality.biz/content/projects/18-2016/3-cargo-cults/cargocults_basketwoman_web.jpg 1125w"
sizes="100vw"
alt="alt text">
</figure>
Here's how it ends up looking: in this instance, the third image wasn't high-res enough to span the whole column:

Related

Core web vitals flagged Image elements do not have explicit width and height

I was checking Core Vitals on PageSpeed insight and noticed its flagging Image elements do not have explicit width and height and suggesting Set an explicit width and height on image elements to reduce layout shifts and improve CLS.
I am not sure what it exactly means and what i can do properly to resolve this issue, specific to my case
<img src="someimage.jpg" width="100%" height="100%" alt="something" class="img-responsive">
My page is responsive and i am using bootstrap v3.x for this webpage as its is old page. since page is responsive and i am using class="img-responsive" which automatically resizes image with, but this impacts core vital such as CLS.
Since layout is responsive what is the best approach to define use image to avoid CLS issue.
I have noticed most of the CLS reported by Page Speed Insigh is for owl Carousal
Below is the copy of code which generate CLS issue for images
<div class="container">
<div class="row">
<div class="col-md-12 col-lg-12 lc-hp-col">
<div class="owl-carousel owl-theme" data-items="1" data-items-desktop="1" data-items-tablet="[991,1]" data-items-mobile="[767,1]" data-pagination-speed="200" data-auto-play="true" data-stop-on-hover="true">
<div class="item">
<img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+1">
</div>
<div class="item">
<img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+2">
</div>
<div class="item">
<img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+3">
</div>
<div class="item">
<img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+4">
</div>
<div class="item">
<img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+5">
</div>
</div>
</div>
</div>
</div>
CodePen link
Some article have suggested to use scrset for responsive images but this is not practical as we have to then upload multiple versions of same image.
<img
width="1000"
height="1000"
src="puppy-1000.jpg"
srcset="puppy-1000.jpg 1000w, puppy-2000.jpg 2000w, puppy-3000.jpg 3000w"
alt="Puppy with balloons"
/>
NOTE: The sizes of your images are fix as of Bootstrap mechanic!
If you have a nearer look to your page your images are responsive but not fluent. That means the size does change in predfined steps when the vieport changes the width. Inbetween this steps the sizes for the images are allways the same even if the sizes are set in percentage. That's the mechanic of Bootstrap.
So, - your are able to set fixed values to the sizes of your images without changing the layout!!!
You will find the original steps Bootstrap uses (if not changed for the project) here:
https://getbootstrap.com/docs/3.4/css/#grid-media-queries
As you see Bootstrap standard is: if viewport width becomes more than 769px the size changes, same as on 992px and on 1200px.
Taken from the codepen example the sizes of your images are:
// Up from Vieport width:
768px = Image: 720x426px
992px = Image: 940x557px
1200px = Image: 992x588px
(Note: below viewport widht 768pxcodepen does not work. Have a look for the size(s) on original page.)
Knowing that you are able to advice fixed sizes to the images by media queries. You may do this using sass with the original tools of Bootstrap (see link above). Or do something like this:
/* below 768px take values from original page */
#media (min-width: 768px {
.owl-carousel img {
width: 720px !important;
height: 426px !important;
}
#media (min-width: 992px {
.owl-carousel img {
width: 940px !important;
height: 552px !important;
}
#media (min-width: 1200px {
.owl-carousel img {
width: 992px !important;
height: 588px !important;
}
NOTE: I am not quite sure if that css overwrites the Bootstrap markup. So maybe you have to give it an higher specificity i.e. by using div.owl-carousel div imgor something similar. And if height is not correct please readout all sizes from original page. Sometimes you will need to be more exact i.e. with height: 588.xxxx px.
Answer
The width and height we are talking about, are intended to be a fixed number to avoid the warning.
That's needed to reserve the (explicit) required space for the image while it's loading. If you give it a percentage, the browser cannot know the size it will need, so it will be changing, and cause the page layout to shift (that's what we try to avoid).
Edit
I'm not sure about what you mean with "it becomes even harder". No one said it's easy, as you have a complex problem.
You are trying to:
Serve a responsive carousel.
A carousel with responsive images.
Avoid warnings from Web Vitals about Layout Shifts.
Complex solutions for complex problems, that's what it is.
There is no real solution to this issue other than the srcset solution that you mentioned. The layout shift issue will likely be flagged unless you specify image dimensions.
I agree that the integration of multiple image sizes is difficult & cumbersome & perhaps not always justified. Even if you integrate the multiple sizes of images you can still have a layout shift if the images are set to scale responsively to ANY size rather than just a set of options.
The CLS is less likely to be flagged by Google (or to bother any users) if your images begin to load very quickly so that the image sizes are known before the layout has a chance to fully render (& thus shift). Defer anything you can to bring the images towards the front of the line.
This may be questionable but I implemented a tiny generated png to get the image data loaded very quickly like this:
<img class="img_scale"
src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
data-src="/img/img.jpg"
/>
You may also be able to use csscalc to estimate the percentage, pixel value or em value of a container for the image in order to greatly reduce the amount of shift. You probably can't eliminate it without using static sizes but you can cut it way down.
You can work around this problem by
Setting explicit <img width height> - for height value use your best guess what the most image heights will be
Later override the HTML element height attribute with the following CSS:
.my-img {
height: auto;
}
However note that this causes cumulative layout shift, CLS, event after the image is loaded, so you are essentially shifting the problem around. The CLS issue can be worked around by making sure the container element hosting the image has min-height set.
Here is the full source code for an example Svelte component where I worked around this problem.
When you use img src tag so you need to add width and height whatever actual image width and height attribute with img tag for an Example like this:
So it is not Create CLI in google page insights.

Serve scaled image for web

I have the "serve scaled image" issue when I test my website with http://gtmetrix.com/
For example, my image size is 2000x3000 and the recommendation is 104x104px (I set the width and height of img to 104x104px in my css). I tried to resize all my icon images to 104x104. However, those images look blurry? I thought it should not be blurry because the size is correct.
My question is how do I know the size to scale the image when
1. img has fix size (I set the width and height of img to 104x104px in my css) => blurry issue
2. responsive image
I use Wordpress, any free plugin that solves the issue. I used optimole but it makes my images blurry!
Thanks,
Use css properties such as
object-fit: cover
for image tag and
background-size: cover /* it can be contain too, depending on the situation */
for backgrounded images
Use "picture" HTML tag for different window widths:
<picture>
<source srcset="/img/blog/responsive-images-lg.png 730w">
<source srcset="/img/blog/responsive-images-md.png 610w">
<source srcset="/img/blog/responsive-images-sm.png 350w">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>

Styling responsive layout in amp-img

Since I've implemented Google AMP I am struggling with this problem. Every time I add an image with a width far smaller than my website width, amp-img automatically add margins to keep the aspect ratio, like this:
I have tried other layouts mentioned in the [official documentation],(https://www.ampproject.org/docs/guides/responsive/control_layout#supported-values-for-the-layout-attribute) like flex-item.
With flex-item for example, I can get the desired behavior in the desktop version, that is, reducing the total margin of the image to look like this:
But in the mobile version, when an image is wider that the screen, the image overflows left and right.
Is there a way I can tweek the responsive layout in order to remove such larger margins when the image is relative small?
Investigating a bit in the code, the problem seems to be caused by the element i-amphtml-sizer, which is an element google-amp adds automatically and of which I have no control of.
I am not posting the url for my blog post in case it is considered spam, but if for some reason you need it, I'll update the question.
UPDATE
It seems more people are having this issue.
I solved it! reading amp documentation on github, in concrete the section on amp-html-layout, in "sizes" there is an example saying:
In the following example, if the viewport is wider than 320px, the image will be 320px wide, otherwise, it will be 100vw wide (100% of the viewport width).
<amp-img src="https://acme.org/image1.png"
width="400" height="300"
layout="responsive"
sizes="(min-width: 320px) 320px, 100vw">
</amp-img>
Previously, my image was:
<figure>
<amp-img
on="tap:lightbox1"
role="button"
tabindex="0"
layout="responsive" src="/img/securitynow.jpg"
width="100"
height="100">
</amp-img>
</figure>
After reading AMP documentation:
<figure>
<amp-img
sizes="(min-width: 100px) 100px, 100vw"
on="tap:lightbox1"
role="button"
tabindex="0"
layout="responsive" src="/img/securitynow.jpg"
width="100"
height="100">
</amp-img>
</figure>
Now it is displaying well on all screen sizes:
In order to work with all kind of image sizes, I'm following this rule:
sizes="(min-width: withOfImage) WithOfImage, 100vw"
This way, when the screen is wider than the image width, the image will have its original width, otherwise the image will be 100% of the viewport width.

using CSS Responsive Image width and height with Google Structured Data recommendations

Google says that it is better to put the width and height of an img in the html: "A web browser can begin to render a page even before images are downloaded"
See Here
<img src="some-address.jpg" width="20px" height="20px">
But, what if the img is in a responsive page?
I did not give any value and the img works well and adapts to any size. But, then the Google testing tool for structured data gives an error: "A value for the width field is required"
https://search.google.com/structured-data/testing-tool
I tried to give that values:
<img src="http://www.w3.org/html/logo/downloads/HTML5_Badge.svg"
width="100%" height="auto">
Here is the example: JSFiddle
It is responsive and it has the values. The error goes away. But I have read that Google requires numeric values.
How to put the width and height of an img in a responsive page?
I suppose that the use of structured data is always recommended. So, I must take into account what the Google testing tool says. Am I right?
This is best done through a css style sheet as the width and height tags for images are generally considered bad practice.
.imageclass{
width: 100%;
max-width: 150px; /* whatever size is the biggest that you want */
height:auto;
}
<img src="http://www.w3.org/html/logo/downloads/HTML5_Badge.svg" class="imageclass" />
Just use css instead of attributes:
img {
width: 100%;
height: auto;
}
<img src="http://www.w3.org/html/logo/downloads/HTML5_Badge.svg">
The article you refer to says:
Specify a width and height for all images. A web browser can begin to render a page even before images are downloaded, provided that it knows the dimensions to wrap non-replaceable elements around. Specifying these dimensions can speed up page loading and improve the user experience. For more information about optimizing your images, see Optimizing Web Graphics on the site Let's Make the Web Faster.
So the reason of specifiing sizes in pixels is that browser will know the image size before it loads the image itself. And there is no sence in specifiing them in css for every image if it is unique and takes all place it needs. Now you are setting one value to auto. With auto browser have to get the image and only then it will be capable to calculate its dimensions ratio and use it. No any reasons to use attributes.
As Unor says here link to a another question
Schema.org’s height/width properties are not for stating in which dimension the image should be displayed, but which dimension the image file has.
So I can put the responsive css as ususal in the css file:
img {
width: 100%;
height: auto;
}
In the html, with structured data I have to give the width and height in px. The real pixels, as I can see in Photoshop:
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<img src="some-address.jpg"/>
<meta itemprop="url" content="some-address.jpg">
<meta itemprop="width" content="20">
<meta itemprop="height" content="20">
</div>

Specifying image dimensions to improve the site speed

I'm trying to optimize my images for SEO.
Page Speed currently only detects image dimensions that are specified
via the image attributes.
According to above line i should use width and height attribute in image tag for improving the page speed. But I have to responsive the site also, for example i have an image with following width and height.
Screen Size 960 pixel
<img src="" width="250" height="250" />
Then how i will adjust the image size on small screens?
Screen Size 480 pixel
<img src="" width="250" height="250" />
if i add an id or class for adjusting the size on the small screen the it will be correct way or not?
.reduceSize{
width:150px;
height:150px;
}
Please guide me i'm wrong or any other suggestion. Also in image tag width and height attribute are necessary for site speed ?
Changing Image dimension through html code wont reduce the image size and wont improve the speed of loading. If you want to load different image size for different screen resolution, you have to use ajax load different images(based on screen size) or other 3rd party image handlers as well as aspJpeg (for windows server) or WideImage (for linux) or find more by searching php image manipulation to resize images dynamically.
You probably will need extra coding to determine the screen size before loading proper images.
May be you can add two different <img> tags. One for mobile device and one for larger screen.
<img class="hide-in-mobile" src="" width="250" height="250" />
In css media queries for mobile devices add
.hide-in-mobile
{
display:none;
}
and
<img class="show-in-mobile" src="" width="150" height="150" />
in media queries for large screen
.show-in-mobile
{
display:none;
}
Width and Height attributes are important for site speed. You can set natural width/height of image then control you img size with CSS in Media. as you told in your question.
<img class="reduceSize" src="" width="250" height="250" />
#media all and (max-width:960px ) {
.reduceSize{
width:350px;
height:350px;
}
}
#media all and (max-width:480px ) {
.reduceSize{
width:150px;
height:150px;
}
}