Jomo
Jomo

Reputation: 111

CSS have number of columns depending on size

I have a number of (short) strings. I want to have them displayed in 2 columns if and only if there is enough space to display the strings without line-breaks. Otherwise I want each string on a separate line (i.e. 1 column) and with line-breaks if still necessary. The width of the strings is dynamic as is the width of the div where all has to be displayed.

enter image description here

I tried different attempts (grid layout, columns, ) but could not find a way. In the end it is also important that the solution does not only work with the latest browsers.

Upvotes: 3

Views: 1007

Answers (1)

Alissa French
Alissa French

Reputation: 56

A stab in the dark as I'm not sure exactly what code you're working with.

If you don't mind the columns not changing simultaneously, you could set white-space: nowrap on the children.

A min-width could also be set on the children, but this would have to be a fixed value and might not be dynamic enough.

If you want all columns to change simultaneously, I would probably use a media query and breakpoint that work well for the longest potential string.

If string length varies too much you could use JS to set up a window resize listener and add a class to the parent once the width of the window or parent element is twice the length of the longest string or less. Much more work but more dynamic.

$(document).ready(function() {
  var widest = null;
  // width of the "widest" element - probably faster than calling .width()
  var widestWidth = 0;
  $('div.parent4 p').each(function() {
    if (widest == null) {
      widest = $(this);
      widestWidth = $(this).width();
    } else if ($(this).width() > widestWidth) {
      widest = $(this);
      widestWidth = $(this).width();
    }
  });

  $(window).on('resize', function() {
    if($('div.container').width() < widestWidth * 2) {
      $('div.parent4').addClass('single');
    } else {
      $('div.parent4').removeClass('single');
    }
  });
});
   
    /* Flex-box */
    .parent {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
    }
    .parent > * {
        white-space: nowrap;
    }
    
    /* Flex-box & white-space */
    .parent1 > * {
        min-width: 50%;
    }
      
    /* Flex-box & min-width */
    .parent2 > * {
        flex-basis: 50%;
        min-width: 162px; /*length of longest string*/
    }
    
    /* Flex-box & media query */
    .parent3 > * {
        flex-basis: 50%;
    }
    @media screen and (max-width: 400px) {
      .parent3 > * {
        flex-basis: 100%;
      }
    }

    /* Flex-box & JS */
    .parent4 > * {
        min-width: 50%;
    }
    .parent4 p {
        display: inline-block;
    }
    .parent4.single {
        display: block;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
      
      <div class="parent parent1">
        <p>CSS: Let children break separately</p>
        <p>When they get too long</p>
        <p>Using white-space</p>
        <p>To keep us on one line!</p>
      </div>
      
      <hr>

      <div class="parent parent2">
        <p>Use a min width to break</p>
        <p>Columns simultaneously</p>
        <p>From 2 columns to 1</p>
        <p>To keep us on one line!</p>
      </div>
      
      <hr>

      <div class="parent parent3">
        <p>Use a media query to break</p>
        <p>Columns simultaneously</p>
        <p>From 2 columns to 1</p>
        <p>To keep us on one line!</p>
      </div>
      
      <hr>

      <div class="parent parent4">
        <div><p>Use JS to detect length</p></div>
        <div><p>And add a class to adjust</p></div>
        <div><p>From 2 columns to 1</p></div>
        <div><p>To keep us on one line!</p></div>
      </div>
      
     </div>

Upvotes: 2

Related Questions