CSS auto column-count when max-height is fixed - html

I wish to achieve a layout where an element (in my case a <ul>) expands to 2 (or more) columns when the height reaches a certain limit.
So for example, if the height is only enough for 3 items, and I have 5, the 4th and 5th item go to the second column, which is only created if needed.
I tried to do this by setting the max-height as suggested here with column-count and column-width set to auto via the columns (I tried setting them separately too, same behaviour).
If on the other hand I change the column-count to a fixed integer, it works and balances the items, but this is not dynamic as I need it. (If I have only 2 elements I don't want to create 2 columns for them).
Is there a way to have the height fixed, and the columns automatically added when the height is not enough to fit all the items?
ul#list {
font-family: sans-serif;
list-style: none;
background: #dddddd;
max-height: 200px;
columns: auto auto;
-webkit-columns: auto auto;
-moz-columns: auto auto;
/** This works, but fixes the columns to 2, which is not what I want.
columns: 2 auto;
-webkit-columns: 2 auto;
-moz-columns: 2 auto;
*/
column-gap: 10px;
-webkit-column-gap: 10px;
-moz-column-gap: 10px;
column-rule: 1px solid black;
-webkit-column-rule: 1px solid rgba(100, 30, 30, 0.4);
-moz-column-rule: 1px solid rgba(100, 30, 30, 0.4);
}
li {
height: 20px;
padding: 2px;
}
<div id="outer">
<ul id="list">
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
<li>Item #4</li>
<li>Item #5</li>
<li>Item #6</li>
<li>Item #7</li>
<li>Item #8</li>
<li>Item #9</li>
<li>Item #10</li>
<li>Item #11</li>
<li>Item #12</li>
</ul>
</div>

First of all, to make CSS Columns work you have to set column-width or column-count. CSS Columns won't work if you doesn't set any of it.
If I understand right, you need to use column-fill property. Unfortunately, only Firefox supports it now. Check out this code snippet (Firefox only).
ul#list {
font-family: sans-serif;
list-style: none;
background: #dddddd;
max-height: 200px;
/* Works only in Firefox! */
-moz-columns: 100px auto;
-moz-column-gap: 10px;
-moz-column-rule: 1px solid rgba(100, 30, 30, 0.4);
-moz-column-fill: auto;
}
li {
height: 20px;
padding: 2px;
}
<div id="outer">
<ul id="list">
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
<li>Item #4</li>
<li>Item #5</li>
<li>Item #6</li>
<li>Item #7</li>
<li>Item #8</li>
<li>Item #9</li>
<li>Item #10</li>
<li>Item #11</li>
<li>Item #12</li>
</ul>
</div>
I think, you could use flex in your case. See example:
ul#list {
font-family: sans-serif;
list-style: none;
background: #dddddd;
height: 200px;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: column wrap;
flex-flow: column wrap;
}
li {
height: 20px;
padding: 2px;
}
<div id="outer">
<ul id="list">
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
<li>Item #4</li>
<li>Item #5</li>
<li>Item #6</li>
<li>Item #7</li>
<li>Item #8</li>
<li>Item #9</li>
<li>Item #10</li>
<li>Item #11</li>
<li>Item #12</li>
</ul>
</div>

Related

Stack DIVs in multiple columns following the order they are typed [duplicate]

This question already has an answer here:
Break unordered list items across columns with flexbox
(1 answer)
Closed 4 years ago.
I try to make 2 column list and vertical order using flexbox
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
see image for the example
Here's a simple wrapping column layout in flexbox.
Each li element takes up 6em height (5em height + .5em margin * 2), so we set the parent container to 30em height to fit five elements.
ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
list-style: none;
margin: 0;
padding: 0;
height: 30em;
}
li {
background: gray;
width: 5em;
height: 5em;
margin: .5em;
}
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
The HTML is straight-forward:
<div class="items">
<div class="item">Heriberto Nickel</div>
<div class="item">Brittaney Haliburton</div>
<div class="item">Maritza Winkler</div>
<div class="item">Carmon Rigg</div>
<div class="item">Alice Marmon</div>
<div class="item">Lyman Steakley</div>
<div class="item">Zenia Correa</div>
</div>
<div class="items">
<div class="item">Heriberto Nickel</div>
<div class="item">Brittaney Haliburton</div>
<div class="item">Maritza Winkler</div>
<div class="item">Carmon Rigg</div>
<div class="item">Alice Marmon</div>
<div class="item">Lyman Steakley</div>
<div class="item">Zenia Correa</div>
</div>
Using floats, the CSS for this would be:
.items {
overflow: hidden; /* simple clearfix */
}
.items .item {
float: left;
width: 25%;
}
.items {
overflow: hidden; /* simple clearfix */
}
.items .item {
float: left;
width: 25%;
}
This gives us four columns that wrap. We can also add a little bit of style to give it a more pleasing look:
.items .item {
float: left;
width: 25%;
box-sizing: border-box;
background: #e0ddd5;
color: #171e42;
padding: 10px;
}
.items .item {
float: left;
width: 25%;
box-sizing: border-box;
background: #e0ddd5;
color: #171e42;
padding: 10px;
}
Hope this helps.
.list-one {
display: inline-block;
float: left;
list-style-type: none;
}
.list-two {
display: inline-block;
float: left;
list-style-type: none;
}
li {
margin-top: 10px;
}
.line-item {
background-color: grey;
height: 50px;
display: block;
color: #fff;
width: 50px;
padding: 30px 20px 0px 20px;
text-align: center
}
<ul class="list-one">
<li><span class="line-item">1</span></li>
<li><span class="line-item">2</span></li>
<li><span class="line-item">3</span></li>
<li><span class="line-item">4</span></li>
<li><span class="line-item">5</span></li>
</ul>
<ul class="list-two">
<li><span class="line-item">6</span></li>
<li><span class="line-item">7</span></li>
<li><span class="line-item">8</span></li>
<li><span class="line-item">9</span></li>
<li><span class="line-item">10</span></li>
</ul>

