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.
What is the difference among col-lg-* , col-md-* and col-sm-* in Twitter Bootstrap?
Updated 2020...
Bootstrap 5
In Bootstrap 5 (alpha) there is a new -xxl- size:
col-* - 0 (xs)
col-sm-* - 576px
col-md-* - 768px
col-lg-* - 992px
col-xl-* - 1200px
col-xxl-* - 1400px
Bootstrap 5 Grid Demo
Bootstrap 4
In Bootstrap 4 there is a new -xl- size, see this demo. Also the -xs- infix has been removed, so smallest columns are simply col-1, col-2.. col-12, etc..
col-* - 0 (xs)
col-sm-* - 576px
col-md-* - 768px
col-lg-* - 992px
col-xl-* - 1200px
Bootstrap 4 Grid Demo
Additionally, Bootstrap 4 includes new auto-layout columns. These also have responsive breakpoints (col, col-sm, col-md, etc..), but don't have defined % widths. Therefore, the auto-layout columns fill equal width across the row.
Bootstrap 3
The Bootstrap 3 grid comes in 4 tiers (or "breakpoints")...
Extra small (for smartphones .col-xs-*)
Small (for tablets .col-sm-*)
Medium (for laptops .col-md-*)
Large (for laptops/desktops .col-lg-*).
These grid sizes enable you to control grid behavior on different widths. The different tiers are controlled by CSS media queries.
So in Bootstrap's 12-column grid...
col-sm-3 is 3 of 12 columns wide (25%) on a typical small device width (> 768 pixels)
col-md-3 is 3 of 12 columns wide (25%) on a typical medium device width (> 992 pixels)
The smaller tier (xs, sm or md) also defines the size for larger screen widths. So, for the same size column on all tiers, just set the width for the smallest viewport...
<div class="col-lg-3 col-md-3 col-sm-3">..</div> is the same as,
<div class="col-sm-3">..</div>
Larger tiers are implied. Because col-sm-3 means 3 units on sm-and-up, unless specifically overridden by a larger tier that uses a different size.
xs(default) > overridden by sm > overridden by md > overridden by lg
Combine the classes to use change column widths on different grid sizes. This creates a responsive layout.
<div class="col-md-3 col-sm-6">..</div>
The sm, md and lg grids will all "stack" vertically on screens/viewports less than 768 pixels. This is where the xs grid fits in. Columns that use the col-xs-* classes will not stack vertically, and continue to scale down on the smallest screens.
Resize your browser using this demo and you'll see the grid scaling effects.
This article explains more about how the Bootstrap grid
The bootstrap docs do explain it, but it still took me a while to get it. It makes more sense when I explain it to myself in one of two ways:
If you think of the columns starting out horizontally, then you can choose when you want them to stack.
For example, if you start with columns:
A B C
You decide when should they stack to be like this:
A
B
C
If you choose col-lg, then the columns will stack when the width is < 1200px.
If you choose col-md, then the columns will stack when the width is < 992px.
If you choose col-sm, then the columns will stack when the width is < 768px.
If you choose col-xs, then the columns will never stack.
On the other hand, if you think of the columns starting out stacked, then you can choose at what point they become horizontal:
If you choose col-sm, then the columns will become horizontal when the width is >= 768px.
If you choose col-md, then the columns will become horizontal when the width is >= 992px.
If you choose col-lg, then the columns will become horizontal when the width is >= 1200px.
From Twitter Bootstrap documentation:
small grid (≥ 768px) = .col-sm-*,
medium grid (≥ 992px) = .col-md-*,
large grid (≥ 1200px) = .col-lg-*.
Let's un-complicate Bootstrap!
Notice how the col-sm occupies the 100% width (in other terms breaks into new line) below 576px but col doesn't. You can notice the current width at the top center in gif.
Here comes the code:
<div class="container">
<div class="row">
<div class="col">col</div>
<div class="col">col</div>
<div class="col">col</div>
</div>
<div class="row">
<div class="col-sm">col-sm</div>
<div class="col-sm">col-sm</div>
<div class="col-sm">col-sm</div>
</div>
</div>
Bootstrap by default aligns all the columns(col) in a single row with equal width. In this case three col will occupy 100%/3 width each, whatever the screen size. You can notice that in gif.
Now what if we want to render only one column per line i.e give 100% width to each column but for smaller screens only? Now comes the col-xx classes!
I used col-sm because I wanted to break the columns into separate lines below 576px. These 4 col-xx classes are provided by Bootstrap for different display devices like mobiles, tablets, laptops, large monitors etc.
So,col-sm would break below 576px, col-md would break below 768px, col-lg would break below 992px and col-xl would break below 1200px
Note that there's no col-xs class in bootstrap 4.
This pretty much sums-up. You can go back to work.
But there's bit more to it. Now comes the col-* and col-xx-* for customizing width.
Remember in the above example I mentioned that col or col-xx takes the equal width in a row. So if we want to give more width to a specific col we can do this.
Bootstrap row is divided into 12 parts, so in above example there were 3 col so each one takes 12/3 = 4 part. You can consider these parts as a way to measure width.
We could also write that in format col-* i.e. col-4 like this :
<div class="row">
<div class="col-4">col</div>
<div class="col-4">col</div>
<div class="col-4">col</div>
</div>
And it would've made no difference because by default bootstrap gives equal width to col (4 + 4 + 4 = 12).
But, what if we want to give 7 parts to 1st col, 3 parts to 2nd col and rest 2 parts (12-7-3 = 2) to 3rd col (7+3+2 so total is 12), we can simply do this:
<div class="row">
<div class="col-7">col-7</div>
<div class="col-3">col-3</div>
<div class="col-2">col-2</div>
</div>
and you can customize the width of col-xx-* classes also.
<div class="row">
<div class="col-sm-7">col-sm-7</div>
<div class="col-sm-3">col-sm-3</div>
<div class="col-sm-2">col-sm-2</div>
</div>
How does it look in the action?
What if sum of col is more than 12? Then the col will shift/adjust to below line. Yes, there can be any number of columns for a row!
<div class="row">
<div class="col-12">col-12</div>
<div class="col-9">col-9</div>
<div class="col-6">col-6</div>
<div class="col-6">col-6</div>
</div>
What if we want 3 columns in a row for large screens but split these columns into 2 rows for small screens?
<div class="row">
<div class="col-12 col-sm">col-12 col-sm TOP</div>
<div class="col col-sm">col col-sm</div>
<div class="col col-sm">col col-sm</div>
</div>
You can play around here: https://jsfiddle.net/JerryGoyal/6vqno0Lm/
I think the confusing aspect of this is the fact that BootStrap 3 is a mobile first responsive system and fails to explain how this affects the col-xx-n hierarchy in that part of the Bootstrap documentation.
This makes you wonder what happens on smaller devices if you choose a value for larger devices and makes you wonder if there is a need to specify multiple values. (You don't)
I would attempt to clarify this by stating that...
Lower grain types (xs, sm) attempt retain layout appearance on smaller screens and larger types (md,lg) will display correctly only on larger screens but will wrap columns on smaller devices.
The values quoted in previous examples refer to the threshold as which bootstrap degrades the appearance to fit the available screen estate.
What this means in practice is that if you make the columns col-xs-n then they will retain correct appearance even on very small screens, until the window drops to a size that is so restrictive that the page cannot be displayed correctly.
This should mean that devices that have a width of 768px or less should show your table as you designed it rather than in degraded (single or wrapped column form).
Obviously this still depends on the content of the columns and that's the whole point. If the page attempts to display multiple columns of large data, side by side on a small screen then the columns will naturally wrap in a horrible way if you did not account for it. Therefore, depending on the data within the columns you can decide the point at which the layout is sacificed to display the content adequately.
e.g. If your page contains three col-sm-n columns bootstrap would wrap the columns into rows when the page width drops below 992px.
This means that the data is still visible but will require vertical scrolling to view it. If you do not want your layout to degrade, choose xs (as long as your data can be adequately displayed on a lower resolution device in three columns)
If the horizontal position of the data is important then you should try to choose lower granularity values to retain the visual nature. If the position is less important but the page must be visible on all devices then a higher value should be used.
If you choose col-lg-n then the columns will display correctly until the screen width drops below the xs threshold of 1200px.
TL;DR
.col-X-Y means on screen size X and up, stretch this element to fill Y columns.
Bootstrap provides a grid of 12 columns per .row, so Y=3 means width=25%.
xs, sm, md, lg are the sizes for smartphone, tablet, laptop, desktop respectively.
The point of specifying different widths on different screen sizes is to let you make things larger on smaller screens.
Example
<div class="col-lg-6 col-xs-12">
Meaning: 50% width on Desktops, 100% width on Mobile, Tablet, and Laptop.
Device Sizes and class prefix:
Extra small devices Phones (<768px) - .col-xs-
Small devices Tablets (≥768px) - .col-sm-
Medium devices Desktops (≥992px) - .col-md-
Large devices Desktops (≥1200px) - .col-lg-
Grid options:
Reference: Grid System
.col-xs-$ Extra Small Phones Less than 768px
.col-sm-$ Small Devices Tablets 768px and Up
.col-md-$ Medium Devices Desktops 992px and Up
.col-lg-$ Large Devices Large Desktops 1200px and Up
One particular case : Before learning bootstrap grid system, make sure browser zoom is set to 100% (a hundred percent). For example : If screen resolution is (1600px x 900px) and browser zoom is 175%, then "bootstrap-ped" elements will be stacked.
HTML
<div class="container-fluid">
<div class="row">
<div class="col-lg-4">class="col-lg-4"</div>
<div class="col-lg-4">class="col-lg-4"</div>
</div>
</div>
Chrome zoom 100%
Browser 100 percent - elements placed horizontally
Chrome zoom 175%
Browser 175 percent - stacked elements
well it's used to tell bootstrap how many columns are to be placed in a row depending on the screen size-
col-xs-2
would show only 2 columns in a row in extra small(xs) screen, in the same way as sm defines a small screen, md(medium sized), lg(large sized),
but according to bootstrap smaller first rule, if you mention
xs-col-2 md-col-4
then 2 columns would be shown in every row for screen sizes from xs upto sm(included) and changes when it gets next size i.e. for md up to lg(included)
for a better understanding of screen sizes try running them in various screen modes in chrome's developer mode(ctr+shift+i) and try various pixels or devices
Here are pictures of the buttons. I wanted the buttons to show up together because without columns they were dropping down to a new line and it looked ugly. Now it works on browser, but not on mobile. I'm sure this is because I defined 3 columns and mobile doesn't have room. But when the browser resizes it moves the buttons accordingly. How do I get it to do that on mobile?
Browser:
Mobile:
Here is the code I used:
<div class="row">
<div class="col-xs-4">Online Reputation</div>
<div class="col-xs-4">Review Management</div>
<div class="col-xs-4">SEO & Web</div>
</div>
On mobile devices, the available width to display elements is usually too narrow to have multiple in the same row while still keeping their texts readable (ie. Not truncated, heavily shrunk down, or wrapping within themselves).
The most common solution to this problem is to display the elements side-by-side when there is available space to do so, but start to stack them after the screen shrinks below a certain width (by styling them using media queries). This is a key part of responsive design, since desktop layouts rarely translate properly to mobile devices. (See Changing the Page Layout Based on Breakpoints for more details on this.)
Bootstrap has breakpoints built into the framework, so there's no need to do any extra work for it. You have the options of xs, sm, md, and lg, which correspond to predefined ranges of screen widths.
You've already used the xs breakpoint in col-xs-4, which basically means that at every possible screen width, the buttons should be 4 units wide. But this doesn't display properly on narrow mobile devices, as you've noticed - so your next option is to go one width higher and use col-sm-4. Doing so would preserve the 4 unit width at any screen width of sm and above, but would stack the buttons once the screen narrows to the xs range:
<div class="row">
<div class="col-sm-4">Online Reputation</div>
<div class="col-sm-4">Review Management</div>
<div class="col-sm-4">SEO & Web</div>
</div>
Here's a demo to show you how that looks. Hope this helps! Let me know if you have any questions.
You need to change text size to something smaller and or less padding of the buttons for it to fit on mobile. Where is your CSS?
So i have an website using a three column lay-out with a fixed width of 1000px. I want to convert this to an bootstrap responsive lay-out. What i did was the following:
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-push-2">Main</div>
<div class="col-lg-2 col-lg-pull-8">Left</div>
<div class="col-lg-2">Right</div>
</div>
</div>
I've set the container width for #media (min-width: 1200px) to width : 1000px. The problem i have now is that my sidebars are to small and the middle column is too wide. Changing the left and right col to col-lg-3 makes the colum to wide and the center column to small. I know bootstrap works with percentage so my question is, is this just how bootstrap works and i have to deal with it? Or is it somehow possible to set an fixed width to the sidebars? or is there an other way to make this happen?
thanks
This is how Bootstrap works. If you want to adapt it to your own liking, you should give your Main, Left and Right divs a class of their own and just adapt the % in your CSS.
Just be aware that creating your own %-width DOES NOT make it responsive! What I mean to say is that your divs will resize according to the browser-width, resulting in a very skinny website on mobile phones. Best is to combine this solution with Bootstrap, so Bootstrap takes over whenever your browser gets under X pixels wide, or to write your own #media and change the look of your website according to the width of the page.
Edit: Of course you could also try and override the bootstrap width in your own CSS, but this might result in some weird things when you use the same col-width again on another page.
I'm having some issues with fluid images when using a max height. I'm trying to bound the image in a box that is at most 450x450 or any arbitrary box thats not in the same aspect ratio as the image. What's happening is that the width of the image is being restricted to 450px but the height is not and the image is overflowing the wrapper div.
my code is:
<div class="wrapper">
<div class="container">
<img src="http://i.imgur.com/iw4yOa0.jpg"/>
</div>
</div>
see http://jsfiddle.net/5fuZ5/ for full code and css.
I know I could achieve this by using jquery but I need a responsive solution that doesn't require javascript.
OK i've got a similar issue and could find nothing to help. My situation is that i have a single column of images that are fluid (fit their container 100% in width) works fine for landscape images but portrait are huge as its the width being fitted, therefore tall and skinny image (portrait) is having its width fit to container thus making it massively tall.
My solution was to think about the container, if in the instance of a portrait image i set the container to be 50% of the landscape container then when i fit the images width (when portrait) to a smaller container i get them proportional (ish).
So wat you want is 2 containers to use, one for portrait and landscape, the landscape one will be the maximum width you want so 450px. Now make your portrait container half a width so 225px (half of the width) if all your images are the same aspect ratio then they should all match nicely and give you a structured grid - or if single column the portrait images will be more or less as tall as the landscape images are wide.
If you want to see this working (for a short time) I'll leave this link up so you can see how i solved it. The example is an email (please don't moan about poor coding, its not finished) template I'm making, where i have a single column of images (its responsive) both portrait and landscape - use a class on the table that contains the portrait image (class=portrait) but this could easily be a div.
http://www.sink140.com/sf-test/single.html
My main point is to stop thinking about trying to control the height, just control the container, let the image fill it, and by adjusting the width of the container (making it smaller) you naturally reduce the height of the image.
Aspect ratio of the images in general will ensure you can predict the layout as you have a baseline of sorts - portrait images relate to the landscape ones.
Hope this helps or at least give you another idea.