Search code examples
htmlcssoverflowcss-grid

CSS Grid with overflow on just one of the rows


I am not sure if it is possible with CSS Display Grid, but I would like to have one the rows from my grid to have a vertical overflow, while the other do not.

.container {
  box-sizing: border-box;
  height: 350px;
  max-width: 300px;
  border: 3px dotted gray;
  overflow: hidden;
  display: grid;
  grid-template-areas: 'item-a' 'item-b';
  grid-template-rows: 1fr 120px;
  grid-template-columns: 200px;
  background-color: grey;
  .item-a {
    grid-area: item-a;
    border: 3px dotted green;
    overflow-x: auto;
    overflow-y: hidden;
    width: 600px;
    background-color: green;
  }
  .item-b {
    grid-area: item-b;
    border: 3px dotted yellow;
    background-color: yellow;
  }
}
<div class="container">
  <div class="item-a">
    Grid child 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis consequat, tortor ut luctus semper, turpis dui consequat ipsum, vitae gravida nunc purus non arcu. Proin congue, turpis eget tempor tristique, turpis eros lobortis nibh, lobortis
    suscipit nisi mi ut dolor. Duis aliquam interdum ipsum. Aenean id metus quis quam mollis interdum. Curabitur vel lectus a quam mollis consequat. Sed auctor efficitur viverra. Aenean iaculis enim diam, eget sodales augue consequat volutpat. Praesent
    placerat mi diam, sed elementum lacus eleifend in. Nulla sit amet dolor at tortor aliquet semper. Integer et sodales elit, quis pulvinar felis. Suspendisse et sodales ipsum. Aenean sem quam, tempor a metus sed, malesuada aliquet sapien. Nullam aliquam
    magna at congue sollicitudin.
  </div>

  <div class="item-b">
    Grid Child 2
  </div>
</div>

The idea is to have a horizontal scroll on the bottom of the green box only. I can add the scroll to the container, but that would scroll the content of the yellow box as well, and I don't want that.

I can also change the structure of my HTML and CSS and use flex instead to achieve the result, but that would add some other implications on the actual solution I am creating.

Looking through Stackoverflow and Google, I was able to only find questions and solutions for vertical scrolling. I tried applying the same ideas of setting specific widths to stuff, but after different combinations I could not find one that yields the result I want.

The fiddle version can be found here: https://jsfiddle.net/esantiagovieira/dkv06zmw/


Solution

  • With your example, it would not work because elements have a default text-wrap value of wrap in them. So the texts in your div would wrap down. That's why there's no horizontal scroll bar in your green div element.

    To solve your issue you would need to add the CSS attribute text-wrap: nowrap to your .item-a class style.

    Additionally, your code already works if you have a block type element inside the item-a div that has a width larger than it. I think you can understand it better if an example is shown. So here's a modified example from your code:

    .container{
      box-sizing: border-box;
      height: 350px;
      max-width: 300px;
      border: 3px dotted gray;
      overflow: hidden;
      display: grid;
      grid-template-areas:
      'item-a'
      'item-b';
      grid-template-rows: 1fr 120px;
      grid-template-columns: 200px;
      background-color: grey;
      }
      .item-a{
        grid-area: item-a;
        border: 3px dotted green;
        overflow-x: auto;
        overflow-y: hidden;
        width: 600px;
        background-color: green;
      }
      .child-block-elem {
       background-color: pink;
       width: 1000px;
       display: block;
      }
      
      .item-b{
        grid-area: item-b;
        border: 3px dotted yellow;
        background-color: yellow;
      }
    <div class="container">
      <div class="item-a">
        Grid child 1:
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis consequat, tortor ut luctus semper, turpis dui consequat ipsum, vitae gravida nunc purus non arcu. Proin congue, turpis eget tempor tristique, turpis eros lobortis nibh, lobortis suscipit nisi mi ut dolor. Duis aliquam interdum ipsum. Aenean id metus quis quam mollis interdum. Curabitur vel lectus a quam mollis consequat. Sed auctor efficitur viverra. Aenean iaculis enim diam, eget sodales augue consequat volutpat. Praesent placerat mi diam, sed elementum lacus eleifend in. Nulla sit amet dolor at tortor aliquet semper. Integer et sodales elit, quis pulvinar felis. Suspendisse et sodales ipsum. Aenean sem quam, tempor a metus sed, malesuada aliquet sapien. Nullam aliquam magna at congue sollicitudin.
        <div class="child-block-elem">A child block element</div>
      </div>
    
      <div class="item-b">
        Grid Child 2
      </div>
    </div>

    In my example, I built upon your existing code by adding a new child block element within the green div, along with its corresponding styles. However, the remaining code is yours. This demonstrates that your existing code functions as intended; the only issue is the text content wrapping within the green div, and the absence of additional content that will make it expand beyond its parent's width.

    I hope this helps!