Menu item is overlaped when use flex in IE11

This is my code jsfiddle
My problem is that the item is overlapped when the width of the window changes to the size that it does not overflow.
When i use chrome
screenshot for chrome
When i use ie
screenshot for ie
<html>
<head>
<style>
ul {
overflow: scroll;
display: flex;
}
li {
flex: 1;
flex-basis: 0px;
padding: 15px;
white-space: nowrap;
list-style: none;
border: 1px solid;
}
</style>
</head>
<body>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item ABCDEF</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
</ul>
</body>
</html>
You can use overflow:hidden, text-overflow: ellipsis , if the text is overflow then it will hide the content and added "..." in the li block.
You could set the min-width property for the container and flex item, then, it will display the item with scrolls. Also, as Pavan Kumar said, you could hide the overflowed text using ellipsis.
Code as below:
<style>
ul {
overflow-x: auto;
display: flex;
min-width:1000px;
list-style-position: inside;
}
li {
flex: 1;
flex-basis: 0px;
padding: 15px;
white-space: nowrap;
list-style: none;
border: 1px solid;
min-width: 50px;
-ms-flex: 1;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
</style>
the result like this.

How to make vertical list 2 column using flexbox [duplicate]

This question already has an answer here:
Break unordered list items across columns with flexbox
(1 answer)
Closed 4 years ago.
I try to make 2 column list and vertical order using flexbox
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
see image for the example
Here's a simple wrapping column layout in flexbox.
Each li element takes up 6em height (5em height + .5em margin * 2), so we set the parent container to 30em height to fit five elements.
ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
list-style: none;
margin: 0;
padding: 0;
height: 30em;
}
li {
background: gray;
width: 5em;
height: 5em;
margin: .5em;
}
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
The HTML is straight-forward:
<div class="items">
<div class="item">Heriberto Nickel</div>
<div class="item">Brittaney Haliburton</div>
<div class="item">Maritza Winkler</div>
<div class="item">Carmon Rigg</div>
<div class="item">Alice Marmon</div>
<div class="item">Lyman Steakley</div>
<div class="item">Zenia Correa</div>
</div>
<div class="items">
<div class="item">Heriberto Nickel</div>
<div class="item">Brittaney Haliburton</div>
<div class="item">Maritza Winkler</div>
<div class="item">Carmon Rigg</div>
<div class="item">Alice Marmon</div>
<div class="item">Lyman Steakley</div>
<div class="item">Zenia Correa</div>
</div>
Using floats, the CSS for this would be:
.items {
overflow: hidden; /* simple clearfix */
}
.items .item {
float: left;
width: 25%;
}
.items {
overflow: hidden; /* simple clearfix */
}
.items .item {
float: left;
width: 25%;
}
This gives us four columns that wrap. We can also add a little bit of style to give it a more pleasing look:
.items .item {
float: left;
width: 25%;
box-sizing: border-box;
background: #e0ddd5;
color: #171e42;
padding: 10px;
}
.items .item {
float: left;
width: 25%;
box-sizing: border-box;
background: #e0ddd5;
color: #171e42;
padding: 10px;
}
Hope this helps.
.list-one {
display: inline-block;
float: left;
list-style-type: none;
}
.list-two {
display: inline-block;
float: left;
list-style-type: none;
}
li {
margin-top: 10px;
}
.line-item {
background-color: grey;
height: 50px;
display: block;
color: #fff;
width: 50px;
padding: 30px 20px 0px 20px;
text-align: center
}
<ul class="list-one">
<li><span class="line-item">1</span></li>
<li><span class="line-item">2</span></li>
<li><span class="line-item">3</span></li>
<li><span class="line-item">4</span></li>
<li><span class="line-item">5</span></li>
</ul>
<ul class="list-two">
<li><span class="line-item">6</span></li>
<li><span class="line-item">7</span></li>
<li><span class="line-item">8</span></li>
<li><span class="line-item">9</span></li>
<li><span class="line-item">10</span></li>
</ul>

