title: How to fit 2 elements to page height?
body: <p>I'm developing an app with the interface that is supposed to fit the page (only some internal elements may have scrolling). The basic layout consists of a header and the main section:</p>
  
  <pre><code>&lt;div class="page"&gt;
    &lt;Navigation/&gt; &lt;!-- a Vue component --&gt;
    &lt;main class="page__main"&gt;
      ...
    &lt;/main&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>currently, CSS has hardcoded height of the header (<code>Navigation</code>):</p>
  
  <pre><code>.page {
      height: 100vh;
  }
  .page__main {
      height: calc(100vh - 80px); /* 80px is the height of the header */
  }
  </code></pre>
  
  <p>I'd like to get rid of this hardcoded bit but make sure <code>.page__main</code>'s height gets no larger than <code>100vh - height of Navigation</code>. Is there a way to do this without JS? I suspect that there are some options that can be used with</p>
  
  <pre><code>.page {
      height: 100vh;
      display: flex;
      flex-direction: column;
  }
  </code></pre>
  
  <p>but just using that with</p>
  
  <pre><code>.page__main {
      flex-shrink: 1;
  }
  </code></pre>
  
  <p>doesn't work: <code>.page__main</code> has children which use <code>height</code> in percents and once I set <code>flex-shrink: 1;</code> instead of <code>height: calc(100vh - 80px);</code> those grow and the interface is broken.</p>
  
  <p>To illustrate the problem better, here's the current state:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body { padding: 0; margin: 0; }
  .page {
    height: 100vh;
    background: blue;
  }
  .page__navigation {
    height: 80px;
    background: gray;
  }
  .page__main {
    height: calc(100vh - 80px);
  }
  .part1 {
    height: 50%;
    background: #eeeeee;
    overflow-y: scroll;
  }
  .part2 {
    height: 50%;
    background: #cccccc;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="page"&gt;
    &lt;div class="page__navigation"&gt;nav stuff&lt;/div&gt;
    &lt;main class="page__main"&gt;
      &lt;div class="part1"&gt;
        this one usually has more elements than it could contain and those are shown with scrolling
        &lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line
      &lt;/div&gt;
      &lt;div class="part2"&gt;
        some
      &lt;/div&gt;
    &lt;/main&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>and here's what happen when I try to "set height" via flex:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body { padding: 0; margin: 0; }
  .page {
    height: 100vh;
    display: flex;
    flex-direction: column;
    background: blue;
  }
  .page__navigation {
    height: 80px;
    background: gray;
  }
  .page__main {
    flex-shrink: 1;
  }
  .part1 {
    height: 50%;
    background: #eeeeee;
    overflow-y: scroll;
  }
  .part2 {
    height: 50%;
    background: #cccccc;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="page"&gt;
    &lt;div class="page__navigation"&gt;nav stuff&lt;/div&gt;
    &lt;main class="page__main"&gt;
      &lt;div class="part1"&gt;
        this one usually has more elements than it could contain and those are shown with scrolling
        &lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line&lt;br&gt;line
      &lt;/div&gt;
      &lt;div class="part2"&gt;
        some
      &lt;/div&gt;
    &lt;/main&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>