I'm working on a menu that needs to be two columns. I've been able to accomplish this but one of the requirements for this menu is, if there is an uneven number of items in each column, the last one should be aligned to the right column.
This is fairly similar to this question I guess. My ul is floated to the right, my li are floated to the left. Floating the li to the right achieves my desired appearance but, as expected, the links are out of order.
Is there a way I could accomplish this without JS?
A combination of :nth-last-child() and :nth-child() should do the trick. Using the code below you select the last child only if it's odd and float it right.
li { width: 50%; display: inline-block; }
li:nth-last-child(1):nth-child(odd) { float: right; }
<ul>
<li>1</li><!--
--><li>2</li><!--
--><li>3</li><!--
--><li>4</li><!--
--><li>5</li><!--
--><li>6</li><!--
--><li>7</li><!--
--><li>8</li><!--
--><li>9</li>
</ul>
I would do the following, in order to avoid using floats :
li { width: 50%; display: inline-block; text-align: left; }
ul { text-align: right; }
<ul>
<li>1</li><!--
--><li>2</li><!--
--><li>3</li><!--
--><li>4</li><!--
--><li>5</li><!--
--><li>6</li><!--
--><li>7</li><!--
--><li>8</li><!--
--><li>9</li>
</ul>
Related
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.
I have a problem with aligment of two li elements inside a div because in the next example
HTML
<div id="menu-container">
<div class="menu-left">
<ul id="menu-principal" class="menu">
<li>Hola</li>
<li>Hola2</li>
</ul>
</div>
<!-- More code -->
</div>
The CSS code is in the next link and I use that html structure because that is what is generated by placing a menu in wordpress.
http://jsfiddle.net/Soldier/KhLhR/1/
I have a simple code with two li elements and I want to align horizontally with 50% of width for each but doesn't work.
Edit
Well.. All responses involve float: left, but did not want to use float: left because this causes overflow to ul and I have to use overflow: hidden .. I thought there was another factor that was failing but they all give +1 and accept the answer that answered first.
Thanks
Add:
float: Left;
to the css class of the li elements of the menu (in this rule):
".menu-left ul li {"
After the "width: 50%"
The float property specifies whether or not a box (an element) should float.
See http://www.w3schools.com/cssref/pr_class_float.asp
This is purely to do with the fact that your width specification is more than you've allowed for the child element in relation to it's parent elements:
.menu-left ul li {
display:inline-block;
vertical-align: top;
width: 50%; // should be less than 50%
}
Updated fiddle: http://jsfiddle.net/KhLhR/3/
http://jsfiddle.net/Soldier/KhLhR/1/
.menu-left ul li {
display:inline-block;
float:left;
vertical-align: top;
width: 50%;
}
Add a left float to your li elements:
.menu-left ul li {
display:inline-block;
vertical-align: top;
width: 50%;
float: left;
}
I am confused by the fact that applying float to li elements seems to mean that the containing ul element has no height. You can see the problem demonstrated in this jsFiddle.
Basically, I would like to create a ul with an arbitrary number of li elements. I would like each li element to have a width of 20%, so I end up with five li elements per line.
I would also like the ul element to have some height, so I can apply a bottom border.
If I use this class on the lis:
.result1 {
width: 20%;
float: left;
}
then the ul has a height of 0. I've seen posts recommending display: inline-block, but if I use this instead:
.result2 {
width: 20%;
display: inline-block;
}
then the ul has height, but there is whitespace between the lis so they break over two lines.
This must be something in the CSS spec that I'm failing to understand. How can I get five elements per line, with height on the containing element?
Add overflow: hidden; to the parent <ul class="results">
Fiddle
Floated elements cause the parent to collapse, you need to clear the parent element.
.results:after {
content: "";
display: table;
clear: both;
}
http://jsfiddle.net/CuCdr/1/
I'm trying to create a menu, in which the last menu item (with different class) will stick automatically to the right corner of the menu. I'm attaching a screenshot for this. There are a few menu items on the left and the last item should somehow count the rest of the available space on the right in the menu div, add this space as padding to the right and display a background in whole area ON HOVER (see the screen to understand this please)
Is something like this possible?
Thanks a lot
See if this will work for you: http://jsfiddle.net/neSxe/2
It relies on the fact that non-floated elements get pushed out of the way of floated elements, so by simply not floating it the last element fill up the rest of the space.
HTML
<ul id="menu">
<li>Services</li>
<li>Doctors</li>
<li>Hospitals</li>
<li>Roasted Chicken</li>
<li class="last">Customer Service</li>
</ul>
CSS
#menu {
width: 600px;
}
#menu li {
float: left;
}
#menu li a {
display: block;
padding: 6px 14px 7px;
color: #fefefe;
background-color: #333;
float: left;
}
#menu li a:hover {
background-color: #666;
}
#menu li.last {
float: none;
}
#menu li.last a {
text-align: center;
float: none;
}
Edit
I've made some changes to make it work smoother on IE6, by floating the anchors too.
If anybody else needs this and do not need to support IE6 and below, you can get rid of those two properties.
assuming your html looks like this:
<div id="menu">
<div class="entry">Services</div>
...
<div class="entry last">Support Staff</div>
</div>
I would make the #menu position: relative;, so that you can position the last menu entry absolute inside the #menu div.
Not necessarily putting the menu item last, but if you always wanted that rounded corner at the end then you could apply a background image to the ul itself and position that right top with the curve. The only issue you'd run into with this method is, if you hover over the last menu it will not put a hover right to the right-hand edge.
If you knew how many menu items there were you could achieve this by setting the correct widths for all your menu items?
Have a look at this:
http://jsfiddle.net/ExLdQ/
The trick is to use your lighter green as the background or background-image for the whole list. You can than use the darker green on all li's and add a background-color:transparent to li.last.
Just add float: right; to your css for the last menu item, and use light background for both the list itself and the last menu item.
I have a navigation with the following html code:
<ul id="nav">
<li><a>home</a></li>
<li><a>login</a></li>
<li class="selected"><a>shop</a></li>
<li><a>help</a></li>
</ul>
What I want to accomplish is that the element with the "selected" class always appears at the left side of the navigation.
So if shop is selected the rendered navigation would look like:
shop home login help
If help is selected:
help home login shop
My css:
#nav li {
display: inline; }
#nav li.selected {
width: 230px;
text-align: center;
background: #b52830;
margin-right: 10px;
float: left;
display: block; }
#nav li.selected a {
display: block;
padding-right: 0; }
#nav li.selected a:hover {
color: #fff; }
It works for certain browser but not for all. Any ideas?
If it does not work the selected element moves beneath the rest...
shop selected:
home login help
shop
Another alternative would be to use a programming language (like php or javascript) to print the list of links in order with class "selected" at the top of the list.
Floating left will put the first ordered li furthest to the left on the same line as the other li elements. Inversely, floating right will put the first ordered li furthest to the right.
How are you applying class "selected" to the appropriate li?
If ul#nav always have fixed width you could tell .selected to float left and all other elements to float right.
I would try to avoid to combine inline and block display like this. It would be helpful if you write how does look like if it not works.