Fieldset child with height 100% is too big

I am trying to stretch a fieldset child to 100%, but the child (ul) is too big and some overflow appears (is cut in my case).
How can I stretch the fieldset child to 100%, but without overflow?
fieldset {
height: 300px;
overflow: hidden;
}
ul {
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-around;
background-color: #ffffbb;
}
<fieldset>
<legend>How to stretch child</legend>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
</ul>
</fieldset>
Just in case here is also external fiddle: Example in Fiddle.
Edited:
Setting height to specific pixel is necessary. I get form layout (design) through WebSocket from C# windows application. Every component is position absolute with exact same properties as in C# application. That means, left, top, width and height.
Solution
Add this to your code:
ul { margin: 0; }
fieldset {
height: 300px;
overflow: hidden;
}
ul {
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-around;
background-color: #ffffcc;
margin: 0;
}
<fieldset>
<legend>How to stretch child</legend>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
</ul>
</fieldset>
Explanation
The ul has default top and bottom margins added by the browser's style sheet.
These margins, when added to height: 100%, cause the overflow.
But even when the overflow issue is fixed, item #8 is packed tightly to the container's bottom edge:
This is because the line-height of the legend also creates height (demo with line-height: 0)
Here are two ways you can handle this:
Define a height for the legend and then adjust the height of the ul. Something like this:
legend {
height: 15px;
}
ul {
height: calc(100% - 15px);
}
demo
Reduce the height of the ul, like this:
ul { height: 95%; }
demo
Use Auto Height for your fields and add Height, Line-height for your li.
Its work clear and nicely.
EDIT: And of course you need to remove the Overflow: hidden; property;
fieldset {
height: auto;
}
ul {
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-around;
background-color: #ffffbb;
}
li {
height: 40px;
line-height: 40px;
}
<fieldset>
<legend>How to stretch child</legend>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
</ul>
</fieldset>
Flexbox doesn't work in <fieldset> source.
You can use a <div> instead codepen.
HTML
<div class='fieldset'>
<legend>aHow to stretch child</legend>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
</ul>
</div>
CSS
.fieldset {
min-height: 300px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
ul {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-around;
background-color: #ffffbb;
}
legend {
margin-right: auto;
margin-left: 12px;
margin-top: -10px;
background: #FFF;
}

Display 2 dropdown lists next to each other

I have 2 drop down ol next to each other, but when the first one is clicked, it brings the second one down with it instead of leaving it at the top.
I can't use position: absolute with either of them as there will be content at the bottom that needs to be pushed down when the drop down is active.
This is the code I have
HTML
<div id="lists">
<div id="list_one">
<a>List One</a>
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ol>
</div>
<div id="list_two">
<a>List Two</a>
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ol>
</div>
</div>
CSS
#lists {
border: 2px solid blue;
position: relative;
width: 300px;
}
#list_one {
width: 100px;
border: 2px solid red;
}
#list_one ol {
display: none;
}
#list_two {
width: 100px;
border: 2px solid green;
position: relative;
top: -25px;
left: 200px;
}
#list_two ol {
display: none;
}
jQuery
$('#list_one a').click(function(){
$('#list_one ol').toggle();
});
$('#list_two a').click(function(){
$('#list_two ol').toggle();
});
jsfiddle: https://jsfiddle.net/e3tctuzp/
Float the two lists left and right within the container, and then set the display of the container to inline-block.
So the CSS for the lists would be:
#lists {
border: 2px solid blue;
position: relative;
width: 300px;
display:inline-block
}
#list_one {
width: 100px;
border: 2px solid red;
float:left;
}
#list_two {
width: 100px;
border: 2px solid green;
position: relative;
float:right;
}
See jsfiddle
Instead of setting the list positions as relative, you could make them float. For that to work you need to set overflow: auto in your #lists, though. You can then float list one to the left and list two to the right. It would look something like this:
#list_one {
...
float: left;
}
#list_two {
...
float: right;
}
#lists {
overflow: auto;
}
Here is your edited fiddle: https://jsfiddle.net/e3tctuzp/2/