Martin DeMello Martin DeMello - 9 days ago 4
CSS Question

Confine a scrollable list to within the viewport height

I have a crossword editor laid out as

_______________________
Top bar
_______________________

........ ___________
........ Across Clues
..Grid..
........
........
___________
Down Clues



_______________________
Bottom bar
_______________________


The across and down clues are both unordered lists, with the html structure

<div>
<label>Across</label>
<ul>Clues</ul>
<label>Down</label>
<ul>Clues</ul>
</div>


There's a codepen here with a stripped-down version of the complete page html and enough placeholder clues to demonstrate the problem.

I'd like the list of clues to size itself to between the grid height (minimum) and the page height minus top/bottom bars (maximum), with scrollbars appearing on both lists if they get too long. What is happening instead is the lists are both displaying all the clues, with a scrollbar appearing on the entire page.

Answer

Fixed with some help from a friend; I'm inserting the entire skeleton in case it helps someone else. Setting the body height to 98vh seems to have been the key fix to not having a full-page scrollbar; for some reason 100% or 100vh both take up a little more space than the actual viewport.

div {
  border: 1px solid #aaa;
}
html,
body {
  height: 98vh;
}
#main {
  height: 100%;
  display: flex;
  flex-flow: column;
}
.crosspad-statusbar {
  max-height: 10%;
}
.crosspad-main {
  display: flex;
}
.crosspad-grid-container {
  flex: 1;
}
.crosspad-clues-container {
  flex: 2;
  display: flex;
  flex-flow: column;
}
.crosspad-clue-section {
  flex: auto;
  overflow: scroll;
}
<html>

<body>
  <div id="main">
    <div class="crosspad-statusbar">
      <p>Top bar</p>
    </div>
    <div class="crosspad-main">
      <div class="crosspad-grid-container">
      </div>
      <div class="crosspad-clues-container">
        <p class="title">Across</p>
        <div class="crosspad-clue-section across">
          <ul class="crosspad-clue-list">
            <li class="crosspad-clue-current">
              <div class="crosspad-clue-number">1</div>
              <div class="crosspad-clue-text"></div>
            </li>
          </ul>
        </div>
        <p class="title">Down</p>
        <div class="crosspad-clue-section down">
          <ul class="crosspad-clue-list">
            <li class="crosspad-clue-current">
              <div class="crosspad-clue-number">1</div>
              <div class="crosspad-clue-text"></div>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="crosspad-statusbar bottom">
      <p>Bottom bar</p>
    </div>
  </div>
</body>

</html>