Help me understand CSS hierarchy

Here is what I need a better understanding of…


<ul id="nav">
     <li>home
           <ul id="subNav>
                <li></li>
                <li></li>
           </ul>
     </li>
     <li>Products</li>
     <li>Contact</li>
</ul>

if I setup my CSS as such:

#nav li{width=200px;}

that will also set the subNav li’s to a width of 200px…ok makes sense.

But if I explicitly call out the subNav li as such:

#subNav li{width=100px;}…the subNav li still takes the property of the #nav li.

Why is #nav li taking precedence over #subNav li? This is what I’m trying to understand. Thanks

This is your code; I added outlines. Open this example page in your browser, then follow the two instructions written at the top of the page and observe the changes that take place on the screen.
Both of these errors are important. Neither is trivial.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>code errors</title>
<!--
INSTRUCTIONS:
Line 29:  <ul id="subNav>  is missing a close quote mark.  Add it  <ul id="subNav">  and see what happens.
Lines 17 and 21:  {width=200px} is improperly formed CSS.  It should be written  {width:200px}  with a colon, not an equals sign.
-->
    <style type="text/css">

#nav li {
    outline:1px solid magenta;    /* TEST Outline */
    width=200px;
}
#subNav li {
    outline:1px solid cyan;    /* TEST Outline */
    width=100px;
}

    </style>
</head>
<body>

<ul id="nav">
     <li>home
           <ul id="subNav>
                <li></li>
                <li></li>
           </ul>
     </li>
     <li>Products</li>
     <li>Contact</li>
</ul>

</body>
</html>

Sorry, my css/html is correct on my actual website I was just quickly typing to make this post.

So you’re saying, besides the semantic errors, that what I’m talking about should be working?

This should help explain it better…

Here is a snap shot of Developer’s Tools showing that #mainNav li is taking precedence over .subColDbl ul li, since the two properties I set are crossed out.

Here is part of the HTML below.

		<ul id="mainNav">
			<li class="home"><a href="index.php">Home<span></span></a></li>
			<li class="capabilities"><a href="capabilities.php">Capabilities<span></span></a>
				
				<div class="subMenu">
					<h3>Manufacturing Capabilities &amp; Services</h3>
					
					<div class="subColDbl">
						<h4>Metal Stampings</h4>	
						<ul>
							<li>Precision Stampings</li>
							<li>Metallic Stampings</li>
							<li>Non-Metallic (Soft) Stampings</li>
							<li>Custom Stampings</li>
						</ul>		
					</div>
										
					<div class="subColDbl">
						<h4>Metal Fabrication</h4>
						<ul>
							<li>Laser Cutting</li>
							<li>CnC Punching</li>
							<li>Forming (Press Brakes)</li>
							<li>Robotic Mig Welding</li>
							<li>Spot Welding</li>
							<li>Resistance (Nut) Welding</li>
						</ul>
					</div>

			</li>
	        <li class="inventory"><a href="inventory.php">Inventory Programs<span></span></a></li>
	        <li class="about"><a href="about.php">About Us<span></span></a></li>
	        <li class="contact"><a href="contact.php">Contact<span></span></a></li>
		
     <!-- END OF mainNav --></ul> 

From what I’ve researched so far about CSS Style Precedence is that Im running into the problem that an ID is more specific than a Class and that is why I’m not seeing the results I’m after.

Hi, Bades,

There are no semantic errors in your example code. There are 3 significant examples of 2 punctuation errors.

No screen captures appear in the previous post nor links to any.

What my example SHOWS is that if the punctuation in the example code that you posted is corrected, it works properly. Why the code on your web site does not work cannot be determined yet, but I would suggest taking another look at the ancestral code on your site. You will probably find a specificity issue. Just a guess because subColDbl is actually the third tier in the menu hierchy.

We have to wait until the css that you attached is approved.

In the meanwhile, your developer’s tools should show which line of CSS is supplying the width to the errant <li>s.

That sounds very likely to me, too. :slight_smile:

Read a few articles where some developers don’t even use ID’s for this particular headache of precedence. Seems ok with me.

