Search code examples
htmlcssflexboxcodepen

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.


Solution

  • 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>