Force an image to fit and keep aspect ratio - html

I want an image to fill the 100% of its container's width, and I want it to have a max-heigth property set to it, all this keeping the aspect ratio but allowing to lose any part of the image.
img {
max-height:200px;
width:100%;
}
I know a similar thing can be done with background-size property but i want to make this to an inline <img> tag.
Any idea of how could i achieve this using CSS? or javascript?

You can try CSS3 object-fit, and see browser support tables.
CSS3 object-fit/object-position Method of specifying how an object (image or video) should fit inside
its box. object-fit options include "contain" (fit according to aspect
ratio), "fill" (stretches object to fill) and "cover" (overflows box
but maintains ratio), where object-position allows the object to be
repositioned like background-image does.
JSFIDDLE DEMO
.container {
width: 200px; /*any size*/
height: 200px; /*any size*/
}
.object-fit-cover {
width: 100%;
height: 100%;
object-fit: cover; /*magic*/
}
<div class="container">
<img class="object-fit-cover" src="https://i.stack.imgur.com/UJ3pb.jpg">
</div>
Related Info:
Exploring object-fit ★ Mozilla Hacks
Polyfill for CSS object-fit property

You can achieve this using css flex properties. Please see the code below
.img-container {
width: 150px;
height: 150px;
border: 2px solid red;
justify-content: center;
display: flex;
flex-direction: row;
overflow: hidden;
}
.img-container .img-to-fit {
flex: 1;
height: 100%;
}
<div class="img-container">
<img class="img-to-fit" src="https://images.pexels.com/photos/8633/nature-tree-green-pine.jpg" />
</div>

Related

How to wrap a resizable div around a image using flexbox

Im trying to wrap a div around a image both when the width or height changes.
The issue is that when the width changes the div does not tightly wrap against the child in this case the child is a image:
Wrap div around a image current result
I did determine that setting the flex-direction between row and column solves it when the div gets resized and could use something like a resize observer to toggle the flex direction but hope there is a css solution to this?
Here is a code pen with the issue: https://codepen.io/quinnaz/pen/rNJdjJy
<div class="container direction-row">
<div class="border">
<img src="https://dummyimage.com/400x600/d4b9d4/7477a3.png" class="img-element" />
</div>
</div>
.container {
resize: both;
overflow: auto;
background-color: beige;
border: solid;
display: flex;
}
.direction-row {
flex-direction: row;
}
.direction-col {
flex-direction: column;
}
.img-element {
max-width: 100%;
max-height: 100%;
display: block;
}
.border {
border-width: 50px;
border-color: blue;
border-style: solid;
}
You need to use the object-fit property and give it the value cover. I would also change max-width and max-height to width and height respectively.
The replaced content (in this case an image) is sized to maintain its aspect ratio while filling the element's entire content box. If the object's aspect ratio does not match the aspect ratio of its box, then the object will be clipped to fit.
codepen link https://codepen.io/thechewy/pen/ZErxevo
.img-element {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
** EDIT **
If you want it to fully fit the .container div you'll then need to make the .border div fill the parent .container with width: 100%; height: 100%; set on .border, this isn't clear in the question though. If not the above snippet should do the trick.
Personally I would just add the border to the image and remove the extra div and CSS.

How to crop image in HTML as a percentage of it's height?

In my HTML code, I have a PNG image that I resized using CSS:
.adjust-image {
border:1px solid #021a40;
display: block;
width: auto;
max-width: 100%;
max-height: 1000px;
}
.img-container {
position: relative;
}
<div class= "img-container">
<img class = "adjust-image noselect fade-out" src="{{ s.photo.url }}">
</div>
Using the image's current size (with max-height), how can I crop the image as a percentage, instead of using px for height?
For instance, how can I get CSS written so that I can just designate something like: height: 34%?
The height property can only use a percentage if its parent has a fixed height. What you can do however is place the image as a background image. Then you can set the height to 0, and as long as the width of the image is 100%, then you can use padding-bottom of a percentage since that references the width of its parent. Weird I know. So an example:
.img {
width: 100%;
height: 0;
padding-bottom: 34%;
background-size: cover;
}
Of course, this may not be the best semantically, but it is a classic way to use aspect ratio in CSS. And once aspect-ratio is sufficiently supported, that will be a great option.

How to adjust image size in html using css

I'm developping an ionic application, and i want to display some images in some cards, the problem is that my images have not the some size, and i want them to look the some.
The idea is to use à css class that will solve the problem ( at least in the width )
.full-width-image {
width: 100%
}
this class will solve the problem of size and all the images will have the some width. how ever i dont know how to make a fixed height for them all. if i add to my css class a fixed height like:
.full-width-image {
width: 100%;
height: 60px;
}
some pictures will look ugly:
how it looks like
what i want is to hide the extra part of the image.
If you have a set width and height you can use object-fit: cover; for the image to fill the entire space without losing its aspect ratio.
I would recommend you to use a flex wrapper around an image.
.wrapper {
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 0 2px gray;
width: 100px;
height: 100px;
overflow: hidden;
margin: 1em;
}
.wrapper img {
border: 1px solid black;
max-width: 100%;
max-height: 100%;
}
.example {
display: flex;
}
<div class="example">
<div class="wrapper">
<img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a">
</div>
<div class="wrapper">
<img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a">
</div>
<div class="wrapper">
<img src="https://upload.wikimedia.org/wikipedia/commons/e/eb/Ash_Tree_-_geograph.org.uk_-_590710.jpg">
</div>
<div>
Using this technique you get a kind of smart image - it scales itself to fit your wrapper, its fixed size, but without distortion. Look, there are black borders around the images, so you can see that both an image with width > height and an image with a tree, where height > width, fit well the wrapper, restricting the width and the height correspondingly.
Also you can you inline-flex instead of flex in the wrapper class.

How make a div container responsive?

I have a div with a background-image assigned in the CSS3 file.
The image is responsive, so it scales according to the screen size BUT the container keeps the height at all screen sizes.
I need to know if there is a way to make the container responsive as well as the background image.
HTML:
<div class="responsive> </div>
CSS3:
.responsive {
background: url('https://s20.postimg.org/o09gf7fvx/bag.jpg') no-repeat center top;
border: 1px solid red;
background-size: contain;
width: 100%;
height: 270px;
}
I must use background-image selector and no img src tag.
Here is the fiddle file.
Thank you.
Update - February 3rd, 2021
Since I wrote the original answer a new CSS property has been introduced - 'aspect-ratio' - to solve this problem.
<div id="responsive">some text</div>
CSS:
#container {
width: 100%;
background: hotpink;
aspect-ratio: 100 / 29;
}
At the time of writing this CSS property doesn't yet have widespread browser support.
Working Example: https://jsfiddle.net/fu0nL57t/
Ref: https://web.dev/aspect-ratio/
=====================================================
Original Answer
This can be done an additional dummy element, inside the element you want to keep at a fixed ratio. If you specify a padding-top or padding-bottom as a percentage, that is in terms of the width of the container element, and this then keeps the height of the container element at a fixed ratio.
<div id="responsive">
some text
<div id="dummy"></div>
</div>
CSS:
#responsive {
display: inline-block;
position: relative;
width: 100%;
background: url('https://s20.postimg.org/o09gf7fvx/bag.jpg') no-repeat center top;
background-size: contain;
}
#dummy {
padding-top: 29%;
}
Working Example:
https://jsfiddle.net/098jj61q/
Credits:
http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio
http://alistapart.com/article/creating-intrinsic-ratios-for-video
Yes its correct. According to #Paulie_D, you can't do that with background image.As per your requirement you can do that using img tag only.
What you have to do, without using the div just make the image responsive by treating it as a block element as,
.img-responsive {
display: block;
max-width: 100%;
height: auto;
}
or if you insist to use division with background image then cover the backgound image and set min-height as,
div.mydiv {
background:url(background_image.jpg);
background-repeat:no-repeat !important;
background-size: cover !important;
background-position:center center !important;
min-height:300px;
}

