Nested CSS classes in li/ul - html

I have a nested li and they have specific classes. I am having issues with the nested classes. Despite the specific class, the styling is that of the class of the parent:
<ul>
<li class="navtitle-current">ONE
<ul>
<li class="navtitle-current">TWO</li>
<li class="navtitle">THREE</li>
</ul>
</li>
</ul>
.navtitle {
font-weight: none;
}
.navtitle a{
background-color:white;
color: gray;
}
.navtitle a:hover,
.navtitle:hover{
background-color:white;
color: black;
}
.navtitle-current {
font-weight: none;
}
.navtitle-current a{
background-color:white;
color: black;
}
.navtitle-current a:hover,
.navtitle-current:hover{
background-color:white;
color: black;
}
What I want to happen is that ONE needs to be in black, TWO in black and THREE in gray. However, all the links are black.
I was under the impression that if I explicitly have a class, I should not have any such issues. Does anyone have any thoughts?
All help is appreciated.
Note: I realize the CSS blocks are not in . I just put the code on here for the sake of showing what I have.

Because .navtitle-current is higher level than .navtitle, the links are inheriting the .navtitle-current a styles. If you want to style links inside that, you need to be more specific with your tags. Change .navtitle a to .navtitle-current .navtitle a and it should work.

Yet another way to go about this:
jsFiddle
.navtitle-current .navtitle a {
background-color:white;
color: gray;
}
It may be just a personal preference, but when possible I try to avoid chaining ul li ul li etc. I find it a bit more readable to use the class names.

The problem is selector specificity - your second to last declaration has the same exact same weight and origin as the class defining the gray-colored text - .navtitle a - and due to the nature of the cascade, the latter rule specified will win
From the 2.1 Spec, Specificity:
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.
To overcome this, just increase the specificity of .navtitle a by including li before the class, e.g.
li.navtitle a {
background-color: gray;
color: gray;
}
Example

You could do it more clever:
<div class="titles">
<ul>
<li class="current">ONE
<ul>
<li class="current">TWO</li>
<li>THREE</li>
</ul>
</li>
</ul>
</div>
.titles ul li {...}
.titles ul li.current {...}
.titles ul li.current ul li {...}
.titles ul li.current ul li.current {...}
regards,

Related

CSS Descendant Selectors: Some Work While Some Do Not

I am trying to style a nav link to be a certain color when I am on that page.
HTML:
<nav>
<ul>
<li>Portfolio</li>
</ul>
</nav>
CSS:
nav a.selected {
color: #000;
}
The above code works. But if I removed the nav selector and just used
a.selected {
color: #000;
}
then the code doesn't work.
What if I wanted anywhere that I have an anchor element with a class "selected" to have #000?
The problem here seems to be the specificity of your selector.
Meaning:
nav a.selected {
color: #000;
}
Is not as exact as:
nav ul li a.selected {
color: #000;
}
Which holds more significance than the above.
So in order for your a.selected to work, You need to remove the nav before it, making it a global modulator just as the color you applied to your global anchor modulator, or apply the more specific selector from above (the second block):
a {
color: #6ab47b;
}
a.selected {
color: #000;
}
As a learner, I suggest You try and stick to the Mozilla Developer Network (MDN) Almanac.

How to apply CSS to list in HTML

