Variable image aspect ratios in a square box - html

I have a database for house listings with images of the homes for each entry. The images are uploaded by a 3rd party and they send images in random widths and lengths. Some are square-ish, some are portrait, some are landscape, etc. Without using javascript, what would be the best way to have the image completely fill a square div that is a definite size (200px by 200px, for example). I think using the image as a background image of each div and using "display: cover" would work great but not sure of any browser compatibility issues or maybe there is a better way. any suggestions?

If compatibility is what you care about, this is the best way to give everyone a decent experience:
div {
background-position: 50% 50%;
background-size: cover;
width: 200px;
height: 200px;
overflow: hidden;
position: relative;
}
img {
position: absolute;
max-width: 100%;
max-height: 100%;
left: calc(-2000px);
}
<div style="background-image: url(http://placehold.it/400x150)">
<img src="http://placehold.it/500x200" />
</div>
Basically, use background-size to scale where available, and show the image to all browsers that don't support calc. Two birds, one stone.

There are a few ways to do this, but I prefer using object-fit: cover, which is supported by all major browsers except IE. If you need a solution that works for IE and Edge, you can check out how to implement a fallback, or fall back to using background-size: cover.

Avoid explicitly defining the images' size. Instead use this:
max-width: 100%;
max-height: 100%;
JsFiddle Demo
OR if you want to use background-image then center it using:
background-position: center center;
background-size: cover;
JsFiddle Demo

Related

Automatically scale image while keeping aspect ratio

I have an img inside a div tag, and currently I am using the CSS
img {
max-height: 100%;
max-width: 100%;
}
This currently keeps the images fitting inside the div, which is what I wanted. However, if the image file is smaller than the div, the image will not be the maximum size it can be. Is there an easy way to maximise the image, while keeping the image inside the div, and keeping the original aspect ratio?
I've tried setting the height to 100%, with a max-width of 100%, but this distorts the image, which is not what I'm looking for.
I also tried object-fit: contain;, but this doesn't seem to do anything.
Thanks :)
Try doing adding it as background, then you can do this:
div {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#Michelangelo's answer is another way to achieve your objective. If you want your image to be inside a img tag (like your original post), keep your max-width and max-height values, and put one of these inside your CSS class:
1) Keep aspect ratio based on width:
width: 300px; /* Your preferred width */
height: auto;
2) Keep aspect ratio based on height:
width: auto;
height: 300px; /* Your preferred height */
I would also suggest you to take a look at the object-fit property here:
https://www.w3schools.com/css/css3_object-fit.asp
It kinda acts as background-size property when you put values like contain or cover, with the plus that you can specify width and height without complicating your layout / DOM hierarchy. It comes very handy when dealing with intrinsic sizes of elements.
If you want to keep the image as an HTML element and not a CSS background, I would use object-fit. There are browser support limitations with this CSS property.
https://caniuse.com/#search=object-fit
You could use a polyfill to combat this. Such as:
https://github.com/fregante/object-fit-images
An example of what I believe you're after could be:
https://codepen.io/bin-man/pen/NWKNWLm
.image-container img {
object-fit: cover;
}
You can play around with the image sizes and remove object-fit to see how it behaves.
Hope this helps.
I guess this is what you need... Please run the code snippet...
div {
width: 100px;
height: 100px;
}
div > img {
max-width: 100%;
max-height: 100%;
object-fit: scale-down;
}
<div>
<img src="https://www.wellnesspetfood.com/sites/default/files/styles/blog_feature/public/media/images/6615505_950x400.jpg?itok=ylLXPrq6" />
</div>
<div>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/06/Kitten_in_Rizal_Park%2C_Manila.jpg" />
</div>

Scaling background image with css only cuts it off, doesn't change the scale

I'm trying to scale down a background image with css. My browser has it scaled all the way to it's maximum resolution, and nothing that should work, is working.
When I try and use max-width it doesn't scale the image, it only cuts off the right edge of the image, and it stays at the same scale.
Here's my CSS
.proj-header{ /* Settings for projects bgr image */
position: relative;
bottom: 20;
height: 450;
background-image: url(pics/fight_shy_lot.jpg);
background-repeat:no-repeat;
background-position: 50% 38%;
max-height: 40%;
max-width: 100%;
background-attachment: fixed;
background-position: center;
}
I don't think html is important as it's just an empty div. Everything is in the css.
The only thing I could get to work is background-size, but it lead to issues when the viewport is resized from my base res.
So my questions is why isn't max-width doing what everyone says it should be doing, or am I using it wrong?
I'm pretty new to web design so I'm sorry if this is a stupid question, but I searched all over for an answer, and all people say is to use max-width, which doesn't do anything for me.

