Floating Dynamic Multi-Line List Items into Two Columns
I have a dynamic list that I need to lineup nicely into 2 columns using CSS and I'm having a terrible time with it.
The markup similar to this:
<ul>
<li>A is for apples</li>
<li>B is for bananas which are yellow in color</li?
<li>C is for cupcakes</li>
....
</ul>
When I simply give the li's a width and float them to the left they are clearing funny and end up formatted similar to this:
A is for apples B is for bananas which
are yellow in color
C is for cupcakes D is for dirtbag
I need the formatting to get the 3rd li directly under the first li - no matter the height of any one of the list items like this:
A is for apples B is for bananas which
C is for cupcake are yellow in color
D is for dirtbag
Each li's text is being pulled from a database and I have no control over how long each is.
Clarification Update - The list may also come out of the database like so:
<ul>
<li>A is for apples that grow on trees</li>
<li>B is for boat</li>
<li>C is for cupcakes</li>
<li>D is for dishes - that sure don't wash themselves</li>
....
</ul>
Requiring the formatting:
A is for apples that B is for boat
grow on trees C is for cupcake
D is for dishes - E is.....
that sure don't wash
themselves
/clarification
My backup plan: The order is not particularly relevant so I have tried to split the list in half and print out the two columns in 2 separate <ul&g开发者_StackOverflow中文版t;
's that floats left with a defined width but with each <li>
having a variable height and the database returning between 2-15 items, using that method the bottom of the columns don't consistently look even. I'd just rather find a better option if possible :/
I´m afraid you're out of luck until IE has css3 multi-column support.
You could of course use it and use a javascript solution for IE (there are multi-column plugins for jQuery for example), but your backup plan seems an easier solution.
Is this what you were after?
http://jsfiddle.net/Mutant_Tractor/fe2as/
EDIT
JQuery approach:
$('li').each(function(e) {
$var = $(this).height();
if ($var > 25) {
$(this).addClass('second')
} else {
$(this).addClass('first')
}
});
You will need to tweak it to allow for instances where multiple lines appear one after each other...
If you are willing to work in some Javascript, I used the following code to solve this same problem for IE 9+ (that's all that was scoped, so I can't guarantee it will work in older IE versions).
Basically, it floats elements left or right (via CSS with the left
and right
classes) depending on which column is currently shorter.
Worth noting is that this code is declared within a View object, so that first this
references the wrapping element (in your case, the <ul>
).
alignContainers: function() {
var thisView = this,
numOfElements = 0;
thisView.$el.find("> div").removeClass("left right")
.each( function() {
if (this.offsetHeight != 0 && this.offsetWidth != 0) {
var leftHeight = 0,
rightHeight = 0;
thisView.$el.find(" > .left").each(function() {
leftHeight += this.offsetHeight;
});
thisView.$el.find(" > .right").each(function() {
rightHeight += this.offsetHeight;
});
if (numOfElements == 0) {
$(this).addClass("left").removeClass("right");
} else if (leftHeight < rightHeight) {
$(this).addClass("left").removeClass("right");
} else {
$(this).addClass("right").removeClass("left");
}
numOfElements++;
} else {
$(this).removeClass("left right")
}
});
}
You need to use a definition list.
<dl>
...
<dt>B</dt>
<dd>is for bananas which are yellow in color</dd>
</dl>
精彩评论