I had to Create a working HTML/CSS for the following nestes list
root
child1
child11
child2
child21
child22
child3
child31
So for this I created the following
HTML
<ul class="list-view">
<li>
<ul><li>Chlid11</li></ul>
</li>
<li>
<ul>
<li>Chlid21</li>
<li>Chlid22</li>
</ul>
</li>
<li>
<ul>
<li>Chlid31</li>
</ul>
</li>
</ul>
Now How will I be able to apply CSS to the leaf parent and root node .
I have to make Leaf to green , parent to red and root should be like parent but with underline
Here Leaf are
Child: 11 , 21, 22 , 31
Parent: the three li
root will be :the first ul
This was a question asked to me in an Interview I am just trying to solve it
Css has to be dynamic . I mean I was not suppose to add classes directly saying what is leaf and what is root .
Something like this
Jsfiddle
UPDATE
CSS
.list-view> li:first-child{
color:red;
text-decoration: underline;
}
.list-view> li ul li {
color:red;
}
.list-view> li ul li ul li{
color:green;
}
I am not able to make just the root node underline
Thanks
I am going to take a stab in the dark, so please don't shoot me if i jumped the gun. But here is my understanding of what he is talking about.
<ul class="root">
<li class="parent">
<ul class="leaf">
<li>Chlid11</li>
</ul>
</li>
<li class="parent">
<ul class="leaf">
<li>Chlid21</li>
<li>Chlid22</li>
</ul>
</li>
<li class="parent">
<ul class="leaf">
<li>Chlid31</li>
</ul>
</li>
</ul>
CodePen for example
first of all, your markup does not make very much sense to me. Nesting ul's inside li's is not very useful when the li's do not contain any other content. I suppose your markup should look more like this:
<ul>
<li>
<span>Root</span>
<ul>
<li>Parent</li>
<li>Parent
<ul>
<li>Leaf</li>
<li>Leaf</li>
</ul>
</li>
</ul>
</li>
<li>Root</li>
</ul>
When it comes to targeting each level with css, you have a number of options. Adding classes to each level may seem the most straight forward, but it can be harder to maintain, and it is easier to make mistakes. Others have already demonstrated this technique, so I'll limit myself to a few alternatives:
option 1a:
ul { /* root + parent + leaf */ }
ul ul { /* parent + leaf */ }
ul ul ul { /* leaf */ }
option 1b:
li { /* root + parent + leaf */ }
li li { /* parent + leaf */ }
li li li { /* leaf */ }
option 2:
ul > li { /* root + parent + leaf */ }
ul > li > ul > li { /* parent + leaf */ }
ul > li > ul > li > ul > li { /* leaf */ }
That is basically it I guess, though you could come up with some variations. Option 1a and 1b are equivalent. Option 2 is more specific, and can be useful when trying to overwrite certain styles. It is considered good practice to keep your selectors as little specific as possible though. This way you can overwrite them easier later on, and your selectors do not get ridiculously long. It just keeps your code easier to read and maintain, so I would definitely go for option 1 in this case.
Note that this technique requires you to overwrite your styles. The styling you requested could ie. be achieved by doing something like this:
li {
color:red;
}
li span {
text-decoration: underline;
}
li li li {
color:green;
}
The pseudo classes you speak of in the comments (:nth-child, ...) are irrelevant here. They are meant for distinguishing between siblings, not for parent-child relations.
edit:
the text-decoration property is a bit tricky to overwrite. Have a look at the specs on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration
Text decorations draw across descendant elements. This means that it is not possible to disable on a descendant a text decoration that is specified on one of its ancestors.
To solve this, you have to make sure the element with the underline is not the parent of the rest of your tree. Th easiest way is to put it in a span and apply the underline only to that:
http://jsfiddle.net/r616k0ks/3/
(I have updated my code samples above accordingly)
Using some specific selectors you can create almost any selection without using classes on the child elements.
I don't know if this is what you're getting at:
/* Root */
.list-view { background: grey; }
/* First level li's */
.list-view > li { background: red; }
/* First level of ul's */
.list-view > li > ul { background: orange; }
/* Second level of li's */
.list-view > li > ul > li { background: purple; }
/* Second level of li's, first element */
.list-view ul > li:nth-child(1) { background: green; }
/* Second level of li's, all other elements */
.list-view ul > li:nth-child(1n+2) { background: blue; }
See link https://jsfiddle.net/6d3g3zLm/
If not, feel free to elaborate on your question.
Have you tried adding classes to your html?
https://jsfiddle.net/w7tx52L5/
HTML
<ul>
Root
<li class="parent">
Parent1
<ul class="child"><li>Chlid11</li></ul>
</li>
<li class="parent">
Parent2
<ul class="child">
<li>Chlid21</li>
<li>Chlid22</li>
</ul>
</li>
<li class="parent">
Parent3
<ul class="child">
<li>Chlid31</li>
</ul>
</li>
</ul>
CSS
.root {
color: red;
text-decoration: underline;
}
.parent {
text-decoration: none;
color: red;
}
.child {
color: green;
}
Edit
from your comment it appears you need to use :nth-child selectors. That wasn't clear from your original question. try this css -
ul {
color: red;
display: inline-block;
width: 100%;
text-decoration: underline;
}
ul li {
display: inline-block;
width: 100%;
text-decoration: none;
color: red;
}
ul li:nth-child(odd) > ul li:first-child {
color:green;
}
ul li:nth-child(even) > ul li {
color: green;
}
The workaround of display: inline-block and width:100% is because text-decoration affects all nested elements as well. http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration
Add classes to the list elements as Geoffrey has shown in his answer. Then apply styling to the classes as you would any styling. If you don't know CSS or anything about how to style, I would suggest researching a little more before you ask these kinds of questions, as this stuff is relatively easy to learn if you put some time and effort into it. http://www.w3schools.com/css/