Reconciling using background-size: cover while building a website from a psd file?

When I use background-size: cover; it causes the image to scale larger to fit the screen. This scaling means the background image doesn't match the dimensions from the psd file I'm trying to replicate. How do I keep the responsiveness that background-size: cover; provides, while maintaining the exact measurements from the psd? Thanks a lot for any help.
html:
<body>
<div class="bg-img"></div>
</body>
css:
.bg-img {
position: absolute;
background: url(../images/site-bg.jpg) no-repeat;
background-size: cover;
width: 100%;
height: 100%;
}
background: url(../images/site-bg.jpg) no-repeat center center;
?
If your intention is to have the background image be able to grow to the maximum 'natural' size of the source image and then not be scaled any larger, this would likely have to be achieved through some combination of media queries (testing both portrait, landscape and square window sizes at various sizes), CSS, or JavaScript.
You could consider using a max-width and/or max-height attribute, along with top: 0; bottom: 0; left: 0; right: 0; margin: auto;. This may yield acceptable results, though it may be that JavaScript is where you would need to look for the most reliable result.

css3 adaptive image in absolute position

I'm stuck on something that should be very simple. I have a page that uses Semantic UI. On that page I have a logo image that is 200px wide by 388px high. The image is positioned absolutely, top left. It does not use any Semantic UI class. I want the image to shrink adaptively to the screen size. I have played about with min and max heights and widths, but the image will not change size at all.
The only way I got it to almost work was to replace the image with a div and set the image as a background. I got that adapting, but I couldn't maintain aspect ratio, and besides, that's not a satisfactory solution.
Here's an example of what I have;
<div class="ui inverted menu">....</div>
<img src="/img.png" class="logo">
<div class="ui page grid">.....</div>
/* css (separate file) */
.logo{
position: absolute;
top: 4px;
left: 6px;
z-index: 2;
min-height: 100px;
max-height: 388px;
width: auto;
}
This is just one of many variants I have tried and I have run out of ideas!
The best solution will be to put the image as a background-image and than set the background-size to cover.
.logo {
background-image: url(path/to/your/image.jpg);
background-size: cover;
}
This way, you'll maintain aspect ratio.
If you don't want parts of your image to be cut off, you can use background-size: contain; instead.
There is an object-fit/object-position method for your problem.
To keep aspect ratio for an img block just use:
object-fit: contain;
For placing img top left:
object-position: 0 0;
Don't forget to stretch image to 100% width and height:
width: 100%;
height: 100%;
Check out fiddle to play with it.
Please notice that this variant is not the best for cross-browser using, since there is no support for object-fit/object-position properties in IE 6-11, Edge and some Mobile Android browsers according to caniuse.
As Simon said before, I'd reccomend you using background-image for cases like this too.

Stretch and scale CSS background