I’m not a big fan of ID’s for that very reason. ID’s are useful as hooks for JavaScript and targets for fragment identifiers, but for most other purposes, I prefer to use classes. I suspect that new coders use “id” instead of “class” simply because it’s shorter and faster to write :slight_smile: without understand the implications of its “weight”.

Anyway, it sounds like you are on the right track.

lets address some issues:

#1. when setting a CSS property you use ‘:’ not ‘=’ so:

 li { width: 500px; }

and NOT

 li{ width= 500px; } 

#2. what you are referring as “hierarchy” … forget it! it doesnt exist. Clear that out of your head… no ‘hierarchy’… cleared? is it out of your head? good! onto…

#3 CSS doesnt have hierarchy,
but it does have SPECIFICITY. That is selectors are more targeted, more specific than others. This is kinda a trippy concept but lemme give you some basics and a few examples

a TAG , or any number of them,

li { your declaration....}   
div li li { your declaration....}   

is less specific than a class

.listItem { your declaration....}   

by the same token and ID is more specific than any number of classes ,tags, or combination

so :

#anID{your declaration....} 

trumps

 .oList .listItem { your declaration....}

which trumps

ul li ul li { .listItem { your declaration....}

Some basics still apply 2 IDs beat one ID, 2 classes beat on class, 2tags beat one, a tag and a class beat a class by itself… follow?

#4 yeah… well now conflicts will happen.
This is what is happening in your code

#subNav li { your declaration....}
#nav li { your declaration....}

see it yet?
They BOTH have the same specificity 1 ID + 1 tag… so CSS gets ‘confused’. It applies the rule that comes LATER in your style sheet as the rule you want.

So…

#subNav li { your declaration....}
#nav li { your declaration....}

( here the #nav li declarations will override the #subNav li declarations !!!)

IS NOT THE SAME AS

#nav li { your declaration....}
#subNav li { your declaration....}

#5 Even if it worked, it’s pretty sloppy. Precarious is a better word. Imagine one day you copy paste some rules about or ave to override something, and poof you switch the order accidentally. it’s better to write selectors that are as specific as you need them to be ( but not too much)

eg.:

#nav li { your declaration....}
#nav #subNav li { your declaration....}

( two IDs is kinda heavy tho)

#nav li { your declaration....}
ul#subNav li { your declaration....} or even

#nav li { your declaration....}
ul  #subNav li { your declaration....}

if you know that you are targeting ONLY direct child elements of #subNav this would work too

#nav li { your declaration....}
#subNav>li { your declaration....}

now you are targeting the element regardless of where you rule are declared in your style sheet

#6 Advanced basics pt.1:
Partial conflicts can occur. That is CSS only applies and overrides what you have declared.


#subNav li { color:red; background:pink; width:500px;  overflow:hidden;  font-size:125%; }
#nav li { width:125px;  font-size:70%; border:1px solid }

since color and background are not declared in #nav li {}, it may be misleading to novices seeing that only the width and font-size #subNav li is coming out ‘wrong’ and with a border. But what is happening is perfectly normal ( in fact useful at times) and that is declarations that are latter in the code are added/overridden. In other words, in the sample above , only concurrent or absent declarations in #subNav li {} are affected by #nav li{}


#7 Advanced basics pt.2:

IDs are pretty heavy. You can use them you can opt not to do so … and sometimes they are unavoidable ( hooks for .js ). Remember that when you do use an ID you have made the MINIMAL requirement for targeting a descendant element using an ID.

#nav li { your declaration....}

ANY OTHER DESCENDANT LI you wish to target will require at least one ID and one tag in the rule.

for example if thought your you want page ALL sub list are pink:

 .subNav{ background: pink; }

and you tossed this in


#nav li { background: orange;}

the sub lists of #nav will be orange and you will need an additional declaration

#nav  .subNav{ background: pink; }

hope that helps you understand CSS a bit better

Sorry for the late response…

Thanks Dresden, you always have great explanations that really help out!

@[B][COLOR=#363][B]dresden_phoenix[/B][/COLOR][/B]

Really thanks for your explanation i just change my mind about css after read your post. So, there is no more hierarchy in css :slight_smile: