Search code examples
htmlcsscss-grid

CSS grid side column will not contain child item


I wish to have a pretty simple layout with a sidebar, and a main section.

I want the sidebar to adjust its width depending on the contents, but only up to a certain point so the main content is not shoved off the page, and if the width is restricted, I just want to ellipse the text. I am trying to do this by using fit-content(20%), but it just will not restrict the size of the sidebar.

I have an example of this at this plnkr where I have.

As can be seen, the side text will just not stay contained even with no width, let alone if I set a larger width.

enter image description here

How can I do this?

body {
  height: 50%;
  width: 50%;
  padding: 5px;
  border: purple solid 1px;
}

#container {
  height: 100%;
  width: 100%;
  overflow: hidden;
  display: grid;
  grid-template-columns: fit-content(20%) 1fr;
  border: red solid 1px;
  padding: 5px;
}

#sidebar {
  /* width: 700px; */
  border: green solid 1px;
}

#item {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
<html>

<head>
  <link rel="stylesheet" href="lib/style.css">
  <script src="lib/script.js"></script>
</head>

<body>
  <div id="container">
    <div id="sidebar">
      <div id="item">
        some long long long long long text text text here here here
      </div>
    </div>
    <div id="main">
      <div>Main content</div>
    </div>
  </div>
</body>

</html>


Solution

  • Add this to your code:

    * {
      box-sizing: border-box;
    }
    
    #sidebar {
      min-width: 0;
    }
    

    min-width: 0 is there to prevent something called "grid blowout", which makes #container ignore its given width and poke out of its container.

    Read more about that here.

    To apply our fix, we need to make sure that there is the column has a definite minimum width instead of auto.

    So we give the grid item a definite min_width, which is 0 in our case.

    Also box-sizing: border-box prevents #container poking out of body because of its parent's padding. It means the elements calculate its width by its border, including padding.

    * {
      box-sizing: border-box;
    }
    
    body {
      height: 50%;
      width: 50%;
      padding: 5px;
      border: purple solid 1px;
    }
    
    #container {
      height: 100%;
      width: 100%;
      overflow: hidden;
      display: grid;
      grid-template-columns: fit-content(20%) 1fr;
      border: red solid 1px;
      padding: 5px;
    }
    
    #sidebar {
      /* width: 700px; */
      min-width: 0;
      border: green solid 1px;
    }
    
    #item {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    <html>
    
    <head>
      <link rel="stylesheet" href="lib/style.css">
      <script src="lib/script.js"></script>
    </head>
    
    <body>
      <div id="container">
        <div id="sidebar">
          <div id="item">
            some long long long long long text text text here here here
          </div>
        </div>
    
        <div id="main">
          <div>Main content</div>
        </div>
    </body>
    
    </html>

    I hope this is what you want.