So currently I'm using Bootstrap's grid system and a simple card. In the card, I render dynamically the background image. Think of the Instagram grid system. Everything works fine, except that once I go below a defined column width, the card resizes it to maybe 10% of its original height and the image is barely visible.
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="card" style=" min-height: 100%; min-width:
100%;background-image: url('<%= rails_blob_path(post.images.first)
%>'); background-position: center; background-size: cover;">
</div>
</div>
</div>
col-md-4: Everything nice as excepted:
Below col-sm-4 (or md, doesn't really matter, once it drops below the last defined col class it starts to look like this):
As you can see, once I scale the width of the browser down, it just snaps the height of the card to the second image.
Is it possible to resize the card in the second picture to fill the height, without messing around with the heights of the other cols? Adding "min-height: 200px;" will fix this issue, but it will also mess with the other col widths and make them appear stretchy.
Sorry if that's a basic question. I found a few posts but I couldn't fix it at all and normally backend, just trying to understand Bootstrap better.
Using "background-size: contain" will make it so that your images don't stretch and are fully visible, but you are still stuck with setting a min-height, which won't mess with your col widths so you don't have to worry about that. Consider using an img tag instead of divs with backgrounds though as they will size based on the image, whereas the image sizes itself with the div when you use divs w/ backgrounds
Cheers,
Ethan
So i came up with a solution, thanks everyone for your input. Just in case someone else runs into this problem:
Heres the working solution:
<div class="card h-100">
<%= image_tag(post.images.first, class:
'img-responsive', style: "width: 100%; height:
100%;")%>
</div>
I tried this before, but the cards were unequally in the height and the images were not really full width/height. The key is here to set the card to h-100 so that the card height is equally. Then, stretch the image in width&height too 100% and use img-responsive. This way, the image scales nicely together with all col widths.
Greetings!
Related
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.
I'm freelancing for a company and came across an issue I can't figure out.
I don't really want to post the URL to the page but I'll try explain as best I can.
The company is using foundation framework inside Magento.
They have 2 column side by side layout Text / image - then image text etc.
The div code is this
<div class="columns small-12 medium-6 type-h tile tile--one medium-push-6" data-equalizer-watch="" style="height: 385px;">
<img class="tile__image tile__image b-lazy b-loaded" src="image-url">
</div>
The main issue is this
data-equalizer-watch="" style="height: 385px;"
On mobile view this height changes randomly from 385 to over 570px depending on screen size. What this is doing is leave a large white space below the image as the image is only 385px in height.
I can't control the div from expending to this size.
I've tried using the important tag to force a max-height but can't.
I don't have access to the source code. Just the page in question inside Magento.
If you dont want it to affect mobile just add this.....
data-equalize-on="medium" to the surrounding div with data-equalizer on it
I'm curious to know how you resolve the following problem.
Using Bootstrap 3 with 24 columns and grid-gutter to 30px.
In wide display, I use col-7 for the sidebar left and col-17 for the main content. The problem is bootstrap is calculating the widths with percentage. So I have 339.5px (29.16667%) for the sidebar, and 824.484px (70.83333%) for the content.
<div class="row">
<aside class="col-lg-7">[sidebar]</aside>
<div class="col-lg-17">[main content]</div>
</div>
Now, I use some scripts like lazysizes and lazyaspectratio to lazy-load my pictures and have the image container kept the same dimensions even if the image is not already loaded. With lazyaspectratio, the width must be 100% to recalculate the height to keep.
BUT... because there is a but... if my main content is 824.484px width, the picture is 824.484px width too, and picture quality is bad. Assuming my picture display must be 824px, the final picture display is shitty and I lost quality, even if the ratio is respected.
My question is : how to bypass this problem with img > width=100% ?
I saw on several threads that people "fix" the width of the row children, like this :
div.row > aside.col-lg-7 {
width: 340px;
}
div.row > div.col-lg-17 {
max-width: 824px;
}
It seems a good solution to keep img > width = 100% and have integer columns width, but with this solution, I must add lot of css rules to manage for multiples col-* and multiples media-queries...
And you ? how do you solve this kind of problem ? Because I think using img-responsive class with width=100% cause quality loss on percentage based width with Bootstrap 3... I'm sure that I'm not the only one to encounter this problem.
Thanks in advance for any suggestion.
Andrejs: You can customize bootstrap at: http://getbootstrap.com/customize/
titouille: You could create a Javascript that rounds the images widths down based on their classes or parents.
For each image element you read in the width of the col or parent and set it (rouded down to 1 px) as it's max-width
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 am building my web application on my laptop but when I navigate the page on my desktop pc the layout of the div are distorted.
I think the solution is giving percentage instead of absolute numbers like 240px to height and width of divs.
What do you think ?
Do you have another recommendations ?
Thanks in advance.
What I've done is :
<div style="height:240px;width:240px"></div>
What I think I have to do is :
<div style="height:100%;width:90%"></div>
When using relative sizing 'px' rather than absolute 'pt', the browser approximates the size which can alter your layout depending on user settings for 'zoom' or text-size' levels, browser version etc.
If you absolutely size the layout div using points (pt), you should not see changes based on browser, screen resolution etc.
Try
<div style="height:240pt;width:240pt"></div>
Great reference on relative vs absolute font management here
What do you mean by "distorted"? Did it get wrapped to the next line? That's the only way I can see there being any distortion.
If you want to keep fixed widths, you simply have to wrap something else around it that will enforce a width. For example, if you wanted 2 divs side-by-side:
<div style="width: 800px">
<div style="width: 300px; float: left;"></div>
<div style="width: 500px; float: left;"></div>
</div>
Since the outer element is 800px, and the inner elements don't exceed that, if the screen is smaller than 800px it will just have a horizontal scroll bar, and your divs should still happily be next to one another. Note that if you have anything like borders or padding set on any of the divs, that will add to the width (and height) of the element, so take that into account.