Resizing flex div image instead of cropping - html

I have a flex with 3 images and I would want them resize if a window is too small right now when window gets smaller first they reorder so they stack vertically and when window gets even smaller the picture gets squeezed instead of resized I would want to keep the image with proper aspect ratio.
.images {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.images div {
display: flex;
margin: 1rem;
}
.images img {
height: 16rem;
max-width: 100%;
}
<div class="images">
<div>
<img src="http://placehold.it/150x200">
</div>
<div>
<img src="http://placehold.it/150x150">
</div>
<div>
<img src="http://placehold.it/150x100">
</div>
</div>

First of all the basic thing to keep in mind to maintain aspect ratio (I'm sure you already know this) is to restrict only one dimension of an image. (Read this)
You are already breaking this in your code- resulting in the 'squeeze' at smaller screen widths:
.images img {
height: 16rem;
max-width: 100%;
}
When window gets smaller first they reorder so they stack vertically
and when window gets even smaller the picture gets squeezed instead of
resized I would want to keep the image with proper aspect ratio.
So here are your options:
So I guess you should remove max-width: 100% and keep width adjust depending on the 16rem height.
.images {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.images div {
display: flex;
margin: 1rem;
}
.images img {
height: 16rem;
/*max-width: 100%;*/
}
<div class="images">
<div>
<img src="http://placehold.it/150x200">
</div>
<div>
<img src="http://placehold.it/150x150">
</div>
<div>
<img src="http://placehold.it/150x100">
</div>
</div>
Well, for small widths you would have horizontal scroll. According to the particular case, if needed you can use some media queries to adjust height at small screen widths.
Let me know your feedback on this. Thanks!

.images img{
height: 16rem;
max-width: 100%;
object-fit: contain;
}

For the aspect ratio fix, you can just run with the CSS3 object-fit property. CSS3 Object-Fit
Set it on your image as:
.images img {
object-fit: contain;
}
That should do the trick of keeping the aspect ratio of the image.
As for the Wrapping that takes place within the flex container, just take out the flex-wrap property in your code so they'll all stay on the same row, rather than wrapping as the container size gets smaller.
EDIT
Try adding a align-self CSS Property to the .images img, see if that's what you're looking for:
.images {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.images div {
display: flex;
margin: 1rem;
}
.images img {
width: 100%;
height: auto;
object-fit: contain;
align-self: flex-start;
}
Hope this helps!

Related

Flex item size from background image

there is a flexbox with flex items
every flex item should be shown as a clickable folder with particular text in it
as far as I understand, the only way to achieve that via CSS is to have a background image
The problem is that I want to get the following as well:
Constraint every flex item, ideally only by the width, e.g. max-width: 20% (to show it nicely on mobile)
Let flex items automatically expand their width/height to show a complete background image (preserving the constraint above)
Unfortunately, was unable to find a right combination of params for that, so far it looks like this:
<div class="container">
<div class="column">
name1
</div>
<div class="column">
name2
</div>
</div>
.container {
height: 100vh;
display: flex;
flex-flow: row wrap;
align-items: center;
}
.column {
max-width: 20%;
background-image: url("./ic-folder.png");
background-size: contain;
background-repeat: no-repeat;
display: flex;
align-items: center;
justify-content: space-around;
This doesn't achieve the goal - looks like every item is large enough just to cover nested <a> and they don't care about background there, so, they are smaller than desired.
I have an assumption that in this particular case we can hard-code the item's size as background image size, but that means that every time the background image is changed, we need to adjust the css with its new dimensions.
Is there any CSS way to force the element to grow in a way to cover its background image?
I think instead of adding the image in the background-image you can put it inside of the element. When you do this image will be clickable. Also if you use the style code that I wrote for the img you create a responsive image. If you want to control the image size you can play with its parent div with this way you can manage to control the width. So I suggest you give what width that you want to the .column and control your width and image problem.
.container {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.column {
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
max-width: 20%;
/* background-image: url("https://t1.thpservices.com/previewimage/gallil/bbd632f2f8bb5df1c8f8aba51a0ef5dd/esy-008887292.jpg");
background-size: contain;
background-repeat: no-repeat; */
}
img {
max-width: 100%;
height: auto;
object-fit: contain;
}
#media screen and(max-width: 450px) {
.container {
flex-direction: column;
}
}
<div class="container">
<div class="column">
<a href="path1"
><img
src="https://t1.thpservices.com/previewimage/gallil/bbd632f2f8bb5df1c8f8aba51a0ef5dd/esy-008887292.jpg"
alt=""
/>name1</a
>
</div>
<div class="column">
<a href="path2"
><img
src="https://t1.thpservices.com/previewimage/gallil/bbd632f2f8bb5df1c8f8aba51a0ef5dd/esy-008887292.jpg"
alt=""
/>name2</a
>
</div>
</div>

img not respecting height property when parent size is defined

I have a column flex container, with one flex child containing an image
<div class="flex">
<p> Test </p>
<div class="flex-item">
<img class="img" src="https://i.imgur.com/E4Os1Fh.png">
</div>
</div>
All elements are given width 100% height 100% along the chain.
html, body {
height: 100%;
}
.flex {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
}
.flex-item {
flex: 1;
}
.img {
width: 100%;
height: 100%;
}
How come the image is not respecting the height properties and is taking up more space than the height of its parent element?
JSFiddle: https://jsfiddle.net/ohewn35k/4/
(You need to resize the window to be smaller than the natural image size to see the problem in action)
EDIT: The example in this question seems to be working fine, but it doesn't not work in my actual code. I have stripped my code down in developer tools and uploaded a zip file
https://www.mediafire.com/file/v32z4xrxnstyd3d/reproduce.7z/file
If you extract the file and open reproduce.html you'll see that the image element has a scrollbar as it's expanding passed its available space for some reason.
Once I fix this problem, I intend to add object-fit: contain to the image so it contains nicely within its available space.
Since you're using flexbox.
Your .flex-item becomes this:
.flex-item {
flex: 1;
}
Essentially you're are telling the flex item to use the maximum space available.
You can read about the flex property on MDN
Your CSS '.img' selector should just be 'img'
Try this
<div class="flex">
<div class="flex-item">
<img src="https://i.imgur.com/E4Os1Fh.png">
</div>
</div>
html, body {
height: 100%;
}
.flex {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
}
.flex-item {
width: 100%;
height: 100%;
}
img {
width: 100%;
height: 100%;
}

Make image responsive maintaining aspect ratio, with padding either side

Here is a link to the working pen: https://codepen.io/Adam0410/pen/OBqRRN
HTML
<div id="imgWrapper">
<img src="https://thestoryengine.co/wp-content/uploads/2017/11/The-crossroads-Section-images-02.png">
</div>
CSS
#imgWrapper {
display: flex;
justify-content: center;
width: 100%;
padding: 0 20px;
}
#imgWrapper img {
width: 100%;
max-width: 1660px;
height: auto;
}
I don't want the image to exceed its original width (hence max-width) but I want it to scale down to the width of the viewport while maintaining its aspect ratio. Currently, the height does not scale with the width, why is this?
Why do you need display flex to imgWrapper?
Change it to block and it will work as expected. In case you need flex in there add it to other wrapper.
#imgWrapper {
display: block;
}
What about using the vm unit to your #imgWrapper making it always responsive:
#imgWrapper {
display: flex;
justyfy-content: center;
vm: 100%;
padding: 0 20px;
}

Background image cover does not scale the image down

I've got a calendar div (that actually has height and width set to 100vh and 100vw to be fullscreen) containing a header and an actual calendar.
I use flex because I want the header to have a specific height, and the contained calendar to take all the vertical space it has left.
rbc-calendar is actually an external library I use (React Big Calendar) which uses flex on its own to scale the rows. I've put the main div css in case it comes in relevant.
I want my calendar container to have a background image. So only for the calendar itself, not the header. I want this image to be scaled down until the height (width) fits the calendar's height (weight), keeping the image's aspect ratio and letting it overflow for the same amount on right/left (top/bottom).
Background-image: cover seems to be what I'm looking for, but for some reasons the image does not get scaled down at all.
.calendar {
height: 333px;
width: 333px;
display: flex;
flex-direction: column;
}
.calendar-header {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
background: lightblue;
}
.calendar-container {
flex: 1;
background-size: cover;
background: #000 url('https://www.chenhuijing.com/slides/29-constellation-2018/img/meme1.jpg') no-repeat center center;
}
.rbc-calendar {
height: 100%;
display: flex;
align-items: stretch;
}
<div class="calendar">
<div class="calendar-header">
<h1>Not working calendar</h1>
</div>
<div class="calendar-container">
<div class="rbc-calendar">
</div>
</div>
</div>
Answer in the question's comments by Temani-afif : setting background after background-size overrides the statement.

Why does flexbox stretch my image rather than retaining aspect ratio?

Flexbox has this behaviour where it stretches images to their natural height. In other words, if I have a flexbox container with a child image, and I resize the width of that image, the height doesn't resize at all and the image gets stretched.
div {
display: flex;
flex-wrap: wrap;
}
img {
width: 50%
}
<div>
<img src="https://i.imgur.com/KAthy7g.jpg" >
<h1>Heading</h1>
<p>Paragraph</p>
</div>
What causes this?
It is stretching because align-self default value is stretch.
Set align-self to center.
align-self: center;
See documentation here:
align-self
The key attribute is align-self: center:
.container {
display: flex;
flex-direction: column;
}
img {
max-width: 100%;
}
img.align-self {
align-self: center;
}
<div class="container">
<p>Without align-self:</p>
<img src="http://i.imgur.com/NFBYJ3hs.jpg" />
<p>With align-self:</p>
<img class="align-self" src="http://i.imgur.com/NFBYJ3hs.jpg" />
</div>
I faced the same issue with a Foundation menu. align-self: center; didn't work for me.
My solution was to wrap the image with a <div style="display: inline-table;">...</div>
Adding margin to align images:
Since we wanted the image to be left-aligned, we added:
img {
margin-right: auto;
}
Similarly for image to be right-aligned, we can add margin-right: auto;. The snippet shows a demo for both types of alignment.
Good Luck...
div {
display:flex;
flex-direction:column;
border: 2px black solid;
}
h1 {
text-align: center;
}
hr {
border: 1px black solid;
width: 100%
}
img.one {
margin-right: auto;
}
img.two {
margin-left: auto;
}
<div>
<h1>Flex Box</h1>
<hr />
<img src="https://via.placeholder.com/80x80" class="one"
/>
<img src="https://via.placeholder.com/80x80" class="two"
/>
<hr />
</div>
It is stretching because align-self default value is stretch.
there is two solution for this case :
1. set img align-self : center
OR
2. set parent align-items : center
img {
align-self: center
}
OR
.parent {
align-items: center
}
I had a similar issue while making my navigation bar, but none of the above worked for me.
My solution was adding height: 100% for the image.
If you're aligning the items horizontally, add width: 100% instead.
EDIT: Chrome seems to add this value by default now, but you'll need to add this for compatibility.
Use one of the CSS settings below: contain or cover is most popular
.my-img {
object-fit: contain;
}
or
.my-img {
object-fit: cover;
}
I had a similar issue, my solution was adding flex-shrink: 0; to the image.