Make image responsive maintaining aspect ratio, with padding either side - html

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;
}

Related

How can I make a resizable flex item retain its aspect ratio?

I have an effect on my website, and it only works within a 16:9 aspect ratio. This means I need to keep it within that aspect ratio. I wanted to make a box that was vertically and horizontally centered which could resize proportionally to contain the effect. I looked up many tutorials and guides on flex resizing, but i still cant get it to work properly. The padding in the that contains the box is lopsided, and it doesnt align properly either. It scrolls horizontally even though im using 100vh/vw?? Does 100% of the viewport's height really mean what it says?
I'm really not sure what to do...
Codepen example of my code below:
https://codepen.io/Ktashi/pen/KKeOJey
html
<div class="flex-align">
<div class="aspect-ratio-box"></div>
</div>
css
body {
padding: 0;
margin: 0;
}
.flex-align {
width: 100vw;
height: 100vh;
margin: 0;
padding: 1vw;
display: flex;
align-items: center;
justify-content: center;
}
.aspect-ratio-box {
height: auto;
aspect-ratio: 16/9;
background: red;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 94vw;
max-height: 94vw;
max-width: 94vw;
}
I tried changing the flex-grow: property's value, along with flex-shrink: and flex-basis: but that didn't help much. I'm very stuck as I've only really been coding with html and css for about a year off and on.
You can use the CSS media query to test whether the item will fit within the parent which has 100vw/100vh dimensions.
This snippet is just to give the idea.
It does a couple of things - makes the parent's padding be part of its dimensions by setting box-sizing border-box and sets the height or width as % of the parent dimensions.
.aspect-ratio-box {
aspect-ratio: 16/9;
background: red;
}
#media (max-aspect-ratio: 16 / 9) {
.aspect-ratio-box {
width: 94%;
}
}
#media (min-aspect-ratio: 16 / 9) {
.aspect-ratio-box {
height: 94%;
}
}
body {
padding: 0;
margin: 0;
background: black;
}
.flex-align {
background: blue;
width: 100vw;
height: 100vh;
margin: 0;
padding: 1vw;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
<div class="flex-align">
<div class="aspect-ratio-box"></div>
</div>

How can I make three containers grow at the same size

So I am building a 3 column preview card using HTML, CSS and FLEXBOX. I built it using the mobile-first approach. It starts off as a column but when it is being expanded and it reaches a certain dimension, it transforms into a row. The problem I am having is that as the containers transform to a row, they grow in different sizes. The heights grow differently as some become columns become taller than others. How can I make sure they all grow at the same rate? How do I make sure that one column does not become larger than the other as they are being expanded? I tried setting flex-grow to 1 and flex-shrink to 1 but it is not working. Please find relevant parts of my code below.
Here is a link to the live version of my site
body {
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
--The panel is the container as a whole--
.panel {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid white;
border-radius: 10px;
width: 100%;
max-width: 960px;
height: 100%
}
--I am styling each column below--
.panel section {
display: flex;
padding: 2.5rem;
flex-direction: column;
text-align: left;
border-bottom: none;
height: 100%;
#media only screen and (min-width: 560px) {
.panel {
display: flex;
flex-direction: row;
border-radius: 10px ;
width: 80%;
height: 100%;
}
.panel section {
height: 100%;
}
}
Remove the height: 100% from the child elements and just simply change the align-items to stretch on desktop, that will create equal height columns.
Well there can be different ways to solve this.
Problem : Due to which this error occur . It the difference between the amount of content in three containers as middle has more content that is you have told more about SUVS . This is the cause
Solution : Either you can make the content almost equal or can make the height of container bigger so that content can easily fit
Content equal and Content fixed height - Less compatible as content can vary on need
Increase height of container - Using hard code(400px; 30em) you can increase the height of the container according to need of content . And you can position Learn more btn at bottom using absolute position . So that it positioned at equal height
#media only screen and (min-width: 560px)
.panel section {
height: 30em;
position: relative;
}
.general-button {
background-color: var(--major-color);
border-radius: 5rem;
padding: 0.89rem;
margin: 1.1em 0;
border: none;
width: 8rem;
position: absolute;
bottom: 0;
}

How to prevent image with srcset to go beyond intrinsic width?

Here is the minimal reproducible example:
body {
margin: 0;
}
div {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
height: 100%; /* has to be 100%, no px or em heights */
}
div img {
max-height: 100%;
max-width: 100%;
object-fit: contain;
}
<div>
<img src="https://dummyimage.com/300x225/000/fff" srcset="https://dummyimage.com/300x225/000/fff 600w, https://dummyimage.com/768x568/000/fff 768w">
</div>
The problem I have is that the image stretches beyond it's natural dimensions and I need to prevent that.
The aim is to:
Parent element of the image in full width and height
Image can't be as background-image (SEO)
Image can't have fixed width and height
Looking only for CSS solutions.

Resizing flex div image instead of cropping

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!

Fixed-aspect ratio div, constrained by the viewport, centered, up to max width and height

Is there a way to achieve this in CSS-only, without JavaScript?
I want a div with the following requirements:
it ALWAYS maintains a given aspect ratio (e.g. 4:3)
its width never exceeds a given fixed maximum in px, e.g. 800px
its height never exceeds a given fixed maximum, e.g. 600px
its dimensions never exceed those of the viewport
it's as big as it can get given the abovementioned constraints
it's centered both vertically and horizontally
In other words, it should fill either the viewport width or height, whichever is more constraining, while maintaining the given aspect ratio; unless this exceeds the fixed maximum width and/or height, in which case it would be constrained by that.
I don't care how many wrappers one inside another are needed.
I know this answer provides the solution to the fixed aspect ratio constrained by the parent's width, and it's easy to add a fixed-max-width constrain with an additional wrapper; but I can't seem to see a way to adapt that to add the height constraints.
I don't think max-height is doable but I was able to get the rest to work. http://codepen.io/syren/pen/PNvorN
#mixin aspect-ratio($width, $height) {
position: relative;
max-width:400px;
margin: 0 auto;
display: block;
&:before{
display: block;
content: " ";
width: 100%;
padding-top: ($height / $width) * 100%;
}
> .content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
.sixteen-nine {
#include aspect-ratio(16,9);
}
You may be able to do some media query magic where you change the way the aspect ratio works on devices where the top and bottom would get cut off. You can't do max-height when you set the height to be 0, but maybe this would work if you set the width to 0 and did padding-left instead of padding-top or bottom, and inverted the math. You could could that through a media query. I would totally try it out right now but I have to get back to work.
I found a couple more resources that might lead you somewhere as well.
Maintaining aspect ratio with min/max height/width?
https://dev.opera.com/articles/css3-object-fit-object-position/
Good luck!
I would recommend the css flex property. It gives you the ability to center the child elements of a parent element which has the display: flex property. Very nifty. You can achieve horizontal/vertical centering as follows.
Here's another post which has instructions for maintaining aspect ratio:
Maintain the aspect ratio of a div with CSS
html, body {
height: 100%;
width: 100%;
overflow: hidden;
margin: 0;
padding: 0;
}
.center {
display: flex;
justify-content: center;
align-content: center;
align-items: center;
align-self: center;
flex: 1 0 auto;
height: 100%;
width: 100%;
}
.center > div {
align-self: auto;
background-color: #aaa;
}
.container {
width: 100%;
padding-bottom: 75%; /* achieves 4:3 aspect ratio */
margin: 0 20px;
background-color: yellow;
}
.centered {
max-width: 800px;
max-height: 600px;
width: 100%;
height: 100%;
}
<!-- ... -->
<div class='center'>
<div class='container'>
<!-- ensure your .centered div has
some specified height & width -->
<div class='centered'>
Your content
</div>
</div>
</div>
<!-- ... -->
JSBin Demo Here