Gajus
Gajus

Reputation: 73808

How can I completely hide elements that overflow their container vertically?

I have a fixed width and height container that consists of arbitrary height elements that need to be stacked vertically. How can I hide any elements that do not fit? overflow: hidden could still show the part of an element that doesn’t overflow.

.container {
  border: 1px solid #eee;
  height: 200px;
  overflow: hidden;
}

.box {
  background-color: #ccc;
  line-height: 54px;
  margin: 20px;
  text-align: center;
  width: 60px;
}

.incorrect {
  background-color: #fa9;
}
<div class="container">
  <div class="box">show</div>
  <div class="box">show</div>
  <div class="box incorrect">hide</div>
</div>

Upvotes: 31

Views: 29943

Answers (3)

djvg
djvg

Reputation: 14255

The OP`s answer is beautiful, but the first item will still be clipped, instead of hidden, if it does not fit.

If you want the first item to become hidden as well, you can use a spacer with the relevant dimension set to zero.

Here's the idea, applied to a row, just for some variation:

(note the .container can be resized for some live action)

.container {
  /* functional */
  height: 1em;
  display: flex;
  flex-flow: row wrap;
  overflow: hidden;
  /* cosmetic & convenience */
  background-color: plum;
  width: 10em;
  resize: horizontal;
}

.container div {
  /* functional */
  height: 100%;
}

.container div:first-child {
  /* functional */
  width: 0;
}
<div class='container'>
  <div>
    <!-- zero-width spacer -->
  </div>
  <div>first</div>
  <div>second</div>
  <div>third</div>
</div>

Upvotes: 5

Abhitalks
Abhitalks

Reputation: 28387

An easy way of doing this would be to use CSS columns instead of flex.

Just use a column-width equal to the width of the container. Apply break-inside: avoid on child divs. And there you go.

It resolves all of the asks:

[..]have a fixed width and height container that consists of arbitrary height elements that need to be stacked vertically. How can I hide any elements that do not fit?

You can notice that the red div (the last one) is hidden completely.

Example Snippet:

* { box-sizing: border-box; margin: 0; padding: 0; }
.container {
  border: 1px solid #999;
  height: 200px; width: 300px; 
  overflow: hidden;
  column-width: 300px; 
}
.box {
  padding: 8px; text-align: center; color: #fff;
  width: 250px; height: 80px;
  break-inside: avoid
}
.box:nth-child(1) { background: #3b3; }
.box:nth-child(2) { background: #33b; width: 200px; height: 75px; }
.box:nth-child(3) { background: #b33; }
<div class="container">
  <div class="box">show</div>
  <div class="box">show</div>
  <div class="box">hide</div>
</div>

Note: As of now, Firefox is still a problem area with CSS columns. The break-inside, although documented on MDN, is buggy in Firefox. The bug is still open: https://bugzilla.mozilla.org/show_bug.cgi?id=549114.

Upvotes: 5

Gajus
Gajus

Reputation: 73808

Assuming that your child elements have the same width as the container, this can be achieved by leveraging the containing box created from the flex property.

The trick is to use flex-flow: column wrap; in conjunction with overflow: hidden; on the container. The former dictates that the content is stacked vertically and that anything that does not fit should be wrapped into a second column, outside of the content box of the container. The latter dictates that this second column (and any subsequent columns) should be hidden.

.container {
  width: 300px;
  height: 200px;
  display: flex;
  flex-flow: column wrap;
  overflow: hidden;
}

.box {
  width: 300px;
  height: 75px;
}

.box:nth-child(1) {
  background: red;
}
.box:nth-child(2) {
  background: green;
}
.box:nth-child(3) {
  background: blue;
}
<div class='container'>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

Upvotes: 42

Related Questions