Avoid stretch on image css - css

I am rendering an image into a div. I want to avoid stretching of my image.
div {
height: 300px;
width: 300px;
}
img {
min-width: 300px;
min-height: 300px;
max-height: 300px;
}
My problem is that my image's width stretches. I want it to have the regular width even though parts of the image will be missing.
div {
height: 300px;
width: 300px;
overflow: hidden;
}
img {
height: 300px
max-width: none;
min-width: 300px;
}

You can achieve this with simply adding object-fit: cover;. An example might be like -
img {
height: 300px
width: 100%;
object-fit: cover;
}

I would forget setting the min-height and the max-height. Just set the height to be 300 pixels and put an overflow hidden on the div tag. That way no matter what the image size it will always stay in proportion and never go outside the boundaries of your div tag.
div { height: 300px; width: 300px; overflow: hidden; }
img { height: 300px; }

Put the image as the div background if you want to avoid stretching the easiest way (yet maintain the original width).

To make it more flexible as just using 300px use:
img {
width: 100%;
object-fit: cover;
}
Height is automatically adjusted

just specify max-width 100% and height :auto

Use max-width instead of min-width, and just set height to 300px (or only use max-height).

You can use overflow:hidden to hide any portion of the image outside of the width of the div.
div {
height: 300px;
width: 300px;
overflow: hidden;
}
img {
/*min-width: 300px;*/
height: 300px;
}

==>If you are gonna have fixed height and don't want width stretched
div {
height: 300px;
width: 300px;
overflow: hidden;
}
img {
height: 300px
}
==>If you are gonna have fixed width and don't want height stretched
div {
height: 300px;
width: 300px;
overflow: hidden;
}
img {
width: 300px
}

After giving the image a fixed height and width, I added object-fit as below:
img {
width: 300px;
height: 300px;
object-fit: contain;
}

To avoid the image from resizing use:
object-fit: none;
More about object-fit
The CSS object-fit property is used to specify how an or
should be resized to fit its container.
This property tells the content to fill the container in a variety of
ways; such as "preserve that aspect ratio" or "stretch up and take up
as much space as possible".
Object-fit Values
fill: this is default. The image is resized to fill the given
dimension. If necessary, the image will be stretched or squished to
fit.
contain: the image keeps its aspect ratio, but is resized to fit within the given dimension
cover: the image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit
none: the image is not resized scale-down - the image is scaled down to the smallest version of none or contain.
More info and examples

I'm adding this to expand on the answers given since some of the answers given like adding width:100% height:auto" etc., will still technically stretch Images and/or make them blurry at times. Let me explain.
I work on a lot of eCommerce websites adding products etc and image stretching/blurring is always a problem. Most times, an image scaling down isn't that much of a issue, so the answers given as far as width:100%; height: auto; etc., work just fine. But there are problems when scaling up if the image's container width is larger than the image's native/normal width.
So for example, if you have an image whose width is 100px, and a div container whose width is 200px, if you add a width:100% and height: auto; to your image randomly, this won't technically "stretch" an image, but it will make it look blurry because you are stretching your image past its normal width.
To fix this, one thing i normally do is something like this, assuming on the desktop, that you have an image that you want to show at its 100% native width with no scaling/stretching/blurring whatsoever, I do something like:
img{
display:block;
margin:0px auto;
width: initial;
height: auto;
}
which keeps my images at their native width with no scaling whatsoever. But then, when an image is going to be seen on a smaller device, I add the same rule block into a media query and do something like:
#media all and (max-width: 1200px){
img{
width:100%;
height:auto;
}
}
What this is effectively saying is "Hey Image, make my image responsive from point A to point B(mobile devices), but once you go from point B to point C (small laptops to desktops where the image fits normally and doesn't need to stretch), make the width equal to its default native width".
Hope this helps. Happy coding everyone.

Related

CSS Resize multiple images so that they have a custom width, but same aspect ratio

