Breaking ul li tree in 2 column - html

I am having a strict two levels ul li structure. I want to display it in 2 columns as the tree is very long and want to occupy the right portion for better user friendliness. So far I have achieved this using css3 property column-count. I am getting the expected result but the problem is it is breaking a subtree which I am unable to prevent. Is there a css property which will work in combination with column-count or independently and allow me to split my tree in 2 column without breaking a sub-tree.
HTML:
<div id="parent">
<ul>
<li>asd
<ul>
<li>lmn</li>
...
</ul>
</li>
<li>xyz
<ul>
<li>pqr</li>
...
</ul>
</li>
...
</ul>
</div>
CSS:
#parent {
column-count:2;
-moz-column-count:2;
-webkit-column-count:2
}
So far my jsfiddle looks like: http://jsfiddle.net/7WwK7/1/

change value display of <li> from default list-item to inline-block + width:99%;, and <li>s won't break anymore through columns.
if you still want the bullet , use a pseudo element to fake it.
http://jsfiddle.net/7WwK7/6/

Related

Targeting every other nested list with CSS

Suppose you have the following HTML nested lists:
<ul>
<li>
List 1
<ul>
<li>
List 2
<ul>
<li>
List 3
<ul>
<li>
List 4
</li>
</ul>
</li>
</ul>
</li>
</ul>
So a nested list 4 deep. I would like to style every other one. I know I could do something like this:
ul,
ul ul ul {
color:red;
}
ul ul,
ul ul ul ul {
color:blue;
}
But that would obviously only work 4 levels deep, so if they added a 5th level, it wouldn't work properly. Is there a way in CSS to automatically target every other nested list like this?
This is straight from w3schools:
p:nth-child(odd)
{
background:#ff0000;
}
p:nth-child(even)
{
background:#0000ff;
}
"The :nth-child() selector is supported in all major browsers, except IE8 and earlier."
So at a GIVEN DEPTH, you can use this to style every other nested list element. But if you need something that also takes into account the varying depths, you may need a javascript based solution which then applies these CSS3 rules.
There is also support for simple formulas in this selector but I can't say for sure how well they work since I haven't tried them, but here's the sample in case it helps you:
p:nth-child(3n+0)
{
background:#ff0000;
}
"Using a formula (an + b). Description: a represents a cycle size, n is a counter (starts at 0), and b is an offset value."
Here the w3schools page for reference which describes how to use that formula: http://www.w3schools.com/cssref/sel_nth-child.asp

Two level menu, setting text-decoration property

Ok, this sounds kind of silly and I don't know if this is some kind of bug in css or what, but when I try to create two level menu where items on the first level have text-decoration property set to underline, I couldn't find a way to set text-decoration to none on the items on the second level.
<ul>
<li style="text-decoration:underline;">item1
<ul>
<li style="text-decoration:none;">subitem1</li>
<li>subitem2</li>
</ul>
</li>
</ul>
Does anyone knows why is this and how can I fix it?
You could change your subitem to
<li style="text-decoration:none !important;">subitem1</li>
that should fix it for you.
However abuse of the !important rule is probably not the greatest way forward. A better strategy in the longer term would be to use a CSS file and add class attributes to your li elements.
Something like:
HTML
<ul>
<li class="main-item">item1
<ul>
<li class="sub-item">subitem1</li>
<li>subitem2</li>
</ul>
</li>
</ul>
CSS
.main-item {
text-decoration:underline;
}
.sub-item {
text-decoration:none;
}
This is simple, first understand that if you are giving text-decoration:underline; to the first level list item then the same css property is gonna apply for for the child so what u can do is
.main-nav > li {text-decoration:underline;} -- with this the css is gonna apply for only the first level of list or the parent items. Note this will not apply for other child list.
With this u dont need to add css for child list
http://jsfiddle.net/qL3Bp/

Confusion with BEM class naming convention. One level deeper

For example I have a menu block with menu elements:
.menu
.menu__element
.menu__element--current
But lets say .menu block is contained inside another block, .header
How to deal with naming in this case?
.header
.header__menu
.header__element
or
.header
.header__menu
.header__menu__element
or
.header
.menu
.menu__element
Consider using "mixes" (more than one BEM entity on the same DOM-node):
<div class="header">
<ul class="menu header__menu">
<li class="menu__element"></li>
<!-- ... -->
</ul>
</div>
So block menu is also element header__menu at the same time. That gives you the ability to apply styles for any abstract menu and add special rules for that particular menu inside the header.
The menu should be a class unto itself so .menu should suffice. If it's a menu that is ONLY in a header and never anywhere else, then .header-menu. Then you can point to the menu directly without going through the header class.
If you prefer to do it the way you outlined, then .header_menu.
<div class="header">
<ul class="menu">
<li class="menu__element">...</li>
<li class="menu__element menu__element--current">...</li>
...
</ul>
</div>
.header {...}
.menu {...}
.menu__element {...}
.menu__element--current {...}
will be right.
Block name does not change when block inserted into another block.
BEM prohibits put an elements in the elements and write classnames like block__element__element, more info: How to properly set an element's scope using BEM?
Here's what the official documentation of BEM says (http://getbem.com/faq/#css-nested-elements);
No matter how deep you're nesting, you always use the top parent as block element. So basically it would be;
.header
.header__menu
.header__element

How can I create a list which displays itself when I click it?

