Display child elements in a single row unless they overflow, then display a single column

I think this is not possible without JavaScript (because you need it to detect overflow). With that being said, you could base your solution around flexbox as it allows you to switch between row / column layout via single CSS property on your container element. Other option might be to switch between inline-block / block display on the children for example, but you would have to do that for all of them - that's why flexbox is better here. Example might look like this:

const outer = document.querySelector('.outer')

if (outer.clientWidth < outer.scrollWidth) {
  outer.classList.add('direction-column');
} else {
  outer.classList.add('direction-row');
}
.outer {
  background-color: lightgrey;
  width: 500px;
  padding: 10px;
  display: flex;
  align-items: flex-start;
}

.inner {
  background-color: darkgrey;
  margin: 5px;
  flex: none;
}

.direction-row {
  flex-direction: row;
}

.direction-column {
  flex-direction: column;
}
<div class="outer">
  <div class="inner">Some text, blah</div>
  <div class="inner">Some text, blah blah</div>
  <div class="inner">Some text, blah blah blah</div>
  <div class="inner">Some text, blah blah blah blah</div>
  <div class="inner">Some text, blah blah blah blah blah</div>
  <div class="inner">Some text, blah blah blah blah blah blah</div>
</div>


I find this question interesting. One possible solution is using Media Query, but only if you know the exact width at which the .outer container will break the layout of your .inner classes. If the text won’t change dynamically, then you can easily calculate the width. In that case, you might use:

    .inner {
      display: inline-block;
    }

    @media only screen and (max-width: 877px) {
      .inner {
        display: block;
      }
    }

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      font-size: 14px;
      color: #222;
      font-family: monospace;
    }

    .outer {

      padding: 0 10px;
      width: fit-content;
    }

    .inner {
      width: auto;
      height: auto;
      margin: 10px 0;
      background-color: darkgrey;
    }
  <div class="outer">
    <p>
      <span class="inner">blah blah</span>
      <span class="inner">blah blah blah</span>
      <span class="inner">blah blah blah blah</span>
      <span class="inner">blah blah blah blah blah</span>
      <span class="inner">blah blah blah blah blah blah</span>
    </p>
  </div>

It is an unusual workaround but it is CSS only.

Tags:

Html

Css