CSS Selector for higher order li

As you can see I had a difficult time expressing the question in the title.
I have a ul that contains lis which themselves contain a ul with it's own lis.
I would like to target just the first li elements and not the elements within the second ul.
If you look at this fiddle (or the code below), I would like to change item 1's color but not sub item 1's. Is that possible without attaching a class to the li elements?
<div class="foo">
<ul>
<li>
item 1
<ul>
<li>sub item 1</li>
</ul>
</li>
</ul>
</div>
will something like this help?
.foo ul li {
color: red;
}
.foo ul li ul li {
color:green;
}
demo - http://jsfiddle.net/victor_007/6fqbc4ud/6/
:not(li) > ul > li {
color: red;
}
ul li{
color:green;
}
To do so, use the child combinators selector, which only selects a direct child.
At first glance you might use ul>li, but that will also select the second level list-items, since they're also a direct child of the list.
So you need to define a starting point, in this case the parent (div).
I now see that you already have the answer yourself. It however doesn't work in your fiddle since you don't declare a 'default' color. Which means that the second level list-item inherits the color of it's parent.
li {
color: blue;
}
.foo>ul>li {
color: red;
}
updated Fiddle.
.foo ul li { color: black; }
.foo > ul > li { color: red; }
Demo

Style ul and li

I'm trying to style some unordered lists and running into problems...it isn't affecting the output!
The example I can't get to change.
<div id="footer">
<div id="foot-nav">
<ul>
<li>home</li>
<li>site map</li>
<li>three</li>
</ul>
</div>
</div>
The CSS:
#footer #foot-nav ul.blah {
list-style-type: none;
}
#footer #foot-nav ul.blah li.blah {
padding:2px 0;
}
#footer #foot-nav ul.blah li.blah a {
color:#333;
text-decoration: none;
}
#footer #foot-nav ul.blah li.blah a:hover {
text-decoration: underline;
}
Another UL from the same page
.mobile-menu #mobile-menu-links ul{
list-style-type: none;
margin:0;
padding-left:3%;
}
.mobile-menu #mobile-menu-links ul li{
padding-bottom:2px;
border-bottom:1px solid #bababa;
}
<div class="mobile-menu" id="mobile-account">
<div id="mobile-menu-links">
<h4>General:</h4>
<ul>
<li>View your profile</li>
<li>Change your settings</li>
<li>View your messages</li>
</ul>
</div>
</div>
The rules from the #mobile-menu ul is taking preference with the ul from the top of the question?
I'm obviously doing something wrong, could you help? Thanks!
http://jsfiddle.net/GgdhX/
You're using a lot of descendant selectors for IDs and needless classes on LI elements.
#foot-nav .blah{
list-style-type: none;
}
#foot-nav .blah li{
padding:2px 0;
}
#foot-nav .blah li a{
color:#333;
text-decoration: none;
}
#foot-nav .blah a:hover{
text-decoration: underline;
}
<div id="foot-nav">
<ul class="blah">
<li>home</li>
<li>site map</li>
<li>three</li>
</ul>
</div>
#footer #foot-nav ul.blah
This selector applies to <ul> elements that have the blah class, which is a descendant of an element with an ID of foot-nav, which is a descendant of an element with an ID of footer.
Aside from the last part, your HTML matches that, so I would assume that the problem is that your #foot-nav element is not within an element with an ID of footer.
You can either remove #footer from all your selectors, or you can put your #foot-nav element within an element that has an ID of footer.
Edit:
Okay, in light of the changes to the question, either there's something wrong with the CSS that is stopping it from getting applied at all, or the CSS is being overridden.
Inspect the element in a web browser's developer tools to see if the rules are showing up at all. If they are, then they are probably being overridden by rules elsewhere on the page. If that is the case, then you should be able to see where the other rules are while you are inspecting the element.
If the rules are not being applied at all, then it's likely there's something wrong with your CSS. Have you run it through a validator to check to see if there are no syntax errors? Are the rules within a media query that isn't in effect?
If you remove all the #footer aspects of the selectors you have on there, everything should work perfectly. I made a jsfiddle of the working copy. Let me know if this is the UI concept you had in mind. Also, I suggest you read up on CSS Specificity to understand how rules are prioritized when applied to different nested elements