Why isn't object-fit working in flexbox?

I have several columns that I am giving equal width using flex. Each contains img tags, and I'd like those images to exhibit the object-fit: cover sizing.
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.test {
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
img {
object-fit: cover;
}
<div class="container">
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
</div>
The images are not resizing, as can be seen in this demo. Why is that?
From the specification:
The object-fit property specifies how the contents of a replaced
element should be fitted to the box established by its used height and
width.
The key term being: fitted to the box established by its used height and width
The image gets replaced, not its container. And the box established by its used height and width relates to the image itself, not its container.
So, scrap the container and make the images themselves the flex items.
.container {
display: flex;
flex-direction: row;
width: 100%;
}
img {
object-fit: cover;
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
<div class="container">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
</div>
Revised Codepen
Additional Details
5.5. Sizing Objects: the object-fit
property
The object-fit property specifies how the contents of a replaced
element should be fitted to the box established by its used height and
width.
Here are three of the values:
cover
The replaced content is sized to maintain its aspect ratio while
filling the element's entire content box.
contain
The replaced content is sized to maintain its aspect ratio while
fitting within the element's content box.
fill
The replaced content is sized to fill the element's content box.
With cover the image retains its aspect ratio and covers all available space. With this option, much of an image may be cropped off-screen.
With contain the aspect ratio is also maintained, but the image scales to fit within the box. This may result in whitespace on the left and/or right (portrait fit), or top and/or bottom (landscape fit). The object-position property can be used to shift the image within its box.
With fill the aspect ratio is abandoned and the image is sized to fit the box.
Browser Compatibility
As of this writing, object-fit is not supported by Internet Explorer. For a workaround see:
Neat trick for CSS object-fit fallback on Edge (and other browsers)
fitie - An object-fit polyfill for Internet Explorer
object-fit-images - Adds support for object-fit on IE9, IE10, IE11, Edge and other old browsers
Polyfill (mostly IE) for CSS object-fit property to fill-in/fit-in images into containers.
The problem is that object-fit specifies how an image is painted inside the img, but you didn't specify the sizes of these elements, only the sizes of their .test parents.
So an alternative to Michael_B's answer is making the images have the same size as the flex items:
img {
height: 100%;
width: 100%;
object-fit: cover;
}
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.test {
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
<div class="container">
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
</div>
For anyone who can't just "scrap the container and make the images themselves the flex items," just add container levels:
<div class="display-flex">
<div class="flex-grow position-relative">
<div class="pos-absolute top-left-right-bottom-0">
<img class="object-fit-cover height-width-100">
As a way to support the object-fit functionality for your images in non-compatible browsers, you can create a CSS class with background-image and background-size. For it to properly calculate the occupied space, you wrap an img element and make it invisible. Example below.
HTML
<div class="my-image">
<img src="path/to/my/image"/>
</div>
CSS
.my-image {
background-image: url('path/to/my/image');
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.my-image > img {
visibility: hidden;
}
If the <img/> is stretched to 100% in IE11 then add flex-shrink: 0 on the <img/> itself, as adviced here: Flexbox on IE11: image stretched for no reason?