If I have multiple images with different aspect ratios, but want them all to be resized such that the widths are equal, but the height is changed so that original aspect ratio is maintained, I can do this with JS and math but is there a short css solution?
I think that's why object-fit property comes
it really helpful in your case and it usually used with Object-position
Yes, simply set the width using CSS and not set the height and the height will be adjusted for you while maintaining the aspect ratio.
img { width: 100px }
<img src=https://i.stack.imgur.com/w5PGK.jpg">
But note the if you worry that the height may turn out to be exceedingly large, you can also use max-height to limit it. But doing so may distort the image:
img { width: 100px; max-height: 160px }
<img src=https://i.stack.imgur.com/w5PGK.jpg">
One solution is just to set a max-width and max-height on the image:
img { max-width: 100px; max-height: 120px }
<img src=https://i.stack.imgur.com/w5PGK.jpg">
and the image will be contained in the box with the proper aspect ratio.
There are also techniques such as to create a viewing box of a fixed size, and set overflow: hidden to limit the display area to the size of the box, while setting a fixed width for the image:
.image-box { width: 100px; height: 100px; overflow: hidden }
.image-box img { width: 100px }
<div class="image-box">
<img src=https://i.stack.imgur.com/w5PGK.jpg">
</div>

How to make an image's width resize itself with a defined height

I am trying to make an image resizable.
I have a specific height for this image: height: 100% (inside a container) and a width: auto; (i want the width to be adapted to the height about the natural image size).
Everything works fine when i access the page, but when i resize the window, the height is correctly resized, but the width keeps its initial value, i want it to be proportional (like when i access the page for the first time) to the height.
Is there a way to do it in CSS ? If not, what is the more optimize solution ?
Here is an illustration in code:
HTML
<div class="container">
<img alt="test" src="/img/test.png">
</div>
CSS
.container {
height: 100px;
width: 100%;
}
.container img {
height: 100%;
width: auto; //i need it to be adapted to each height about the natural image's dimensions
}
UPDATE
Here is a jsfiddle
http://jsfiddle.net/CRGj6/1/
Sometime it works sometime it doesn't...
window resize affects only the width of the element but not the height. It is kinda make sense because if you resize the height, more content is scrollable that means don't do anything to width but to increase the scrollbar length (so more content to be scrolled). Assuming that you want to preserve the aspect ratio of the image,
.wrapper .container img {
position: relative;
height: auto;
width: 100%;
}
would be the solution to this problem.

set div width as a percentage of height

I am trying to set the width of the .full_height_div element using pure css, based on its height. It has to be width-relative-to-height, and not height-relative-to-width. The reason for this is that the parent container (.set_rectangle_height) is already a div with height relative to the page width. Obviously, as the page is resized the divs on the page will resize, so i cannot set a fixed width in px for the .full_height_div child.
So .rectangle and .set_rectangle_height make up the parent container which has a width as a percentage of the page and a height relative to this width. See here for an explanation for this method.
But the problem is that then I want to place a div inside the parent with height: 100% and width relative to this height. The aim is then that I will be able to alter the browser window size and everything will keep its aspect ratio.
here is my failed attempt:
.rectangle
{
position: relative;
width: 30%;/*the outermost div is always a % of the page
width, even while resizing*/
display:inline-block;
background-color: green;
}
.set_rectangle_height
{
padding-bottom: 30%;/*this sets the height of the outermost div
to a ratio of 1:3*/
position: relative;
float: left;
width: 100%;
height: 100%;
}
.full_height_div/*this is the div that i want to have a width relative
to its height*/
{
height: 100%;
width: 20px;/*i will delete this once .square_set_width is working*/
position: absolute;
background-color: red;
}
.square_set_width
{
display: inline-block;
padding-left: 100%; /*i want to use something like this line to set
the width of this div to be equal to .full_height_div's height - ie a 1:1 aspect
ratio, but padding-left does not work :( */
position: relative;
height: 100%;
background-color: blue;
}
<div class='rectangle'>
<div class='set_rectangle_height'>
<div class='full_height_div'>
<div class='square_set_width'></div>
</div>
</div>
</div>
So, this is what the above incorrect markup looks like:
And this is what i want it to look like:
I know I could find the blue square percentage height in javascript, then set the width to be equal to this height, but it would be really handy if there is a pure css fix for what I am trying to do. I will be using this structure a lot and I don't really want to go writing code to resize all the divs on my page.
you have to use javascript for that. If I understood you, you want a perfect blue square. Use
var height = $('.square_set_width').height();
$('.square_set_width').css('width',height);
here is a jsfiddle: http://jsfiddle.net/a8kxu/
Edit: instead of doing padding-bottom: 30% do height: 70% instead. Here is another fiddle: http://jsfiddle.net/a8kxu/1/
Edit #2: Sorry, but you cant use css to do this. Its not powerful enough
If i understand you correctly
you can do
#divID {
width: 75%;
margin-left: auto; // this is used to center the container
margin-right: auto;// this as well
}