CSS cascading order within one stylesheet

I'm trying to figure out if I'm totally mis-understanding something here.
I have a menu and submenu (dropdown style using only CSS, no javascript) and for some reason the sub-menu styles (defined by .submenu li a) always shows up at the same style as the parent a (defined by #menu li a) even though the submenu CSS styles show up AFTER the top menu styles.
Am I mis-understanding CSS rules? I thought features defined LATER and at a lower level override the top level (for example, inline style will always override style.css styles). I'm attaching a screenshot off Firebug that shows crossing out the font sizes defined on line 275 in favour of styles defined at line 225, on the parent DOM objects.
My DOM looks like this to simplify it:
<ul id="menu">
<li>
about us
<ul class="submenu">
<li>
Testimonials
</li>
</ul>
</li>
<li>
listings
</li>
<li>
MLS® Search
</li>
<li>
City Guide
<ul class="submenu">
<li>
The West End
</li>
<li>
Coal Harbour
</li>
</ul>
</li>
<li>
blog
</li>
</ul>
And my CSS looks like this.
#menu li a:link, #menu li a:visited {
color:#333;
text-decoration:none;
font-size:16px;
font-weight: bold;
padding-bottom: 3px;
text-transform: uppercase;
}
#menu li a:hover {
color:#333;
background-image: url('../images/pink_dots.png');
background-position: bottom left;
background-repeat: repeat-x;
}
#menu li a:active {
position:relative;
color:#333;
}
.submenu {
position:absolute;
left: -9999px;
display: block;
background-color: #DD2D77;
padding:0px 0px 0px 0px;
margin: 0px;
top:16px;
z-index: 20;
}
#menu li:hover .submenu {
left: -5px;
}
.submenu li {
text-align: left !important;
margin:0px !important;
padding: 2px 0px 3px 0px !important;
position:relative;
display: block;
width: auto;
float: none;
text-align: left;
}
.submenu li:hover {
}
.submenu li a:link, .submenu li a:visited {
color:#fff;
text-align: left;
font-size:12px;
font-weight: normal;
margin: 0px;
white-space:nowrap;
display: block;
padding:3px 7px 5px 7px !important;
min-width: auto;
zoom: normal;
}
.submenu li a:hover, .submenu li a:active {
color:#fff !important;
background-image: none !important;
background-color: #73AA12;
}
The id selector has more specificity than your other selector.
Increase the specificity, which is favoured over !important.
Yes; you are misunderstanding how CSS works.
http://www.htmldog.com/guides/cssadvanced/specificity/
The order in which you define rules in the CSS file means nothing. The selector determines which rules apply and when.
The axiom behind CSS is - the more specific your selectors are, the more precedence they take over less specific ones.
This is how anchor styles work for instance. To show an underline only on hover:
a:hover
{
text-decoration: underline;
}
a
{
text-decoration: none;
}
Even though the less specific rule is defined later, the more specific rule (an anchor tag that is also mouse hovered) overrules the more general rule.
You're correct in saying that rules declared later in the cascade take precedence but only if they are at an equal or higher specificity.
Your first style #main li a uses an ID as the context whereas the second style .submenu li a uses a CLASS as the context. An ID holds more specificity than the CLASS, so it overrides the .submenu.
You need to read up a bit on CSS Specificity:
http://www.htmldog.com/guides/cssadvanced/specificity/
http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
http://coding.smashingmagazine.com/2010/04/07/css-specificity-and-inheritance/
http://css-tricks.com/specifics-on-css-specificity/
You could do a quick fix and declare #main > li a - which will only apply to anchors inside list items that are direct descendants of the #main element. Then, your .submenu li a rule will be applied to your submenu items.
Here is a specificity calculator that you can add as a bookmark in your browser: http://www.westciv.com/mri/
When you click it, it will open a window that you can either type a selector into, or you can click an element on the page and it will suggest the selector that you should use (showing you the path it took to get there).
It may help as a learning tool.