4lackof 4lackof - 3 months ago 28
CSS Question

Maintain aspect ratio of flex item

I have a page which is supposed to emulate a letter size piece of paper. The page is basically split into two parts, the top nav-bar and the the main part of the page.

My code currently looks like this:



html, body { height: 100%; overflow: hidden; }
body {
display: flex;
flex-flow: column;
font-family: "Arial", "Helvetica", "sans-serif";
font-size: 1em;
}
.hor-nav {
background-color: #666;
color: white;
height: 64px;
}
.main {
display: inline-flex;
flex: 1;
width: 100%;
}
.page {
border: 1px solid black;
flex: 1 1 auto;
margin: 16px;
padding-right: 77.27975270479134%;
}

<div class="hor-nav">
test
</div>
<div class="main">
<div class="page">
test
</div>
</div>





I have been trying to make use of the "padding %" trick but it does not seem to be working for.


My end goal is the "paper" (an emulation of 11in tall and 8.5in wide piece of letter paper) to fill the remaining vertical/height space after the nav-bar (the grey bar at the top of the above snippet) while at the same time keep the aspect ratio of 11:8.5 (or 1.294:1).


To fill the vertical space I am using a flex box and the paper is a flex-item with the property:
flex: 1 1 auto;
. This grows or shinks the paper to accommodate the change of the webpage, however, it also effects it's width.

The most successful I have gotten is getting rid of the
flex: 1 1 auto;
and using
width: 77.2%;
(what I calculated to be the width of a piece of "paper," however this number might not be correct), except that this did not work, as it did not hold the aspect ratio, but instead just made sure the width was only 77.2% of the containing element.

note: as you can see from my above snippet, I am using a
padding
as I attempted the padding trick for this but as @Michael_B pointed out this does not work. As I have no other working code I have not been able to replace it out yet.



Does anyone know how to keep a flex-item aspect ratio while at the same time growing it's height to fill the rest of the document (of course, with the margins)


Thank you.

Answer

Using an aspect ratio calculator, we can determine that 8.5 x 11 is equivalent to 8 x 10 (80% x 100%).

Using CSS viewport percentage units, we can set an element's height to emulate letter-size paper on all screen sizes.

This is the basic code:

.page {
  height: 100vh;
  width: 80vh;
}

body {
  display: flex;
  flex-flow: column;
}
.hor-nav {
  background-color: #666;
  color: white;
  height: 64px;
}
.main { }

.page {
  border: 1px solid black;
  margin: 16px;
  height: calc(100vh - 32px - 64px);  /* height, less margins, less nav height */
  width: calc(80vh - 32px - 64px);
}
<div class="hor-nav">test</div>
<div class="main">
  <div class="page">test</div>
</div>

jsFiddle