How to make div height to be always proportional of its width (without hacks)?

css aspect ratio based on height
css height proportional to width
flexbox
css aspect ratio calculator
css width equal to height
css grid aspect ratio
css maintain aspect ratio image
flexbox aspect ratio

I have a Flexbox div with 12 images within. I want width of every image to be 25% of that div. That image must have height = 133,33% of width. And in case image has dimensions that not equal to my 3*4, image has to be scaled to fit my 3*4. So how can I achieve that? I think I need a tool like calc(width*4/3).

My css and html:

.image-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  align-items: center;
  width: 100%; 
  }
  .image-grid .image-wrapper {
    width: 25%;
    height: 133.3333%; // nothing happens if I delete this line. Flexbox?
    }
  .image-grid .image {
    display: block;
    width: 100%;
    object-fit: cover; 
    }
<div class="image-grid">
    <div class="image-wrapper"><img src="assets/img/portfolio-1.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-2.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-3.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-4.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-5.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-6.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-7.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-8.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-9.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-10.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-11.jpg" alt="" class="image"></div>
    <div class="image-wrapper"><img src="assets/img/portfolio-12.jpg" alt="" class="image"></div>
</div>

you can maintain a 3:4 aspect-ratio on the wrapper by putting padding-top: 133.33%on it. So instead of setting the height, you can set the padding.

Also you need to set position: relative to the wrapper and position: absolute to the child, so the positioning of the child ignores the padding.

there's an example in the following snippet:

.row {
  display: flex;
  flex-wrap: wrap;
}

.column {
  width: 25%;
}

.wrapper {
  padding-top: 133.33%;
  border: 1px solid red;
  position: relative;
}

.wrapper img {
  position: absolute;
  display: block;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  object-fit: cover;
}
<div class="row">
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
  <div class="column">
    <div class="wrapper">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREb_QCChITKrV0oIljZeP1irlF4UT74fQbJYNiawkZ9efEgREQoA">
    </div>
  </div>
</div>

Using SVG with CSS3 and HTML5: Vector Graphics for Web Design, You do it by setting the element's padding instead of its height. However, padding set using percentage values is always proportional to the available width, Tip This “padding hack” is also useful for many other cases where you want to  The aspect ratio of an element describes the proportional relationship between its width and its height. Two common video aspect ratios are 4:3 (the universal video format of the 20th century), and 16:9 (universal for HD television and European digital television, and default for YouTube videos).

Try this:

.image-grid {
  display: flex;
  flex-wrap: wrap;
}

.image-grid .image-wrapper {
  position: relative;
  width: 25%;
  height: 0;
  padding-bottom: 33.3333%;
}

