I'm having an issue using object-fit: cover and srcset together. I have the image set to:
.banner-fit {
object-fit: cover;
height: 50vh;
width: 100vw;
max-width: 1300px;
}
and the image is using srcset like so
<img srcset="
./assets/images/media/media-4x.jpg 3200w,
./assets/images/media/media-3x.jpg 2400w,
./assets/images/media/media-2x.jpg 1600w,
./assets/images/media/media-1x.jpg 800w,
" src="./assets/images/media/media-2x.jpg" alt="Newspapers" class='banner-fit'>
The issue is that mobile devices are choosing the image based on the width. For instance a device with a 320 CSS px screen with a density of 2x is choosing the 800px x 344px image. But because of the object-fit:cover the device actually needs a size bigger to display properly (not be blurry). For instance the image on that same device will be 284 CSS px tall, so 568 actually pixels, which means that it needs the 1600px x 688px image.
Any suggestions on how to handle this?
I think using the attribute sizes we can specify which image to load when the viewport has certain width. sizes defines the media condition based on which the image from srcset is used. link
Related
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">
I'm working on a site which has a series of 'hero' panels running down the home page which have text overlaid on large background images.
Ideally I'd like to use inline images with srcset and sizes so the browser can choose the most appropriate image based on the screen size, rather than just whacking in the largest possible image as a background-image and then scaling it down for smaller screens.
So far my markup looks like:
<img
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
srcset="/img/trekking_320.jpg 320w,
/img/trekking_480.jpg 480w,
/img/trekking_600.jpg 600w,
/img/trekking_768.jpg 768w,
/img/trekking_960.jpg 960w"
data-sizes="100vw"
class="lazyload"
>
and CSS:
img {
position: absolute;
height: 100%; width: auto;
}
and overflow:hidden on the container.
The height of the images is 320px up to 768px, then 480px up to 960px and then a max-height of 600px after that.
I've made a Codepen to illustrate the problem. Everything works fine on retina screens at all different screen sizes (mobile, tablet, laptop) and on a normal dpi screen it's fine too up to 768px wide, but after that the images don't fill the screen.
So is it possible to do all the things I've asked in the title? Am I on the right track or do I need to take a completely different approach?
Don't abuse <img /> for background images - use CSS background-image (with background-size: cover or fill for a 'responsive' look) but use the image-set function to specify different images for different device display resolutions:
Is there a srcset equivalent for css background image
https://drafts.csswg.org/css-images-3/#image-set-notation
Though as of June 2017, image-set is not supported by Firefox/Gecko, Internet Explorer or Edge - only WebKit-based browsers (Chrome, Safari, Opera): http://caniuse.com/css-image-set/embed
body {
background-image: -webkit-image-set(
url('path/to/image') 1x,
url('path/to/high-res-image') 2x,
etc...
);
background-size: cover;
}
I currently have a header which is of an image (the width = 1920px and height = 250) It sits at the very top of the page, and looks well with some resolutions.
But when i got to a resolution that actually changed my screen size, the image is still 1920px and then allows me to scroll. Is there a way of making it scale down to fit the page?
You can make your image responsive.
You can use bootstrap and add class for your image.
e.g
<img src="xyz.png" class="img-responsive">
OR
You can manually try to make your image responsive with CSS rules.
e.g
max-width:100% !important;
max-height:100% !important;
display:block;
You will have 2 things here.
As the screen size differs your image should get fit in the window.
You need to maintain the aspect ratio of the image in responsive design, otherwise your image will be stretched out (It is a challenge to maintain aspect ratio in responsive design).
For the first one you can use width:100% and height:auto also max-width:100% to make sure it does not cross your section.
If you are designing based on some particular resolution then use media query
#media (max-width:768px)
{
width:... // define your width based on the resolution
}
Now the 2nd point : How to maintain aspect ratio. Follow the steps here:
http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/
Also, found a stackoverflow post, which will be useful to you :CSS force image resize and keep aspect ratio
You may use the responsive image code that is:-
img {
width: 100%;
height: auto;
}
Else if you have images for multiple resolutions you are recommended to use media Queries:-
//set width as per requirement
#media (max-width: 900px) {
background-image: url(img/cover.jpg);
}
How are you showing the image in the header? Using img tag or using background-image CSS property?
If you are using <img> tag, then you need to set max-width: 100%;
If you are using background-image property, then you need to set background-size: 100% auto;
Hope this help
Thanks
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.
Say I have a 400 px wide and 250 px high image. The user resizes the screen or loads the page on a smartphone.
Say the screen width is 320 px wide. The 400 px image won't fit.
Is there a way to automatically resize the image (and keep proportions) when the screen is not wide enough, using CSS?
In other words the image should be resized from 400px wide to 320px wide (for example).
Use
max-width: 100%;
Google responsive images for more information.
http://mobile.smashingmagazine.com/2013/07/08/choosing-a-responsive-image-solution/
No need to use mediaqueries for this specific case: just define
#yourimage {
width: 100%;
max-width: 400px;
}
this will ensure a full-width image for every viewport width up to 400px
You need to specify both min and max:
demo: http://jsfiddle.net/abhitalks/Vv9RT/
css:
img {
min-width: 220px;
max-width: 420px;
width: 100%;
}
Try changing the panel size in the fiddle. min-height will ensure a minimum acceptable size when the screen size gets too low. max-height will ensure a maximum size so that it doesn't get huge.
100% width will keep it within bounds.
by using the css3 media queries u can do make possible
ex: #media screen (max-width:480px){
img{
width:320px;
}
}
or
img{ max-width:100%}
or else you can use both.. 'img{ max-width:100%}' place before the media quires