Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent grid area from expanding causing whole page to scroll

I'm using the following grid layout:

grid-template-columns: 10em 1fr 10em;
grid-template-rows: 2em 1fr 2em;

To create a centered area that fills most of the screen while leaving some padding around it. Inside this 1fr x 1fr grid area is a pane div which contains an editor div which contains a content div.

The content div can be any height, and the editor div has overflow: scroll set. My problem is that instead of pane staying the same size and editor handling the overflow, pane grows and causes the whole page to scroll.

I can keep pane from growing by setting its overflow: scroll, but this causes the editor itself to scroll, rather than its content. This is unacceptable because the editor has buttons which must always be on screen.

Is there a way, within grid layout, to allow this functionality? I originally had it working with a flex layout, where the pane div was a single item within a 100% x 100% flexbox. I switched to grid to allow me to easily resize side-menus, so implementing this without grid is not preferable.

Also, multi-browser support would be amazing, but my target browser is Chrome.

Here's a jsfiddle with my reproducing my problem.

body, html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

#site {
  width: 100%;
  height: 100%;
  background-color: #000;
  
  display: grid;
  grid-template-rows: 10em 1fr 10em;
  grid-template-columns: 2em 1fr 2em;
  grid-template-areas:
  'top top top'
  'lpn mid rpn'
  'bot bot bot';
}

#pane {
  grid-area: mid;
  height: 100%;
  width: 100%;
  background-color: #f0f;
}

#editor {
  display: relative;
  overflow: scroll;
}

#content {
   height: 2000px;
}
<div id='site'>
<div id='pane'>
  <div id='editor'>
    <div id='content'>  
    </div>
  </div>
</div>
</div>
like image 938
eiko Avatar asked Oct 12 '18 19:10

eiko


People also ask

How do I stop my grid from stretching?

By default, a grid item cannot be smaller than the size of its content. Grid items have an initial size of min-width: auto and min-height: auto . You can override this behavior by setting grid items to min-width: 0 , min-height: 0 or overflow with any value other than visible .

How do I stop a page from scrolling?

There's another way to disable scrolling that is commonly used when opening modals or scrollable floating elements. And it is simply by adding the CSS property overflow: hidden; on the element you want to prevent the scroll.

What prevents the body from scrolling when overlay is on?

Approach: To prevent body scrolling but allow overlay scrolling we have to switch the overflow to be hidden when the overlay is being shown.


2 Answers

min-width: auto / min-height: auto

Generally speaking, a grid item cannot be smaller than its content. The default minimum size of grid items is min-width: auto and min-height: auto.

This often causes grid items to overflow their grid areas or grid containers. It also prevents scrollbars from rendering on the items, since an overflow condition can't be triggered (the grid item just keeps expanding).

To override this default (and allow grid items to shrink past their content size) you can use min-width: 0, min-height: 0 or overflow with any value other than visible.

This behavior, with references to official documentation, is explained in this post:

  • Prevent content from expanding grid items

1fr

Another thing to note is that 1fr means minmax(auto, 1fr). This means, again, that the track to which it is applied cannot shrink below the content size (i.e., the min value in the minmax() function is auto, meaning content-based).

Therefore, to override this setting, use minmax(0, 1fr) instead of 1fr.

More details here: https://github.com/w3c/csswg-drafts/issues/1777


revised demo (tested in Chrome, Firefox and Edge)

body, html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

#site {
  width: 100%;
  height: 100%;
  background-color: #000;
  
  display: grid;

  /* grid-template-rows: 10em 1fr 10em; */
  grid-template-rows: 10em minmax(0, 1fr) 10em; /* new */

  grid-template-columns: 2em 1fr 2em;
  grid-template-areas:
  'top top top'
  'lpn mid rpn'
  'bot bot bot';
}

#pane {
  grid-area: mid;
  height: 100%;
  width: 100%;
  background-color: #f0f;
  overflow: auto; /* new */
}

#editor {
  /* display: relative; */
  /* overflow: scroll; */
}

#content {
   height: 2000px;
}
<div id='site'>
  <div id='pane'>
    <div id='editor'>
      <div id='content'></div>
    </div>
  </div>
</div>

jsFiddle demo

like image 70
Michael Benjamin Avatar answered Oct 20 '22 15:10

Michael Benjamin


Not 100% sure if this is what you're asking. I added a wrapper to content to make it scrollable, and set a vh height on it, which you could adjust.

#content-scroll {
   height: 40vh;
   overflow: scroll;
}
#content {
   height: 2000px;
}

<div id='site'>
<div id='pane'>
  <div id='editor'>
  <div id='content-scroll'>
    <div id='content'>

    </div>
    </div>
  </div>
</div>
</div>

https://jsfiddle.net/16owL8x0/

like image 1
Joe Fitzsimmons Avatar answered Oct 20 '22 15:10

Joe Fitzsimmons