CSS Grid hide elements that don't fit

Viewed 514

I'm trying to create a pure CSS responsive navigation. This means no media queries, no pixel values and no JS.

The first challenge is to hide the navigation if there's not enough horizontal space. I was able to accomplish this, but at the expense of giving it a pixel value.

.wrapper {
  background: rgba(0, 255, 0, 0.1);
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min-content, 250px));
  justify-content: space-between;
  grid-template-rows: auto;
  grid-auto-rows: 0;
  /* Automatically created rows will have a height of 0. */
  overflow: hidden;
  border: 1px solid red;
}

.logo {
  background: rgba(255, 0, 0, 0.1);
}

.another-element {
  background: rgba(0, 0, 255, 0.1);
  display: flex;
  gap: 10px;
  flex-wrap: nowrap;
  overflow: hidden;
}

a {
  white-space: nowrap;
  background: orange;
}
<div class="wrapper">
  <div class="logo">Logo</div>
  <div class="another-element">
    <a>Link 1</a>
    <a>Link 2</a>
    <a>Link 3</a>
    <a>Link 4</a>
  </div>
</div>

I've studied the repeat() function. A few notes:

  • Auto rows can only be created by using the repeat() function with auto-fill or auto-fit.
  • Auto rows can be collapsed with grid-auto-rows: 0; thus hiding the elements that do not fit the first line.
  • When using repeat() with auto-fit as the first argument, one can use minmax() as the second. The minmax() function allows us to set a minimum and maximum values for the columns, but it requires a pair of length/percentage and min-content, max-content or auto, but does not accept min-content for both arguments: minmax(min-content, min-content) doesn't seem to be valid CSS.

So everything works as expected, except the fact that the wrapping happens at a fixed 250px*2 value instead of when there's not enough space for both items. Any idea how to make the wrap only happen when there's not enough space?

Here's a codepen.

1 Answers

Having played around with this for ages, I can’t improve on your grid solution.

I think what I will do in my project is to use a flexbox with a fixed height container/wrapper. This may or may not suit your use case.

.container {
  border: 1px solid black;
  height: 2em;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  flex-wrap: wrap;
  column-gap: 1em;
  overflow: hidden;
}
.box {
  box-sizing: border-box;
  height: 100%;
  background: cyan;
  padding-left: 5px;
}
<div class="container">
  <div class="box">the quick</div>
  <div class="box">the quick brown</div>
  <div class="box">the quick brown fox</div>
  <div class="box">the quick brown fox jumps</div>
  <div class="box">the quick brown fox jumps over</div>
  <div class="box">the quick brown fox jumps over the lazy dog</div>
</div>

Related