CSS Tip: hide content in short containers
Tags: css, responsivity, webdev
Published: 2020-06-30 17:41:48

## The problem

I was recently asked: "Show the percentage on the progress bar, but *only if* it's at least 30 pixels tall." In other words, I was tasked to hide some content if the the container wasn't tall enough.

Now, the first thing that I thought was: "Shoot, it would be the perfect task for [element queries](https://tomhodgins.github.io/element-queries-spec/element-queries.html)..." But we're not going to get those anytime soon.

Alternatively, I could use a library like [this one](https://github.com/marcj/css-element-queries) or good ol' [eq.js](https://github.com/Snugug/eq.js), but I wondered if that could be achieved with just CSS.

I found out it could be done.

## The solution

I don't want to bore you, so here you go:

{% codepen https://codepen.io/MaxArt2501/pen/vYLewGP %}

## Why it works

This is basically the same principle of breaking lines of text: the container isn't wide enough, so the rest of the text goes on a new line.

![Text in a container that gets wrapped when the container isn't wide enough](https://dev-to-uploads.s3.amazonaws.com/i/bme7k15av26gv5ndgw7d.png)

But if we limit the height of the paragraph to just the first line (with something like `height: 1lh` - [what's `lh`?](https://dev.to/maxart2501/the-new-and-old-css-units-youve-never-heard-about-1mn1#-raw-lh-endraw-and-raw-rlh-endraw-)) and hide the overflown content, we can hide the content if the container isn't wide enough:

![Limiting the height of the container effectively hides the rest of the text from view](https://dev-to-uploads.s3.amazonaws.com/i/uqwdfmcupy1rf4lrnqks.png)

### Flexing the layout

But we're not dealing with just text. Fortunately, we can use the same logic in a flex container:

```html
<div>
  <span>Lorem</span>
  <span>ipsum</span>
</div>
```

```css
div {
  display: flex;
  flex-wrap: wrap;
}
```

So, if the second `<span>` can't fit the first line, it's placed in the row below.

### Shift the axis

We've talked about *width* so far, but the initial problem had a *height* costraint. That's where `flex-direction: column` comes into play: this way, if the second `<span>` can't fit the first *column*, it's moved *on the right*.

In the end, the second `<span>` contains the content we want to hide. We don't care about the first one, so it could also be empty. Even better, we can avoid using a `<span>` altogether and use a pseudo-element instead:

```css
div {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
div::before {
  content: '';
  width: 100%;
}
```

Note that we *need* that first, empty content, or else the content we want to hide would just sit on the top. And we also need to declare `width: 100%` because without any size on the *cross* axis it'd like the element isn't even there.

### Wrapping up

What happens when the height isn't enough, then? Our content is pushed outside of our container, as it's clear in this screenshot (I painted the pseudo-element yellow to highlight its role - but normally its height is zero):

![The content we want to hide is pushed on the right of the constrained container](https://dev-to-uploads.s3.amazonaws.com/i/0crqitbh4jhhwd6p0bqk.png)

Now all we have to do is to declare `overflow: hidden` and we're golden.

## Hidden ≠ not rendered

My final warning is that you should be aware that *hidden content* isn't the same as *not rendered* or *inert*. Which means that it's *not* the same as `display: none` or `<template>` elements. In a nutshell, images and other media still get downloaded.

## Conclusions

My good friend [Giacomo Zinetti](https://dev.to/gcmznt) has pushed this kind of tricks to another level to mimic media and element queries. For example:

{% codepen https://codepen.io/gcmznt/pen/yRKVNQ %}

The previous warning still applies, but it's impressive how we can go far without using expensive queries.

Have a nice CSS, folks! 👋