How can I break <li> elements vertically - css

I have a list of <li> elements where the <ul> has a fixed size of 150px (height) and 400px (width)
How are you today
How I would like to stay:
NOTE: This list is dynamic!
Thank you all for your help

You can't.
LIs go vertically or horizontally, they do not wrap to new coloumns.
If you want lists as illustrated you need to use multiple ULs and float them.
If your LIs in on big long list, you can write some JavaScript that will break them down into multiple ULs. CSS cannot do this by itself.

Maybe an answer to an old post. But if you want your list items to be dynamic and in 4 columns, you could use this in the CSS.
div {
-webkit-columns: 100px 4; /* Chrome, Safari, Opera */
-moz-columns: 100px 4; /* Firefox */
columns: 100px 4;
}
Wrap a div around the <ul> and than use this css.
Working DEMO

You need to use multiple containers and distribute the elements between them. CSS doesn't currently support columnar layouts such as what you're trying.
Anyway, if the content is generated server-side, you can separate into columns there. Otherwise you can do it client-side with JavaScript. If you don't mind jQuery, something like Masonry can do all the heavy lifting.

sorry to disappoint but you'll need to break the list into three,
<ul>
<li></li>
...
</ul>
<ul>
<li></li>
...
</ul>
<ul>
<li></li>
...
</ul>
set a width for the ul elements and let them float
ul {
display: block;
width: 200px;
float: left;
}
a following element should have clear: left;

you may use the css display property.
ul li {
display: inline-block;
}

You could simply float them...
li { float: left; width: 200px; }
DEMO
or use inline-block....
li { display: inline-block; width: 200px; }
Demo
These do result in list items being displayed horizontally rather than vertically.
If you want list items to remain listed vertically, then you need to use mutiple containers (ul) for each list.

When you think about your problem a bit creative then there is a relative easy solution.
You must just decide how much li's you have at max in one column. When you get your data dynamically, then you can directly create the ul's dynamically.
It can be achieved on server side and also on client side without a problem.

Since you know the dimensions in pixels of the UL and LI elements, you can position the LIs easily, at least theoretically. For example:
<!DOCTYPE html>
<html>
<head>
<title>example<title>
<style type="text/css">
ul { border : 2px solid blue ; height : 200px }
li { height : 25px; }
li:nth-child(9),
li:nth-child(17),
li:nth-child(25),
li:nth-child(33) {
margin-top : -200px
}
li:nth-child(8) ~ li { margin-left : 150px }
li:nth-child(16) ~ li { margin-left : 300px }
li:nth-child(24) ~ li { margin-left : 450px }
li:nth-child(32) ~ li { margin-left : 600px }
</style>
</head>
<body>
<ul>
<li>LI number 1</li>
<li>LI number 2</li>
...
<li>LI number 36</li>
</ul>
</body>
</html>
The UL block will only be as high as the latest column, so you need to explicitly set its height.

Related

Is it possible to split a ul list li item in two equal parts when words overflow?

I have a list and what happens is this:
short item------------------------| (end of ul div)
short item
short item
really really really really long
item
is it possible to make the width of the li shrink to fit two lines or to make the li break exactly in two? like so:
really really really
really long item
so that it looks more even? or is that impossible with css?
EDIT:
It's a regular ul li list (generated by the site), single level. Nothing special. I just don't like the effect because they (the li's) have a different color than the div that contains the list, so each li has a box that fits it, and the really long item's box looks off when there's just one or two overflowing words.
I guess I'll have to find a way to do it with jquery or something. Setting a width or a max-width doesn't help, there already is one and even longer items would create an unnecesary number of lines.
I would try putting a width on the UL so it contains the Li
here is a tool to let you play with css i tried it here and seems to narrow down all the li's
http://www.w3schools.com/css/tryit.asp?filename=trycss_navbar_horizontal_float
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
width: 100px;
}
li {
float: right;
}
a {
display: block;
width: 60px;
background-color: #dddddd;
}
</style>
I don't think that breaking li into 2 equal parts is possible with only css, but you can set max-width property to li it will limit the width of your list.
html:
<ul>
<li>short item</li>
<li>short item</li>
<li>short item</li>
<li>really really really really long item</li>
</ul>
css:
li {
max-width: 150px;
}
demo: http://jsfiddle.net/557t6p0k/
Try adding a width=10% your <ul> tag like <ul="10%"><ul/ul> and play around with the number a little bit

Learning Div placement

