I am creating a navigation bar right now and I want the width of the main elements on the navigation to be auto, but sub elements to all be a fixed width. The way the list is made is as such:
<li>Main Element
<ul>
<li> Sub Element </li>
<li> Sub Element </li>
<li> Sub Element </li>
</ul>
</li>
This is repeated for each main menu item and its submenu items.
The issue I am having is I want to css for the sub elements to be 100px in width, but the main elements to be equal to the text size plus 10px of padding on both the left and right. It appears I can not change one without changing both, even after attempting to make classes to separate them. I have also tried editting ul li and li ul styles in my external style sheet. Thank you in advance for all help.
ul li affects all li's at any level under an ul. ul > li only affects the li's that are direct children of an ul. It's called a child combinator: http://www.w3.org/TR/css3-selectors/#child-combinators
You must use it if you are to make it happen without using classes (using classes would actually be the better way imo - http://www.jsfiddle.net/joplomacedo/xeWA4 )
The trick is applying the styles you want applied on the main menu items under ul > li and then override them at ul ul > li. Here's a fiddle - http://jsfiddle.net/joplomacedo/xeWA4/3/
EDIT:
You actually don't need to use the child combinator at all. Child combinators came to my mind
when I first read your question, and I kind of never questioned their use. So, ul li overridden by ul ul li works perfectly as well - and keeps it simpler.
Related
I want to write a horizontal tag list as navigator. I read some css files online, and find the following (desendant?) selector style in a single css file:
nav ul li a { ...}
nav a {...}
nav ul li {...}
I know the for 2, nav a means select all the "a" elements under nav class. But what about 1. and 3.?
Does 3. means select all the "li" insinde "ul", and the "ul" should also inside "nav"? It seems to me that 1 and 2. will have similar effect. But I cannot find an answer online.
The first means that it will apply to all <a> elements inside a <li> which is inside <ul> which is within a <nav>. In other words, it will style code that looks like this:
<nav>
<ul>
<li>
<a>...</a>
</li>
</ul>
</nav>
The reason that selector 1 and selector 2 will apply to the same elements is because if you notice <nav><ul><li><a>...</a></li></ul></nav>, the <a> is both times inside the <nav><ul>...</ul></nav>. The first selector is just more restrictive than the second selector, but because everything inside a <ul> is always supposed to also be inside a <li> element, the selectors should always apply to the same elements.
The third selector will apply to <li> elements inside a <ul> which is inside a <nav>, just like you said. In other words:
<nav>
<ul>
<li>...</li>
</ul>
</nav>
Edit: As #Hughes suggested, something to note here is the concept of "specificity." When there are multiple rules that apply to the same object, there is often times a need to break ties. For instance, what happens if we have this code?
nav ul a { color: blue; }
nav ul li a { color: green; }
It's up to CSS to determine which font colour to apply to <nav><ul><li><a> ... </a></li></ul></nav>. In these cases, CSS chooses the rule which is more specific when describing which elements it applies to. In this example, the <a> would be coloured green, because the nav ul li a rule is more specific when describing the elements that the rule should apply to (just think of the English definition for the word "specific"). Thus while both selector 1 and selector 2 from the question should apply to the same objects, if they ever both provide the same CSS property, the value in selector 1 would be chosen over the value in selector 2.
My page generates two ULs of the same ID and I would like to remove the last one via CSS (display: none). I was trying with :last-child property but no luck at all. I either made both of them disappear or none of them.
Example:
<div id="content">
<ul id="some-ul">
<li>...</li>
<li>...</li>
</ul>
<ul id="some-ul">
<li>...</li>
<li>...</li>
</ul>
</div>
I would like to apply display: none only for the last ul#some-ul inside my #content.
It could be done like so:
#content ul:last-child {
display:none;
}
Note that last-child is only supported in IE9+. As mentioned by #Jop, you should set a class on the last child element to get around this for older versions of IE.
jsFiddle here.
Also, remember that ID's should always be unique.
Completely generic way to do this, that relies on no classes or ID's
div ul:last-of-type li:last-child {
display:none;
}
So basically, the div is the parent item that contains the list items - it could have a class or ID if you want.
Within that, you have your ul tags - the last-of-type does the magic, finding the last ul within the parent div. You then simply use last child on the li.
Here's the fiddle:
http://jsfiddle.net/Kx8SN/
I'm not sure if my question title accurately displays what I'm trying to ask, but this is pretty much my first exposure to CSS3 and have been exploring various projects people have done in order to gain some hands on experience.
In searching through these projects I cam across something I'm having some trouble understanding. What exactly is the difference between the following two lines:
#random_ID > ul > li > a { ... }
#random_ID ul li a { ... }
Are these just two ways of writing the same thing? Any help would be greatly appreciated!
The greater than symbol limits the lookup to just first-level descendants: children of the selector on the left. Without the symbol, it can be any descendent at any level.
So the first example, it's "random_ID with a child ul with a child li with a child a" and the second is "random_ID with any descendant ul with any descendent li with any descendent a"
> means "direct child". This will only style it if the element (one on the right of >) is a direct child of the parent (one on the left of >)
So say if I have the following layout:
<div>
<ul>
<li></li>
<li></li>
</ul>
</div>
div > li { background: red; } Would not work, because li is not a direct child of it, whereas div > ul > li> or div li would work.
It should be noted that not every browser supports the direct child tag, specifically older versions of internet explorer, so don't rely on it, or have some fallback if you do use it.
Let's say a have the following code:
<nav id="main-navigation">
<ul>
<li>Link 1 Level 1</li>
<li>Link 1 Level 1</li>
<ul>
<li>Link 1 Level 2
</ul>
</ul>
</nav>
And now I want to to set first ul's height to 100px and second ul should be 300px.
When I try
nav ul {
height: 100px
}
Second ul also inherits this value.
I was trying "~", "+", ">", first-childs etc. but don't know how to do that, even with documentation.
Is there a good explained (preferably with demos/screens) guide to new css3 selectors? W3 Table is too nerdy for me.
Thanks!!!
Just select any ul that is a descendant of ul and give it that style, if you will only have 2 layers of <ul>s. No need for any special CSS2/CSS3 combinators since <ul> cannot directly contain <ul>, plus you don't have to worry about IE either.
nav ul {
height: 100px;
}
nav ul ul {
height: 300px;
}
To select direct children of an element, and not any descendant, you should use the > syntax. In your case (after you put the second ul inside a li) you need:
nav > ul {
height: 100px;
}
nav > ul > li > ul {
height: 300px;
}
Extra: It doesn't really make sense to have a 300px item inside a 100px item. Why do you want that?
Another extra: Try to read the w3c docs, it will save you some time in the long run. What you don't understand you can always ask on SO.
Firstly, how imporant is browser compatibility to you? All of those selectors you mentioned have issues in various versions of IE (IE8 is obviously better than IE7, but even IE8 is missing a lot of CSS selectors)
Simple nested selectors (ie just a space between the CSS names) will work for you - although as you say, setting nav li {height:100px;} sets it for all the LIs, you can override that with nav li li {height:300px;} to set the inner one back the way you want it.
If you want to use the 'correct' selectors, the one you want is >.
nav>ul>li {
height:100px;
}
This will only affect the outer LI elements, not the inner one. However as I say, it won't work in older versions of IE (fortunately it does work in IE7 and up, so it's only an issue if you want to support IE6).
You say that you've found the various selectors quite hard to grasp. I recommend you visit Quirksmode. For a start, it's got a very handy compatibility chart showing which browsers support which selectors, but it's also got excellent examples of how each selector works, which should help you understand them a bit better.
I have a basic unordered list in HTML/CSS as follows...
<div class="floatleft">
<ul class="help">
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>
I'm trying to do some custom stuff (image bullets, margin, padding, etc.) Since I assigned a class to the list block, I thought I could make my CSS declarations like the first two lines below. But that doesn't work. When I do it like in the two lines below that, it works fine. I'm not understanding what the difference is.
.help ul { declarations } /* Doesn't work */
.help li { declarations } /* Doesn't work */
ul.help { declarations } /* Works! */
li.help { declarations } /* Works! */
Can anyone enlighten me? Thanks.
The "doesn't work" requires the <ul> to be a child (direct or non-direct) of any element of class help
So if the div was:
<div class="floatleft help">
It would work.
.help ul is targeting <ul> descendants of elements with the 'help' class:
Example: (won't work)
<div class="help">
<ul>
ul.help targets <ul> elements with the help class.
Example: (will work)
<ul class="help">
.help li should work as that is targeting <li> descendants of elements with the 'help' class, which is what you have.
Example: (will work)
<ul class="help>
<li>
li.help shouldn't work because that will target <li> elements with the 'help' class, which you don't have in your markup.
Example: (won't work)
<ul>
<li class="help">
Read up on how descendant selectors and the cascade (the 'C' in CSS) works.
The space character pretty much means "now let's look at the children".
So when you have .help ul you are saying "grab all things with a class of help" then "grab all ul children within those things".
However, "ul.help" says "grab all things that BOTH have a class of help and are a ul".
The problem is that the selector .help ul applies to a ul tag that is a child of an element with the class help. The corresponding markup for this would look something like this, where the div tag could be any element, and not necessarily the immediate parent of the ul tag.
<div class="help">
<ul>
....
</ul>
</div>
In your case, you have a ul tag with the class help, which is exactly what ul.help selects.
For a comprehensive reference on CSS selectors, see the W3C page.
To expand on Matt's answer:
.help ul Means "a ul element contained (however deeply nested) within an element with the class 'help'"
ul.help Means "a ul element with the class 'help'"
For reference
ul .help Means "an element with the class 'help' contained (however deeply nested) within an element with a ul element"
On the last line li.help shouldn't work either because you're addressing all li's with a class of 'help' of which you have none.
What 'works' might also depend on which element you're trying to apply the styles to. You might want to check some HTML reference guides as to what elements to apply your list settings to. Generally your overall bullet settings are done on the ul but some spacing is also applied to the li's in some browsers.