3

I've done a few things with css columns and I really like them, but today I stumbled into a problem for which I just won't find a solution:

I have a page with multiple lists. These lists have dynamic contents and open up in small popups. The old behaviour was, that the list contents have been shown in a single column (normal HTML <ul>). The new behaviour should be that they are displayed in up to 4 columns. So I have extended my CSS with ul { column-count: 4; }. This works pretty nice for lists with many entries.

Now to my problem: sometimes there are lists with less then 4 entries. If that's the case, the popups for the lists still span 4 columns, with only 2 columns filled. So the popup for the less-filled list is still as wide as a popup with a full-filled list. For example:

ul {
  background-color: lime;
  list-style: none;
  column-count: 4;
}
<ul>
<li>entry 1</li>
<li>entry 2</li>
<li>entry 3</li>
<li>entry 4</li>
<li>entry 5</li>
<li>entry 6</li>
<li>entry 7</li>
<li>entry 8</li>
<li>entry 9</li>
<li>entry 10</li>
<li>entry 11</li>
<li>entry 12</li>
</ul>

<ul>
<li>entry 1</li>
<li>entry 2</li>
</ul>

My question now is: How do I hide those empty columns? I want a popup with a less filled list (no. of entries < 4) to be less wide then a popup with a full-filled list. I'd like to find a CSS-only solution, as I didn't intend to count the entries and add extra classes to decrease the column-count.

The order in which the elements are displayed is important: top-down and then left-right.

I've tried using flexbox, but there I have to set a fixed width for the container, which just results in the popups being too wide as well.

Edit for clarification: Problem Screenshot The dotted line should be the right border for the second popup. The diagonal lines mark the empty space I need to be gone.

Edit further approaches: Another approach posted by user 'Gobbin' as answer, is to use flex. But as I mentioned, I'd have to set some fixed width. Here it is a max-width for the list itself, so that wrapping works and a fixed width for the list elements. I don't want to have either. Also this approach lists the items from left to right and then from top to bottom, which is also not what I need:

ul {
  list-style: none;
  display: inline-flex;
  flex-wrap: wrap;
  max-width: 16em;
  float: left;
  clear: both;
}

li {
  background-color: lime;
  width: 4em;
}
<ul>
<li>entry 1</li>
<li>entry 2</li>
<li>entry 3</li>
<li>entry 4</li>
<li>entry 5</li>
<li>entry 6</li>
<li>entry 7</li>
<li>entry 8</li>
<li>entry 9</li>
<li>entry 10</li>
<li>entry 11</li>
<li>entry 12</li>
</ul>

<ul>
<li>entry 1</li>
<li>entry 2</li>
</ul>
Akerus
  • 363
  • 2
  • 16
  • Highly suggest looking into CSS Grid and CSS Flexbox. They are, quite literally made for this sort of thing – TheCrzyMan Mar 02 '18 at 13:48
  • @TheCrzyMan isn't CSS grid pretty much fixed for column counts and overall widths? And I already mentioned, that with flexbox I have to set a fixed width for the container, so that the items will be in columns. – Akerus Mar 02 '18 at 13:52
  • Hmm.. Guess I need to read better. Also, why do you need to not display the empty columns? Can you just give the `li` elements the background color? – TheCrzyMan Mar 02 '18 at 14:02
  • @TheCrzyMan these lists are shown in popups, which can be distinguished from the normal background. The background-color in the code snippet here is for visualization only. – Akerus Mar 02 '18 at 14:04
  • Do you need to have the column count? can you just get rid of it? – TheCrzyMan Mar 02 '18 at 14:12
  • @TheCrzyMan When I use `column-width` I have to set a fixed width for the popups. Then again, when less then 4 entries, the popup is too wide. I've updated my question for clarification. – Akerus Mar 02 '18 at 14:15

2 Answers2

1

Maybe this is an option for you, although the columns are spread across the available width.

var maxColumns = 4;
$("ul").each(function() {
  var numColumns = $(this).find("li").length;
  $(this).css("column-count", numColumns);
  $(this).css("width", 25*numColumns + "%");
});
ul {
  background-color: lime;
  list-style: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>entry 1</li>
  <li>entry 2</li>
  <li>entry 3</li>
  <li>entry 4</li>
</ul>

<ul>
  <li>entry 1</li>
  <li>entry 2</li>
</ul>
Gerard
  • 15,418
  • 5
  • 30
  • 52
  • And the spreading of the content for the complete width is problematic. :/ – Akerus Mar 02 '18 at 14:50
  • Adjusted taking into account 4 columns is the maximum. – Gerard Mar 02 '18 at 14:56
  • This is getting an interesting approach. Unfortunately this is no pure CSS solution as requested. But I will look further into this if nothing else pops up! – Akerus Mar 02 '18 at 15:00
0

I think this is your desired layout. Edited my answer as the list items still had margins.

ul {
  list-style: none;
    display: inline-flex;
    float: left;
    clear: both;
}
li{
   background-color: lime;
   width: 100%;
   display: inline;
}
<ul>
<li>entry 1</li>
<li>entry 2</li>
<li>entry 3</li>
<li>entry 4</li>
</ul>

<ul>
<li>entry 1</li>
<li>entry 2</li>
</ul>
Gobbin
  • 530
  • 3
  • 17