Did a lot of research on all the separate components. However, I don't understand how the components work together. Several placement issues have plagued me on different occasions. I would like to understand why it behaves like it does.
Designing a site with a fixed header, containing some buttons. I want the buttons to be placed on a colored row (NAV). That's why I made a child of NAV. However I can't seem to place the buttons over the bar.
Html
<body>
<nav class="row">
<ul class="menu">
<li id="link1">Link 1</li>
<li id="link2">Link 2</li>
<li id="link3">Link 3</li>
<li id="link4">Link 4</li>
<li id="link5">Link 5</li>
</ul>
</nav>
<div class="row main">
#RenderBody()
</div>
CSS
nav, div, li {
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
border: 1px dashed black;
}
.row {
width: 100%;
padding-left: 20px;
padding-right: 20px;
}
nav {
position: fixed;
top: 80px;
height: 40px;
z-index: 100;
background-color: Green;
border-bottom: solid greenyellow 2px;
}
.menu li {
display: block;
background-color: darkgreen;
float: left;
height: 40px;
width: 60px;
}
.menu a {
color: white;
}
Result
It can be fixed by several things, like button margin or placing the buttons relative with a negative Top offset. However, these solutions feel 'dirty', like it's not the right way to do it. Why are the LI's not on top of NAV?
because your broswer applies by default some margin to the ul tag
try adding
ul {
margin: 0;
}
you could avoid these issues by using a css reset (Eric Meyer is the authority here: http://meyerweb.com/eric/tools/css/reset/) or Necolas' Normalize.css: http://necolas.github.io/normalize.css/
the first one zeroes all the values of all elements - you have to rebuild the style of some elements like lists.
The second one normalizes the values of elements to fix browsers inconsistencies
When you use the "float" property on some elements (here the "LI"), the parent (here the "menu") ignore his floating children to calculate his height.
So you have to specify a valid height to your menu, or probably better, use "overflow:auto" on it to remember him his children.
So remove your
nav {
height:40px;
}
and add in your CSS :
.menu {
overflow:auto;
}
As in this fiddle : http://jsfiddle.net/bE3QH/
When using the element ul it sometimes creates whitespace on browsers. By making the margin 0px you are removing the whitespace decreasing the area used by element. hope this helps. The following code can be used...
ul {
margin:0px
}
You can use this instead of your code.
You will get ready made menu control on this website.
You can modify as you want & you will get your menu control available in a moment.
Here's the link.
http://cssmenumaker.com
http://tympanus.net/codrops/2010/07/16/slide-down-box-menu/
http://cssmenumaker.com/builder/1666948
Please check it out.
These are very useful and it will definitely save your time as well.
I hope this will resolve your issue.
Add this to your CSS:
ul{
margin:0;
padding:0;
}
This clears the default properties for ul elements
You would be better off if you didn't specify a width and a height for the list items, but rather displaying the anchor tags as blocks, and giving those a width and height.

css make inline-block elements span the whole width of container

OK so this is actually a little complicated.
I have a navigation list where the list items are set to inline-block. The number of items is the list is dynamic so may vary.
My aim is to have the list items span the whole width of the container. (e.g. if there were 4 list items each one would take up 25% of the container width [ignoring margin/padding etc])
There is the added complication that browsers seem to add a 4px margin to inline-block elements where there is whitespace between them (linebreak/space etc).
I have made a fiddle as a starting point which has 2 examples: the first is just the list items in inline-block mode which the 2nd justifies them accross the width.
Neither achieves what I want which is for the whole width to be taken up by the elements without them breaking onto another line.
http://jsfiddle.net/4K4cU/2/
edit: slightly separate but why in my 2nd example is there a space beneath the lis, dispite the fact I have set line-height and font-size to 0?
OK, despite many decent answers and my inital thinking that js/jquery was the only way to go there is in fact a good css-only solution: using table cells. Original suggestion by #Pumbaa80
.list {
margin:0;
padding: 0;
list-style-type: none;
display: table;
table-layout: fixed;
width:100%;
}
.list>li {
display: table-cell;
border:1px green solid;
padding:5px;
text-align: center;
}
.container {
border: 1px #777 solid;
}
<div class="container">
<ul class="list">
<li>text</li>
<li>text</li>
<li>some longer text</li>
<li>text</li>
</ul>
</div>
This is superior to other solutions as:
css-only
no 4px margin problem as with inline-block
no clearfix need for floated elements
maintains equally distributed width independent of li content
concise css
Fiddle here: http://jsfiddle.net/rQhfC/
It's now 2016 and I wanted to update this question with an answer using flexbox. Consult with CanIUse for browser-compatiblity.
/* Important styles */
ul {
display: flex;
}
li {
flex: 1 1 100%;
text-align: center;
}
/* Optional demo styles */
* {
margin: 0;
padding: 0;
}
ul {
margin-top: 2em;
justify-content: space-around;
list-style: none;
font-family: Verdana, sans-serif;
}
li {
padding: 1em 0;
align-items: center;
background-color: cornflowerblue;
color: #fff;
}
li:nth-child(even) {
background-color: #9980FA;
}
<ul>
<li>text</li>
<li>text</li>
<li>text</li>
<li>text</li>
</ul>
Pre-edit fiddle (now inlined in above snippet)
Here is one way of modifying your original concept.
The CSS is:
.list {
padding:0;
margin:0;
list-style-type:0;
overflow: hidden;
height: 42px;
}
.list li {
display: inline-block;
line-height: 40px;
padding: 0 5px;
border:1px green solid;
margin:0;
text-align:center;
}
On your parent container, .list, set a height to enclose the child elements.
In this case, I chose 40px and added 2px to account for the border.
Also, set overflow: hidden on .list to hide the 2nd line generated by the pseudo-element.
On the li elements, set line-height: 40px which will center the text vertically.
Since the height is fixed, the second line gets hidden and you can style your parent with a border and so on without extra white space breaking the design.
Demo: http://jsfiddle.net/audetwebdesign/WaRZT/
Not Foolproof...
In some cases, you may have more links than can fit on a single line. In that case, the items could force a second row to form and because of overflow hidden, you would not see them.
Evenly Spaced Border Boxes
If you want the border boxes to be evenly distributed, you need to set a width to the li elements.
If the content comes from a CMS, and you have some control over the coding, you can dynamically generate a class name to set the correct width using predefined CSS rules, for example:
.row-of-4 .list li { width: 24%; }
.row-of-5 .list li { width: 19%; }
.row-of-6 .list li { width: 16%; }
See: http://jsfiddle.net/audetwebdesign/WaRZT/3/
There are multiple fixes to this. The one I prefer is simply to remove the whitespace between the elements, simply because the font-size trick involves non-semantic CSS. And its a lot easier haha. Code because answer requires it:
<ul class="list">
<li>
text
</li><li>
text
</li><li>
text
</li><li>
text
</li>
</ul>
Updated jsFiddle, where the first list has items set to width:25%; and fits in the window on one line. If this isn't what you were going for, I must have misunderstood.
EDIT: for unknown number of list items
There is some CSS3 stuff for this, but to be cross-browser compatible back to IE8, you want a JS solution. Something like this should work:
var listItems = document.querySelectorAll('li');
listItems.style.width = listItems.parentNode.style.width / listItems.length;
SECOND EDIT: for jQuery instead of JS
Winging it, but:
var $listitems = $('.list').children();
$listitems.width($listitems.parent().width()/$listitems.length);
you can use the display:inline-block with li element,and use the text-align:justify with ul element. If you are interested ,please click here.

Why does my list's background-color disappear when I float its list elements?

The moment I float my unordered-list element...the background color fails. Why?
<style type="text/css">
.bkgrd-blue { background-color: #094AB2; }
.application-bar { color: #FFFFFF; }
.application-bar ul { }
.application-bar ul.control-bar { list-style: none outside none; margin: 0; overflow: visible; padding: 0; }
.application-bar ul.control-bar.branding { float: left;}
</style>
<div class="application-bar bkgrd-blue">
<ul class="control-bar">
<li>
This is working!
</li>
</ul>
</div>
<div class="application-bar bkgrd-blue">
<ul class="control-bar branding">
<li>
The moment I float this...it fails! Why?
</li>
</ul>
</div>
Floating an element removes it from the normal document flow so containers don't expand - that is, the containing div has 0 height.
To fix this you need to clear the float. You can either:
set overflow: hidden on the div
float the div
add an element after the floated list with clear:both - this could be done using the :after pseudo-element
Here's a demo using the first solution: http://jsfiddle.net/FSH4Y/
I added:
.application-bar {
color: #FFFFFF;
overflow: hidden;
}
Here's some more info on this issue: CSS Tricks: All About Floats - have a look at the section called The Great Collapse
You need to clear under the list, usually I add a div like
<div style='clear:both;'></div>
This will allow the floated element's parent to properly calculate it's height.
You need to float the containing div with the background in it as well. As soon as you float the inner ul, the containing div effectively has no content so ends up with a height of 0.

Resize unknown number of elements to fill width of parent container

I need to put an unknown number of divs (likely a limit of about 5) into a parent container and always make sure they remain equally divided. I'm not sure if this can be done with CSS alone but I figured I better ask. So if we know that 3 divs are used:
<style>
.menu-button {
float: left;
width: 33%;
}
</style>
<div>
<div class="menu-button">Button X</div>
<div class="menu-button">Button Y</div>
<div class="menu-button">Button Z</div>
</div>
Seems to work, but what if the number of .menu-button divs is unknown? Is there a better way to do it so it automatically adjusts horizontally?
To do that with any element, you have two solutions:
make the browser simulating the table behavior
using Flexible Box layout
For instance, to build an horizontal menu, with equal width of every li elements, with this HTML code :
<div id="menu">
<ul>
<li>First Element</li>
<li>Second Element</li>
<li>Third Element</li>
...
<li>N Element</li>
</ul>
</div>
Using the table layout, CSS code would look like that:
#menu{
width: 100%; /* for instance */
display: table;
table-layout: fixed;
}
#menu ul{
display: table-row;
}
#menu ul li{
display: table-cell;
}
Flexible Box layout is a more modern solution, and it's pretty widely supported nowadays:
#menu{
width: 100%; /* for instance */
}
#menu ul{
display: flex;
flex-flow: row;
}
#menu ul li{
flex-grow: 1;
}
Unfortunatly I think you'll have to use tables to do this. As <td>'s resize itslef to fit into the full width.
HTH
Try this solution (demo page).
Basically, you need to make the divs display:inline-block, and apply text-align:justify to them. Then force a line break. One drawback is there will always be some space between divs, i.e. no way to make their edges touch.

Resources