I am looking to create a menu which will enable me to display a list when I click a link -- I am not sure if I should create a menu title with submenus, or a list with sublists.
For instance, if I click
"Example 1"
a sub list of Example 1-1, Example 1-2, Example 1-3 etc are displayed.
Any suggestions much appreciated!!!
I suggest you can use jquery and some styles, there is an example:
http://jsfiddle.net/rv87r/1/
<ul>
<li style="cursor:pointer" onclick="lastElementChild.style.display=(lastElementChild.style.display=='none'?'':'none')">list1
<ul>
<li>item1</li>
<li>item2</li>
</ul>
</li>
</ul>​
this is a simple example, you should use jquery or id's to select the inner element because lastElementChild will not work on IE<9
if you can't use jquery then you can use
(lastElementChild?lastElementchild:lastChild)
this will return the last child on IE<9 too
As far as I know CSS doesn't support clicking. (apart from a:active, but it would not help you). It is possible to create a drop-down menu with the hover functionality, according to this, this and this tutorials.
To create what you need you will have to use javascript.
I would also recommend a JavaScript based solution, because it's very flexible and easy to achieve. However, if you absolutely want to use HTML/CSS only, you could do it like this:
It works "on click". It's tested in Safari 5/6, Firefox 13 (both OS X) and in IE9 (Windows 7). When you click the container, the list becomes visible. It stays visible until you click outside the open (focused) container (for example the second list) or any other element on the page.
CSS
div.container > h2 {
cursor: pointer;
}
div.container > ul {
display: none;
}
div.container:focus > ul {
display: block;
}
HTML
<div class="container" tabindex="-1">
<h2>Example 1</h2>
<ul>
<li>List Element 1</li>
<li>List Element 2</li>
<li>List Element 3</li>
</ul>
</div>
Demo
Try before buy

CSS on nested list : avoid styling of both lists

I have the folowing nested list structure:
HTML:
<div id="my_nested_list">
<ul>
<li>
Item label
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
</ul>
<li>
<li>...</li>
</ul>
</div>
CSS:
#my_nested_list>ul {
/* first level list */
}
#my_nested_list>ul>li {
/* first level items */
}
#my_nested_list>ul>li ul {
/* second level list */
}
#my_nested_list>ul>li ul>li {
/* second level items */
}
My problem is that with space selector instead of >, first level rules apply on the second level. But i need ie6 support, which does not support >. Thus i have to use space.
So far i have 2 solutions:
put classes on every ul and li, and use #my_nested_list ul.firstlevel li.firstlevel
use #my_nested_list ul li, and #my_nested_list ul li ul li to rewrite every unwanted first level rule.
Do you have better ideas?
Ordering the css properly is the key word.
http://jsfiddle.net/wHztz/
CSS:
ul { background: red; }
ul ul { background: green }
ul li { background: yellow; margin: 10px;}
ul ul li { background: blue; }
HTML is the same as in your question, minus the div.
Edit: Damn i always end up realizing things after ive posted my answer.. Seems like you had this idea.
About putting classes to the list. You would only need to put classes to the ul's
( Nevermind.. it depends )
Edit2: If youd insist on using classes on each element but really dont care for adding them manually, you could do something like this: http://jsfiddle.net/wHztz/5/
This gives each ul a class in sequence: ulist1, ulist2, ulist3... depending on how many uls you have of course.
Edit3: changed the code a little.
http://jsfiddle.net/wHztz/6/ - Note that i didnt change anything in the CSS so CSS doesnt do a thing in this example.
jQuery:
$("#my_nested_list > ul, ul ul").each(function (i) {
i = i+1;
$(this).addClass("list"+i).children().addClass("list"+i);
});
This generates to:
<div id="my_nested_list">
<ul class="list1">
<li class="list1">
Item label
<ul class="list2">
<li class="list2">Subitem 1</li>
<li class="list2">Subitem 2</li>
<li class="list2">Subitem 3</li>
</ul>
</li><li class="list1">
</li><li class="list1">...</li>
</ul>
</div>
You could easily target this like:
ul.list1 {}
li.list1 {}
ul.list2 {}
li.list2 {}
Note that you could change this part:
$(this).addClass("list"+i).children().addClass("list"+i);
into
$(this).addClass("ul"+i).children().addClass("li"+i);
and it would result to this.
<div id="my_nested_list">
<ul class="ul1">
<li class="li1">
Item label
<ul class="ul2">
<li class="li2">Subitem 1</li>
<li class="li2">Subitem 2</li>
<li class="li2">Subitem 3</li>
</ul>
</li><li class="li1">
</li><li class="li1">...</li>
</ul>
</div>
Your problem isn't the > selector, it's the need to support IE6.
My first advice would be to try to minimise your requirement to support this ancient browser -- even if you can't drop support entirely, accept the fact that it doesn't support some things you want to use, and that it'll look bad as a result. If it is still usable in IE6, then you've done the job, no matter how bad it looks.
This advice probably won't help in this specific case, because if you're styling nested lists, it probably means a menu structure which really needs to be styled differently between the two levels. But in general, don't sweat it too much for IE6; it's not worth the hassle.
If you really need to get some new-fangled CSS selector to work in IE6, I would recommend going the Javascript route. There are several good libraries out there which target older versions of IE, and hack in support for various features, including CSS selectors.
The two that spring to mind are:
Firstly the venerable IE7.js by Dean Edwards (and the follow-on scripts, IE8.js and IE9.js). This script has been around for ages, and adds a raft of features and bug fixes to various version of IE, but primarily IE6.
Secondly, you could try Selectivizr. This is a much newer script which focuses on adding missing CSS selectors to various versions of IE. Selectivzr works in conjunction with another library (it can use any one of several), so if you're already using a library such as JQuery or MooTools, this may be a good choice.
Both of the above will make IE6 recognise your > CSS selector (among others), and thus your stylesheets will work in IE6 without any need to rewrite them.
Obviously, both these solutions use Javascript to work, so if your IE6 user base is in the habit of switching off their Javascript then they'll end up with a broken site. It is for you to determine how serious an issue this is and how many people it will affect.
I hope that helps.