CSS force image resize and keep aspect ratio

I am working with images, and I ran into a problem with aspect ratios.
<img src="big_image.jpg" width="900" height="600" alt="" />
As you can see, height and width are already specified. I added a CSS rule for images:
img {
max-width: 500px;
}
But for big_image.jpg, I receive width=500 and height=600. How do I set images to be re-sized, whilst keeping their aspect ratios.
img {
display: block;
max-width:230px;
max-height:95px;
width: auto;
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">
This will make image shrink if it's too big for specified area (as downside, it will not enlarge image).
Here's a solution:
object-fit: cover;
width: 100%;
height: 250px;
You can adjust the width and height to fit your needs, and the object-fit property will do the cropping for you.
More information about the possible values for the object-fit property and a compatibility table are available here: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
The solutions below will allow scaling up and scaling down of the image, depending on the parent box width.
All images have a parent container with a fixed width for demonstration purposes only. In production, this will be the width of the parent box.
Best Practice (2018):
This solution tells the browser to render the image with max available width and adjust the height as a percentage of that width.
.parent {
width: 100px;
}
img {
display: block;
width: 100%;
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
<img width="400" height="400" src="https://placehold.it/400x400">
</div>
Fancier Solution:
With the fancier solution, you'll be able to crop the image regardless of its size and add a background color to compensate for the cropping.
.parent {
width: 100px;
}
.container {
display: block;
width: 100%;
height: auto;
position: relative;
overflow: hidden;
padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}
.container img {
display: block;
max-width: 100%;
max-height: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
<div class="container">
<img width="640" height="220" src="https://placehold.it/640x220">
</div>
</div>
For the line specifying padding, you need to calculate the aspect ratio of the image, for example:
640px (w) = 100%
220px (h) = ?
640/220 = 2.909
100/2.909 = 34.37%
So, top padding = 34.37%.
Very similar to some answers here, but in my case I had images that sometimes were taller, sometimes larger.
This style worked like a charm to make sure that all images use all available space, keep the ratio and not cuts:
.img {
object-fit: contain;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
The background-size property is ie>=9 only, but if that is fine with you, you can use a div with background-image and set background-size: contain:
div.image{
background-image: url("your/url/here");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
Now you can just set your div size to whatever you want and not only will the image keep its aspect ratio it will also be centralized both vertically and horizontally within the div. Just don't forget to set the sizes on the css since divs don't have the width/height attribute on the tag itself.
This approach is different than setecs answer, using this the image area will be constant and defined by you (leaving empty spaces either horizontally or vertically depending on the div size and image aspect ratio), while setecs answer will get you a box that exactly the size of the scaled image (without empty spaces).
Edit:
According to the MDN background-size documentation you can simulate the background-size property in IE8 using a proprietary filter declaration:
Though Internet Explorer 8 doesn't support the background-size property, it is possible to emulate some of its functionality using the non-standard -ms-filter function:
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
Remove the "height" property.
<img src="big_image.jpg" width="900" alt=""/>
By specifying both you are changing the aspect ratio of the image. Just setting one will resize but preserve the aspect ratio.
Optionally, to restrict oversizings:
<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
Firefox 71+ (2019-12-03) and Chrome 79+ (2019-12-10) support internal mapping of the width and height HTML attributes of the IMG element to the new aspect-ratio CSS property (the property itself is not yet available for direct use).
The calculated aspect ratio is used to reserve space for the image until it is loaded, and as long as the calculated aspect ratio is equal to the actual aspect ratio of the image, page “jump” is prevented after loading the image.
For this to work, one of the two image dimensions must be overridden via CSS to the auto value:
IMG {max-width: 100%; height: auto; }
<img src="example.png" width="1280" height="720" alt="Example" />
In the example, the aspect ratio of 16:9 (1280:720) is maintained even if the image is not yet loaded and the effective image width is less than 1280 as a result of max-width: 100%.
See also the related Firefox bug 392261.
Here is a solution :
img {
width: 100%;
height: auto;
object-fit: cover;
}
This will make sure the image always covers the entire parent (scaling down and up) and keeps the same aspect ratio.
Just add this to your css, It will automaticly shrink and expand with keeping the original ratio.
img {
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
This is mental. Use the scale-down property - it explains itself.
Inline styling:
<img src='/nic-cage.png' style={{ maxWidth: '50%', objectFit: 'scale-down' }} />
This will stop flex from stretching it. In this case, the image would go to 50% of the width of its parent container and the height would scale down to match.
Keep it simple.
Just replace the height attribute by the aspect-ratio attribute.
img {
max-width: 500px;
aspect-ratio: 900 / 600;
}
<img src="big_image.png" width="900"/>
The aspect-ratio attribute is not necessary, but prevent image layout shifts.
To maintain a responsive image while still enforcing the image to have a certain aspect ratio you can do the following:
HTML:
<div class="ratio2-1">
<img src="../image.png" alt="image">
</div>
And SCSS:
.ratio2-1 {
overflow: hidden;
position: relative;
&:before {
content: '';
display: block;
padding-top: 50%; // ratio 2:1
}
img {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
This can be used to enforce a certain aspect ratio, regardless of the size of the image that authors upload.
Thanks to #Kseso at http://codepen.io/Kseso/pen/bfdhg. Check this URL for more ratios and a working example.
Set the CSS class of your image container tag to image-class:
<div class="image-full"></div>
and add this you your CSS stylesheet.
.image-full {
background: url(...some image...) no-repeat;
background-size: cover;
background-position: center center;
}
I would suggest for a responsive approach the best practice would be using the Viewport units and min/max attributes as follows:
img{
display: block;
width: 12vw;
height:12vw;
max-width:100%;
min-width:100px;
min-height:100px;
object-fit:contain;
}
To force image that fit in a exact size, you don't need to write too many codes. It's so simple
img{
width: 200px;
height: auto;
object-fit: contain; /* Fit logo in the image size */
-o-object-fit: contain; /* Fit logo fro opera browser */
object-position: top; /* Set logo position */
-o-object-position: top; /* Logo position for opera browser */
}
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">
https://jsfiddle.net/sot2qgj6/3/
Here is the answer if you want to put image with fixed percentage of width, but not fixed pixel of width.
And this will be useful when dealing with different size of screen.
The tricks are
Using padding-top to set the height from width.
Using position: absolute to put image in the padding space.
Using max-height and max-width to make sure the image will not over the parent element.
using display:block and margin: auto to center the image.
I've also comment most of the tricks inside the fiddle.
I also find some other ways to make this happen.
There will be no real image in html, so I personly perfer the top answer when I need "img" element in html.
simple css by using background
http://jsfiddle.net/4660s79h/2/
background-image with word on top
http://jsfiddle.net/4660s79h/1/
the concept to use position absolute is from here
http://www.w3schools.com/howto/howto_css_aspect_ratio.asp
You can use this:
img {
width: 500px;
height: 600px;
object-fit: contain;
position: relative;
top: 50%;
transform: translateY(-50%);
}
You can create a div like this:
<div class="image" style="background-image:url('/to/your/image')"></div>
And use this css to style it:
height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover
You can set the container to display: flex and align-items: center (other align-items values work too). Instead of align-items you can also set align-self on the image itself.
This will make image shrink if it's too big for specified area (as downside, it will not enlarge image).
The solution by setec is fine for "Shrink to Fit" in auto mode.
But, to optimally EXPAND to fit in 'auto' mode, you need to first put the received image into a temp id,
Check if it can be expanded in height or in width (depending upon its aspect ration v/s the aspect ratio of your display block),
$(".temp_image").attr("src","str.jpg" ).load(function() {
// callback to get actual size of received image
// define to expand image in Height
if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
$(".image").css('height', max_height_of_box);
$(".image").css('width',' auto');
} else {
// define to expand image in Width
$(".image").css('width' ,max_width_of_box);
$(".image").css('height','auto');
}
//Finally put the image to Completely Fill the display area while maintaining aspect ratio.
$(".image").attr("src","str.jpg");
});
This approach is useful when received images are smaller than display box. You must save them on your server in Original Small size rather than their expanded version to fill your Bigger display Box to save on size and bandwidth.
You Can use:-
transform: scaleX(1.2);
to change the width without changing height.
And
transform: scaleY(1.2);
to change the height without changing width
You can use this on images and video tags in html and css. This does not change the aspect ration also.
you can use aspect-ratio property css
.my-image {
aspect-ratio: 1/1; // square
aspect-ratio: 16/9; // wide screen 1080p
aspect-ratio: 4/3;
aspect-ratio: 2/3;
}
img {
max-width: 80px; /* Also works with percentage value like 100% */
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">
<p>Let's say the author of the HTML deliberately wants
the height to be half the value of the width,
this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">
How about using a pseudo element for vertical alignment? This less code is for a carousel but i guess it works on every fixed size container. It will keep the aspect ratio and insert #gray-dark bars on top/bottom or left/write for the shortest dimension. In the meanwhile the image is centered horizontally by the text-align and vertically by the pseudo element.
> li {
float: left;
overflow: hidden;
background-color: #gray-dark;
text-align: center;
> a img,
> img {
display: inline-block;
max-height: 100%;
max-width: 100%;
width: auto;
height: auto;
margin: auto;
text-align: center;
}
// Add pseudo element for vertical alignment of inline (img)
&:before {
content: "";
height: 100%;
display: inline-block;
vertical-align: middle;
}
}
Fullscreen presentation:
img[data-attribute] {height: 100vh;}
Keep in mind that if the view-port height is greater than the image the image will naturally degrade relative to the difference.
If the application can have an image of any aspect ratio or resolution then you can manage height and width as in this link.
This uses Javascript and HTML
https://stackoverflow.com/a/65090175/13338731

fluid image width, matching height

I am trying (if it is at all possible) to use css to make an image 100% the width of a fluid div, but as the images are square (and will be distorted if not square) I want to be able to match the height to the width... for fluid width I am using:
.img{
max-width: 100%;
width: 100%;
min-width: 400px;
}
which works fine for setting the width on all major browsers, but I just cant figure out how to match the height to the width :/
Try throwing in height:auto into your class.
.img{
max-width: 100%;
width: 100%;
min-width: 400px;
height: auto; // <-- add me
}
As mentioned in the comments though, most browsers should be adjusting and scaling the images correctly. But glad this could help.
Now, with CSS3 there is new units that are measured relative to the viewport, (browser window), if you want a fluid image with respect to the window this it works better in most use cases than "%". These are vh and vw, which measure viewport height and width, respectively.
.img{
max-width: 100vw;
width: 100vw;
min-width: 400px;
height: auto;
}

Resources