CSS on nested list : avoid styling of both lists - html

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.

Related

Is there a way to avoid using the :not psuedo-class to pick an item out of a list in CSS?

Say I have an unordered list:
<div id="list">
<ul>
<li>Item 1</li>
<li><img src="2.jpg"></li>
<li>Item 3</li>
</div>
And my CSS is:
#list a:hover {background: #FFF;}
Is there an easy way to NOT target the img list item aside from using the :not psuedo-class. I'm sure there is but I'm having the hardest time figuring out what that is.
Thank you!
EDIT: Trying to avoid all psuedo-classes for IE7/8 support. :not and :nth-child are solutions to the problem, I'm just intentionally avoiding them.
You can use nth-child() see fiddle: https://jsfiddle.net/DIRTY_SMITH/dzx37chb/2/
li:nth-child(odd) a:hover {background: blue;}
Microsoft has dropped support for anything under IE 11 as of January 12th, 2016.
Therefore it would be wise not waste your time on trying to find a solution for avoiding all psuedo-classes.
Beginning January 12, 2016, only the most current version of Internet Explorer available for a supported operating system will receive technical supports and security updates.
An answer to my own question but please tell me if there is a better way:
<li class="selected-item">Item 1</li>
<li>Item 1</li>
<li class="selected-item">Item 1</li>
CSS:
.selected-item a:hover {background: #FFF;}
So just target the specific items. Its a bit clunky in the HTML.

CSS Styles Inherited from Parent in Nested List

I'm working on a resume-layout done in html/css. The problem I am encountering is an inheritance issue, I think. I've done a bit of research online, and this seems to be a fairly common problem, often associated with IE (insert expletives about IE).
This is what I'm attempting:
Edit
I want to have the parent list item underlined with no bullet point (disc).
I want the child (nested list) to have a bullet point (disc) and no underline.
So I've gone to JSfiddle and cut out the sections of the code (CSS normalize checked) to try and sort out what's going on and what I might be doing wrong.
HTML:
<h3>Qualifications Summary</h3>
<ul id="qualifications">
<li>BS in Computer Animation with a focus on art, design, illustration, and motion graphics.</li>
</ul>
<h3>Related Experience</h3>
<ul class="experience">
<li>Jun. 2002 – Present ~ <span class="jobtitle">Freelance Illustrator & Web Designer</span> ~ Drakenhart Studios
<ul>
<li>Educator, Illustrator, Graphic & Web Designer</li>
</ul>
</li>
<li>Nov 2006 - April 2008 ~ <span class="jobtitle">Graphic / Web Design</span> ~ National A1 Inc, Philadelphia, PA
<ul>
<li>Junior Designer</li>
</ul>
</li>
</ul>
This is the CSS:
ul {
padding-bottom: 15px;
margin:0px;
font-family: "Open Sans", Arial, Helvetica, sans-serif;
font-size: 14px;
}
/*Nested List Issues*/
ul.experience li {
text-decoration:underline;
list-style: none;
}
ul.experience ul li{
text-decoration:none;
list-style: disc;
}
Even with the code sectioned out and only the CSS that relates directly to it used, I still get the error.
Question I've been asking myself:
1) Is it something in the Normalize code? Not that I can see.
2) Is it the Browser/version? I use Chrome 36.x mostly. I've checked it in IE and Firefox. The same issue occurs.
3) Is there another way of doing this? Perhaps and very likely my syntax or usage is wrong. I've tried other ways including the > selector, but the most I get is the discs on the nested li shows up.
I made other attempts but as I am new.... I can't posted them yet. :)
I just can't seem to get it to work. What have I done incorrectly?
edit
Current suggestions offer to place a span tag around the parent element's content and style that. So far that seems to work. It adds more code to the markup rather then focus on CSS muscle. Inelegant but functional.
The normalize setting causes margin and padding on the list items to be removed. Try setting the list item to have a margin-left of 2em for instance. Also, instead of the text-decoration on the outer li, place your text in a span, and set the text-decoration on that instead.
You don't state exactly what the issue is, but I'm going to assume that it's 2 things:
1) The underline text-decoration property is showing up in the sub-list items. This is a bit confusing until you look at the markup:
<ul class="experience">
<li>Jun. 2002 – Present ~ <span class="jobtitle">Freelance Illustrator & Web Designer</span> ~ Drakenhart Studios
<ul>
<li>Educator, Illustrator, Graphic & Web Designer</li>
</ul>
</li>
...
Note that the first-level list item for <ul class="experience"> is not closed until after the sub-list is closed. What this means is that the sub-list gets the underline appearance even if you over-ride it on the sub-list items (as the property is actually on the parent list item).
To get around this, wrap the part you want underlined in another element, like a span and apply the underline style to the span:
<ul class="experience">
<li><span>Jun. 2002 – Present ~ <span class="jobtitle">Freelance Illustrator & Web Designer</span> ~ Drakenhart Studios</span>
<ul>
<li>Educator, Illustrator, Graphic & Web Designer</li>
</ul>
</li>
...
CSS:
ul.experience > li span {
text-decoration:underline;
}
2) The other issue I assume, is the disc not showing up. That's because normalize.css removes margin and padding from all lists. Add that back in:
ul.experience ul {
list-style: disc;
padding-left: 2em;
}
fiddle
IF you un-check "Normalized CSS" on the Fiddle Options (left pane of Fiddle) your code should work somehow... (it worked for me).
Using both steveax and Steven Don's suggestions I still had trouble with it. I realized that a part of the issue was with Bootstrap 3.0. After singling out the code and the CSS in Jssfiddle, though it mostly worked there, it still was not working in my working draft.
After a bit of adjusting both html and the css I finally got it to behave with little issues. However where it worked in JSFiddle, it wasn't working in my working code.
So because I was using bootstrap I double checked the documentation and still couldn't find the issue there. So I used Chrome's inspect element. For some reason list-style does not override the more specific list-style-type in Bootstrap.
So I switched the CSS around so I wasn't turning off and then on-again the list style Bootstrap was enforcing. I just switched off the disc for the main entry heading that was underlined as well, and then used the span tag on it (the first li) to underline it while avoiding underlining the child element as well.
I even removed the span around the job title, and used the strong tag instead.
HTML
<ul class="experience">
<li><span>Jun. 2002 – Present ~ <b>Freelance Illustrator & Web Designer</b> ~ Drakenhart Studios </span>
<ul>
<li>Educator, Illustrator, Graphic & Web Designer</li>
</ul>
</li>
</ul>
CSS
ul.experience > li { padding-left:2em; }
ul.experience ul { list-style:disc; padding-left:2em; }
ul.experience > li span { text-decoration:underline; }
Less code then I was using before in my CSS. It now works properly.
Try using the CSS important. An example of how it would be used is below:
text-align: center !important;
As you can see, it goes just before the semi-colon. Hope this helps!

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/

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