1

I would like to use css columns to arrange a list of items into three columns. When I click on certain items, I will use JS to expand them, and when that happens I don’t want the layout be adjusted to compensate. Is this possible?

$('.clickme').click(function(){
  $(this).toggleClass('big');
});
/* relevant CSS */
ul{
  display:block;
  max-width:640px;
  list-style:none;
  margin:0;
  padding:0;
}
.box1 ul{
  columns: 200px 3;
}
.box1 li{
  break-inside: avoid;
}
.box2 ul{
  width: 200px;
  float: left;
}
li{
  display:block;
  background-color:#555;
  color:white;
  border: 1px solid white;
  padding: 4px;
  min-height:1px;
}


/* less relevant CSS */
body{font-family: sans-serif;}
.clickme{
  transition: min-height .5s;
}
.clickme:hover{
  background-color:#999;
  cursor: pointer;
}
.clickme.big{
  min-height:100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="box1">
<h3>I don't want this - when an element expands the other elements rearrange themselves.</h3>
<ul>
 <li>item</li>
 <li>item</li>
 <li>some of these items are longer than others</li>
 <li>item</li>
 <li>some of these items are longer than others</li>
 <li>item</li>
 <li class="clickme">click me</li>
 <li>item</li>
 <li>item</li>
 <li>some of these items are longer than others</li>
 <li>item</li>
 <li>item</li>
</ul>
</div>

<div class="box2">
<h3>This is what I want - when an element expands the other elements stay put. I'm using multiple lists for this though, and I'd like to use just one list if possible.</h3>
<ul>
 <li>item</li>
 <li>item</li>
 <li>some of these items are longer than others</li>
 <li>item</li>
</ul>
<ul>
 <li>some of these items are longer than others</li>
 <li>item</li>
 <li class="clickme">click me</li>
 <li>item</li>
</ul>
<ul>
 <li>item</li>
 <li>some of these items are longer than others</li>
 <li>item</li>
 <li>item</li>
</ul>
</div>

Here's the CSS I'm using for the columns:

.box1 ul{
  columns: 200px 3;
}

Here's a codepen to illustrate - http://codepen.io/anon/pen/YNpJYG

Note: It’s obviously less ideal, but if it’s possible to have CSS columns create the columns based on the number of elements rather than their size, that could work for me.

TylerH
  • 20,799
  • 66
  • 75
  • 101
launchoverit
  • 4,807
  • 4
  • 20
  • 23
  • Unfortunately the only way to do what you want is with the multiple list as you have in the provided example. There is no way to set each column to have a certain number of elements on it. – Callum Jan 19 '17 at 17:45

1 Answers1

2

Unfortunately, CSS3 multi-column layout does not allow editing each column respectively and there is no way to manually edit their heights.

However, there are some properties that you can use to show the content of 'clickme' without disarranging other list elements. Use 'column-span' to span the element through all columns and 'column-gap' to remove the space between columns.

$('.clickme').click(function(){
  $(this).toggleClass('big');
});
/* relevant CSS */
ul{
  display:block;
  max-width:600px;
  list-style:none;
  margin:0;
  padding:0;
}
.box1 ul{
  -webkit-column-count: 3; 
  -moz-column-count: 3; 
  column-count: 3;
  -webkit-column-gap: 0px; 
  -moz-column-gap: 0px; 
  column-gap: 0px;
  -webkit-column-width: 100px; /* Chrome, Safari, Opera */
  -moz-column-width: 100px; /* Firefox */
  column-width: 100px;
}
.box1 li{
  break-inside: avoid;
}

li{
  display:block;
  background-color:#555;
  color:white;
  border: 1px solid white;
  padding: 4px;
  height: 18px;
}


/* less relevant CSS */
body{font-family: sans-serif;}
.clickme{
  transition: height .5s;
  text-align: center;
  -webkit-column-span: all; 
  column-span: all;
}
.clickme:hover{
  background-color:#999;
  cursor: pointer;
}
.clickme.big{
  height:100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box1">
<ul>
 <li>wut</li>
 <li>wut</li>
 <li>wut</li>
 <li>wut</li>
 <li>wut</li>
 <li>wut</li>
 <li class="clickme">click me</li>
 <li>wut</li>
 <li>wut</li>
 <li>wut</li>
  <li>wut</li>
 <li>wut</li>
 <li>wut</li>
</ul>
</div>
  • Thanks for the suggestion, unfortunately I don't think this will work for me since I do need all of the items to be in columns (rather than some spanning all rows). Also apologies for not specifying this before, but some items can be longer than others. I've updated the codepen to illustrate this. – launchoverit Jan 19 '17 at 19:30
  • What CSS3 multi-column layout does is that automatically rearranges the elements in a such way that the equal height is given to every column. Unfortunately, as I have mentioned, there is no property to edit columns' heights. The second solution you provided seems reasonable. Why doesn't it suit you? – Nedim Kurbegović Jan 19 '17 at 21:25
  • Mainly because it's a navigation menu, and it's bad for accessibility to have it broken up into multiple lists. Also we'd prefer to avoid using JS for basic layout like this. – launchoverit Jan 19 '17 at 23:46