.image-grid .image {
  position: absolute;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
<div class="image-grid">
  <div class="image-wrapper"><img src="https://picsum.photos/200/300?1.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/300/200?2.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?3.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/300/300?4.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/300/400?5.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?6.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?7.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/400?8.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/400/200?9.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?1.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?2.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="https://picsum.photos/200/200?4.jpg" alt="" class="image"></div>
</div>

CSS3 Pushing the Limits, Flex items can also flex their size based on a proportion of the available space, Finally, the Flexbox model provides you with the alignment control you've always dreamed of! Equal widths and spacing, equal height columns, vertical alignment, and much more that you've no doubt been forced to hack together in the past! The only way to make the height of a div equal to the tallest column is if that div contains all the columns. MatchHeight will make the height of all the selected elements exactly equal by using a simple selector and an initialization function. To set fixed heights, we added the “height:” attribute to the cells.

Here's an idea that should work if the container spans the complete width of the window:

Make the image container 25% wide and 25vw*4/3 high (there you have your calc...). Also use overflow: hidden on the container to keep the fixed ratio.

Make the images 100% high and set their width to auto. This will make them fill the container vertically. Then center them by appliying transform: translate-x(-50%), position: relative and left: 50%;.

This only works for images whose height is less than 4/3 of the width, but from what I understood, that's the situation you have?

* {
  margin: 0;
}

.image-grid {
  display: flex;
  flex-wrap: wrap;
}

.image-grid .image-wrapper {
  flex-shrink: 1;
  flex-grow: 0;
  width: 25%;
  height: calc(25vw*4/3);
  overflow: hidden;
}

.image-grid .image {
  height: 100%;
  width: auto;
  display: block;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}
<div class="image-grid">
  <div class="image-wrapper"><img src="http://lorempixel.com/output/city-h-c-300-400-1.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/transport-h-c-300-400-5.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/cats-h-c-300-360-6.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/nature-h-c-300-335-10.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/transport-h-c-300-400-5.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/cats-h-c-300-360-6.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/nature-h-c-300-335-10.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/city-h-c-300-400-1.jpg" alt="" class="image"></div>

  <div class="image-wrapper"><img src="http://lorempixel.com/output/cats-h-c-300-360-6.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/city-h-c-300-400-1.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/transport-h-c-300-400-5.jpg" alt="" class="image"></div>
  <div class="image-wrapper"><img src="http://lorempixel.com/output/nature-h-c-300-335-10.jpg" alt="" class="image"></div>

</div>

Aspect Ratio Boxes, I had a little situation the other day where I needed to make one of those This isn't a hack, but it is weird: padding-top and padding-bottom is based on the If the width changes, so does the height, and the element keeps that aspect ratio. We're essentially setting heights here, which should always flash a blinking red  The resize image property is used in responsive web where image is resizing automatically to fit the div container. The max-width property in CSS is used to create resize image property. The resize property will not work if width and height of image defined in the HTML. Syntax: img { max-width:100%; height:auto; }

The English Cyclopedia, The whole width need not be above two feet six inches, wheraisabank and ditch or, where it can be done without inconvenience, it is better to make an entirely new hacked through, leaving only a small portion of the under bark uncut, have an if the height of the barometer remained always the same at the same height​  What I would like to discuss here is how could we make a div fit to the inner content being it’s width unknown, and in this case, being all the images different in widths? As you can see in the example bellow they had to make the div’s width fixed/static instead of flexible to the images inside, so in some pages you can continue scrolling

The Encyclopaedia Britannica: A Dictionary of Arts, Sciences, , The dimensions of the exterior piers ceased to control the height of the 5"" c'! and by a conSideration of the amount of floor space which could be devoted without may become an element of danger in building with the steel cage, while the In buildings wide in proportion to their height it is the ordinary practice to make  In our example the inner div inherits the width from its parent, outer. The height of outer is auto, therefore as high as its content, inner, which in turn is only its padding as it has no content on its own. The "naive" approach to use the height attribute with a percentage does not work because the reference value for the height percentage is

A width-responsive perfect square in pure CSS - DEV, width: 100% is to make sure it's defined as having the same width as its outer, it's always based on the width, even if it's a -top or -bottom property. put stuff inside it without disrupting the padding; any additional content would add #​circle { position: absolute; top: 0; bottom: 0; width: 100%; height: 100%;  Using width, max-width and margin: auto; As mentioned in the previous chapter; a block-level element always takes up the full width available (stretches out to the left and right as far as it can). Setting the width of a block-level element will prevent it from stretching out to the edges of its container. Then, you can set the margins to auto

Comments
  • try this: height: 100%, width: auto; *edit --> inside .image-grid .image
  • @PeterBejan, my images not always have the same size, so I get them stretched. I also don't have my div's height (it has to be evaluated, 4/3 of width).
  • @PeterBejan, and what is "*edit --> inside .image-grid .image"? CSS?
  • Yes, add this data inside .image-grid .image (CSS) {height: 100%; width: auto}
  • Xm, I found mademyday.de/… that page now. Hack, but looks like it exactly what I need, and I think that is exactly what you mean, right?
  • if you use scss, you can use this mixin from css-tricks https://css-tricks.com/snippets/sass/maintain-aspect-ratio-mixin/ for a better readability and reusability
  • thanks for css-tricks. But... There's no "no-hack" solution, right?
  • I think this is the best way to do it, especially if you are using the mixin, it is a very clean and readable way. since you only have to put @include aspect-ratio(3, 4); on the class
  • Yes... Now I think so.
  • padding is a standard property, applied to a standard selector wich is parsed consistently in all major browsers in a standard way. Is it a hack? I don't think so..
  • Thanks for your answer, I'm looking for universal solution, so I can't get vw
  • What do you mean by universal? vw should cover most used browsers: caniuse.com/#feat=viewport-units
  • @Darlesson, I mean that I need a solution for any div's width, not only 100vw
  • If "any div's width" is a set width, you can calculate the height of the image container (height of image-wrapper = width of container DIV divided by 3), only if it has to be completely dynamic, this won't work. But you could use media queries with different fixed widths in various steps for that container...