Is there a way to get a background in CSS to stretch or scale to fill its container?
Use the CSS 3 property background-size:
#my_container {
background-size: 100% auto; /* width and height, can be %, px or whatever. */
}
This is available for modern browsers, since 2012.
For modern browsers, you can accomplish this by using background-size:
body {
background-image: url(bg.jpg);
background-size: cover;
}
cover means stretching the image either vertically or horizontally so it never tiles/repeats.
That would work for Safari 3 (or later), Chrome, Opera 10+, Firefox 3.6+, and Internet Explorer 9 (or later).
For it to work with lower verions of Internet Explorer, try these CSS:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";
Scaling an image with CSS is not quite possible, but a similar effect can be achieved in the following manner, though.
Use this markup:
<div id="background">
<img src="img.jpg" class="stretch" alt="" />
</div>
with the following CSS:
#background {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
z-index: 0;
}
.stretch {
width:100%;
height:100%;
}
and you should be done!
In order to scale the image to be "full bleed" and maintain the aspect ratio, you can do this instead:
.stretch { min-width:100%; min-height:100%; width:auto; height:auto; }
It works out quite nicely! If one dimension is cropped, however, it will be cropped on only one side of the image, rather than being evenly cropped on both sides (and centered). I've tested it in Firefox, Webkit, and Internet Explorer 8.
Use the background-size attribute in CSS3:
.class {
background-image: url(bg.gif);
background-size: 100%;
}
EDIT: Modernizr supports detection of background-size support. You can use a JavaScript workaround written to work however you need it and load it dynamically when there is no support. This will keep the code maintainable without resorting to intrusive CSS hacks for certain browsers.
Personally I use a script to deal with it using jQuery, its an adaption of imgsizer. As most designs I do now use width %'s for fluid layouts across devices there is a slight adaptation to one of the loops (accounting for sizes that aren't always 100%):
for (var i = 0; i < images.length; i++) {
var image = images[i],
width = String(image.currentStyle.width);
if (width.indexOf('%') == -1) {
continue;
}
image.origWidth = image.offsetWidth;
image.origHeight = image.offsetHeight;
imgCache.push(image);
c.ieAlpha(image);
image.style.width = width;
}
EDIT:
You may also be interested in jQuery CSS3 Finaliz[s]e.
Try the article background-size. If you use all of the following, it will work in most browsers except Internet Explorer.
.foo {
background-image: url(bg-image.png);
-moz-background-size: 100% 100%;
-o-background-size: 100% 100%;
-webkit-background-size: 100% 100%;
background-size: 100% 100%;
}
.style1 {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
Works in:
Safari 3+
Chrome Whatever+
IE 9+
Opera 10+ (Opera 9.5 supported background-size but not the keywords)
Firefox 3.6+ (Firefox 4 supports non-vendor prefixed version)
In addition you can try this for an ie solution
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";
zoom:1;
Credit to this article by Chris Coyier
http://css-tricks.com/perfect-full-page-background-image/
Not currently. It will be available in CSS 3, but it will take some time until it's implemented in most browsers.
In one word: no. The only way to stretch an image is with the <img> tag. You'll have to be creative.
This used to be true in 2008, when the answer was written. Today modern browsers support background-size which solves this problem. Beware that IE8 doesn't support it.
Define "stretch and scale"...
If you've got a bitmap format, it's generally not great (graphically speaking) to stretch it and pull it about. You can use repeatable patterns to give the illusion of the same effect. For instance if you have a gradient that gets lighter towards the bottom of the page, then you would use a graphic that's a single pixel wide and the same height as your container (or preferably larger to account for scaling) and then tile it across the page. Likewise, if the gradient ran across the page, it would be one pixel high and wider than your container and repeated down the page.
Normally to give the illusion of it stretching to fill the container when the container grows or shrinks, you make the image larger than the container. Any overlap would not be displayed outside the bounds of the container.
If you want an effect that relies on something like a box with curved edges, then you would stick the left side of your box to the left side of your container with enough overlap that (within reason) no matter how large the container, it never runs out of background and then you layer an image of the right side of the box with curved edges and position it on the right of the container. Thus as the container shrinks or grows, the curved box effect appears to shrink or grow with it - it doesn't in fact, but it gives the illusion that is what's happening.
As for really making the image shrink and grow with the container, you would need to use some layering tricks to make the image appear to function as a background and some javascript to resize it with the container. There's no current way of doing this with CSS...
If you're using vector graphics, you're way outside my realm of expertise I'm afraid.
This is what I've made of it. In the stretch class, I simply changed the height to auto. This way your background picture has always got the same size as the width of the screen and the height will allways have the right size.
#background {
width: 100%;
height: 100%;
position: absolute;
margin-left: 0px;
margin-top: 0px;
z-index: 0;
}
.stretch {
width:100%;
height:auto;
}
Add a background-attachment line:
#background {
background-attachment:fixed;
width: 100%;
height: 100%;
position: absolute;
margin-left: 0px;
margin-top: 0px;
z-index: 0;
}
.stretch {
width:100%;
height:auto;
}
I would like to point out that this is equivalent to doing:
html { width: 100%; height: 100%; }
body { width: 100%; height: 100%; /* Add background image or gradient to stretch here. */}
Another great solution for this is Srobbin's Backstretch which can be applied to the body or any element on the page - http://srobbin.com/jquery-plugins/backstretch/
Try this
http://jsfiddle.net/5LZ55/4/
body
{
background: url(http://p1.pichost.me/i/40/1639647.jpg) no-repeat fixed;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
}
An additional tip for SolidSmile's cheat is to scale (the proportionate re-sizing) by setting a width and using auto for height.
Ex:
#background {
width: 500px;
height: auto;
position: absolute;
left: 0px;
top: 0px;
z-index: 0;
}
Use the border-image : yourimage property to set your image and scale it upto the entire border of your screen or window .