CSS: floated elements give zero height on the containing element - css-float

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/

Related

Aligning Two-Column List Items

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>

Get children to line up centred or middle

JS Fiddle here
I am attempting to align child elements evenly between left and right. I tried using margin-left and right: auto but nothing happened.
Here is a screen shot of the navigation in question. I have added a border of 1 px around each element so you can see:
I'd like the nav line items to be centred in comparisson to their parent. So in the image the line items would move to the right a bit to be centred between the parent rectangle, which is an unordered list.
Here is my approximation of the relevant html:
<nav>
<div id="main-nav">
<ul id="menu-main">
<li>cats</li>
<li>dogs</li>
<li>sheep</li>
</ul>
</div>
</nav>
Currently relevant (I think) CSS is:
#main-navigation {
display: inline;
float: left;}
#main-navigation div {
display: block;}
#menu-main {
position: relative;
float: left;}
#menu-main li {
float: left;
}
Put another way, I'd like to centre floated child elements against the parent. If I zoom in and out with my browser I can see that the nav adjusts and change size with some line items moving between top and bottom row in order to fit.
But is there a way to ensure that, whatever the current size of the nav, the child line items will be centred?
Here's another picture, where I have manually added a margin left to #menu-main.
Now it looks more centred on my screen right now. But is there a way to auto centre it?
See this : http://jsfiddle.net/rahjrLny/1/
You don't need to float your li elements, simply set them to display:inline . Then you can add text-align: centre to your ul element, and all should be good.
(You'll need to remove some margins that have appeared in the fiddle due to the changes)
This would be my solution: JSFiddle
There's some redundant CSS (for example, no need to specify #main-navigation div {display: block;} if you don't have any div elements inside the #main-navigation).
I've gone with display:inline-block as opposed to display:inline (plus added some colour borders for visual clarity). Please bear in mind I'm working with the code you supplied in the question rather than building the code from the screenshots.
nav {display:inline-block; width:100%;}
#main-nav {
float:left;
width:100%;
}
ul#menu-main {
margin:0;
padding:0;
text-align:center;
width:100%;
float:left;
}
#menu-main li {
list-style: none;
padding: 0.5em;
display:inline-block;
}
EDIT: I answered this question before I observed there was a fiddle supplied, and worked instead from the code supplied in the question. This may not be the right answer for OP but I'm going to leave it alone for now as I believe it gives a valid example of how one could approach the task of centering a nav list.

how to expand width of child elements according to parent width

I've the following set of li in my DOM. But all them have only a min-width and the width is set to according to the elements inside each li.
Demo : link
parent css
#parent{
width:1024px;
height:90px;
background-color:black
}
what I want is to expand the li elements width to fit the entire width of the parent element. How can I achieve this using css3.
Thank you.
Use text-align: justify; on the #header element.
Then stretch the content to take up 100% width
FIDDLE
#header {
text-align: justify;
}
#header li {
display: inline-block;
}
#header:after {
content: '';
display: inline-block;
width: 100%;
}
One way is display: flex;: http://jsfiddle.net/kCRc3/18/
Another is display: table; http://jsfiddle.net/kCRc3/24/
display: table; may seem more concise, but there are several quirks such as alignment of cell contents that you need to be aware of.
If you set width: 100% to an element with display: block;, which is the case for any li element by default, then it will expand to the size of its parent.
In your example that would be the .header-tile.
Note that width is already introduced in CSS1 and there's no need for any CSS2 or CSS3 rule or setting.
To achieve it, you need to create new class-defining the remaining width i.e
(parent width - all li width = remaining width) and add it to any of <li class="header-tile newWidth">i.e
.newWidth{
width:100px; // this could be the remaining width
}
From your comments i guess that you want all list items in combination fill the width of their parent, not each single one of them (so that there's no remaining space in the ul).
One way of doing this is to set their display behavior to table, like in this fiddle: http://jsfiddle.net/SURzu/
If you don't have to fix the width of the ul, you could also set both ul and li tags to display: inline-block; to achieve this.
You can use css display: [table, table-row, table-cell] to expand elements in container.
Here is JSFiddle.
CSS:
#parent{
width: 1024px;
height: 90px;
background-color: black;
display: table;
}
#header {
display: table-row;
}
.header-tile {
display: table-cell;
}

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.

CSS stretch elements to fit container height

Demo - how to stretch li elements to parent container height, so they fit all in ul with appropriate height?
I need smth like that:
ul { display: table;}
li { display: table-row;}
Include one line inside the block of stylesheets for li
height: 25%;

Resources