Good practice on selecting a list menu - css

Considering this markup:
<div id="container">
<div id="mainmenu">
<ul>
<li> <h1>My Dashboard</h1></li><br>
<li> <h1>About</h1></li><br>
<li> <h1>Contact</h1></li><br>
<li> <h1>Setttings</h1></li><br>
<li> <h1>Log Out</h1></li><br>
</ul>
</div>
</div>
Selecting this way is a valid thing? I am having issues with some properties.
#container ul li{
display: inline-block;
}
#mainmenu ul li a{}
#mainmenu ul li a:hover{}
full sample:
https://jsfiddle.net/jhr1q1q4/

I'm somewhat unsure what you're asking...
Strictly speaking, the selectors you provided are valid and would select the <a> elements within your #mainmenu element.
But I would ask: is the ul li part of the selectors necessary? You could rewrite both of them as
#mainmenu a {}
#mainmenu a:hover {}
and they would work the same and require less parsing. If you wanted to only select <a> elements that are descendants of <li> elements, you could keep the li in your selector; however, the ul is not necessary -- it is implied your <li> elements will be children of a <ul> (assuming you're writing valid HTML).
Another note: <a> elements are inline, meaning they're meant to act at the text level. <h1> elements, on the other hand, are block-level elements, and thus do not belong inside <a> elements. In fact, you usually shouldn't have more than one <h1> on a page, let alone be using <h1>'s to mark up menu items. If you want your menu items to be big like headers, use your CSS rules to style them that way.
I am having issues with some properties.
What properties are causing trouble?

Related

Double html tag in css Style Sheet

I am changing a wordpress stylesheet and found this
.banner ul ul
This is all part of .banner ul already, so i.e.
.banner ul {blabla}
.banner ul ul {blabla}
. banner ul ul ul {blabla}
I am wondering what this does, does this only target the second/third ul?
Assuming it wasn't a mistake (which doesn't seem to be), that represents css to be applied to an ul inside another ul, like so:
<div class="banner">
<ul>
<li>
...
</li>
<li>
<ul> <----
<li>...</li>
<li>...</li>
</ul>
</li>
</ul>
</div>
Only what is inside that second ul will be affected by what's inside .banner ul ul
The author of the stylesheet probably intends to provide a selector with greater specificity in order to override other existing styles which might affect a <ul> inside a <ul> (as others have mentioned). It's very likely that your site may have inline <style> blocks or other stylesheets that also attempt to style the same element. Though it may be identical to parent styles, by being more specific with the selector, this style will be more likely to be applied over conflicting styles.

CSS multiple descendant selectors

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.

Styling a dynamic nested UL structure

I have a nested UL structure that represents a folder tree which can grow very deep. I'm stuck at doing a simple :hover effect for the LI elements. The problem is that doing a li:hover won't work as it affects all the parent "li's" aswell. Usually I would have tried to apply the hover effect to a link element or something in the LI, to avoid parents taking the style aswell, but due to circumstances that's not an option now. I have a working solution by using javascript to place a class on the hovered LI and then style this class instead, but i'm really interested in seeing if there's actually a way of accomplishing this through pure css.
I imagine there may be a way of doing a very "hardcoded" css solution but i am more interested in a dynamic and clean one, since the structure can nest indefinitely.
Maybe there's some pseudo selector i'm not aware of? Note that it doesn't have to be IE<8 compatible
<ul>
<li>
This LI should not recieve the hover effect
<ul>
<li>
A li:hover will place the effect on this LI,
but also the parent LI, since that element is
also techincally being hovered.
</li>
</ul>
</li>
</ul>
If you want to use pure CSS then you will need to us parent, child, elements.
For the hover elements:
ul li:hover{
"Style"
}
For the other elements:
ul li ul li{
"Style"
}
UPDATE: I just reread your question, in which you state:
"Usually I would have tried to apply the hover effect to a link
element or something in the LI, to avoid parents taking the style as
well, but due to circumstances that's not an option now."
If that is true, then the solution below is not viable for your circumstance, and you cannot achieve what you desire with pure CSS. I've left my answer, however, as others who want to achieve this but can use a nested element may find it useful.
Pure CSS Only by Adding HTML
The only way you can possibly achieve something of what you seek by pure CSS is to add an extra element (like a span) within the li and perform the hover on that. I assume that whatever folder is being hovered, that folder alone is what you want to highlight. If so, this fiddle illustrates what I am saying, using this code:
HTML
<ul>
<li>
<span>Folder 1</span>
<ul>
<li>
<span>Folder 1.1</span>
<ul>
<li>
<span>Folder 1.1.1</span>
<ul>
<li>
<span>Folder 1.1.1.1</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
CSS
li span:hover {
color: red;
background-color: yellow;
}
Now, if you want child folders to also highlight on hover of a parent folder, then perhaps this fiddle illustrates what you want with this code change:
CSS
li span:hover,
li span:hover + ul span {
color: red;
background-color: yellow;
}
They key point is to utilize the extra element to control the hover, whether of the item itself or any later generation elements that the hover should affect.
Not clear at all... but if you want to style nested LI when you are hovered the parent LI without styling the parent one...
Try this:
CSS
ul li ul li {
color: blue
}
ul li:hover ul li {
color: red
}
fiddle example: http://jsfiddle.net/EHp3n/
Your question is not very clear and also it will confuse. Let me explain, when the user hover the city (India / China / UK), style should be applied to State and Country through CSS.
<ul>
<li>India (Apply Style)
<ul>
<li>India State (Apply Style)
<ul>
<li>India City (On Hover)</li>
</ul>
</li>
</ul>
</li>
<li>China
<ul>
<li>China State
<ul>
<li>China City</li>
</ul>
</li>
</ul>
</li>
<li>United Kingdom
<ul>
<li>UK State
<ul>
<li>UK City</li>
</ul>
</li>
</ul>
</li>
</ul>

CSS Unordered List: Why Does One Technique Work But Another Doesn't Work?

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.

How can I manage this nested markup and CSS to keep things simple and easy to work with?

I have the following markup that is used to produce a pop-up style mega-menu (the .column div is there to allow multiple columns within each popup, though the example below only has a single column)...
<ul id="mainmenu">
<li class="mega">
<h2>Menu 1</h2>
<div class="submenu col1 leftmenu">
<div class="column">
<ul>
<li><h3>Sub Menu Heading</h3></li>
<li><a class="hilight" href="#">Do Something</a></li>
<li><a class="hilight" href="#">More great stuff</a></li>
<li>Another Item</li>
</ul>
</div>
</div>
</li>
<li class="mega">
<h2>Second Menu</h2>
<div class="submenu col3 leftmenu">
blar blar blar
</div>
</li>
// more menus here
</ul>
As this nests quite deeply with quite a few similar tags (<li> <a>) I end up needing a fairly horrible list of selectors to style it in css, eg.
#mainmenu li h2 a {}
#mainmenu li.mega .column li h3 a {}
Can anyone suggest any improvements to the markup so that it would be simpler to target with CSS and jQuery?
If it were me, I'd put nicely targetable classes on the final entities in question, and change
#mainmenu li h2 a {}
to
#mainmenu .section {}
and
#mainmenu li.mega .column li h3 a {}
to
#mainmenu .subsection {}
and whatnot.
Personally I think your html looks good, it's not plagued with endless ids and none of the classes seem redundant or useless.
If you don't ever use an h3 anywhere but inside an li, inside a column, inside a parent li then you could do: #mainmenu h3 a. I really think you can just be less explicit in your selectors.
I try to really utilize unique html tags so that all I need is an id on the top-most element and a few classes beneath if needed.
You could always use more specific selector names. Instead of:
#mainmenu li.mega .column li h3 a {}
and
<ul id="mainmenu"><li class="mega"><div class="column"><li><h3><a>
use
h3.mega_column a {}
and
<ul id="mainmenu"><li class="mega"><div class="column"><li><h3 class="mega_column"><a>
Not without seeing the rest of your CSS really, but I think your motivation is wrong. You should aim for your mark-up to reflect exactly what content is required. If this thing needs to be defined as separate from that thing they need to exist as different elements, if not, not. Separate concerns and don't even think about the CSS until your mark-up is as it needs to be.
I will say that it looks like it's possible you could collapse div.column and the ul child into just ul.column and the anchor in the h2's could possibly be moved inside the div.submenu's and given a "header" class for example.
Aside from making sure that your structure is really fitting the semantics of your content and not just there for design reasons, there are a few things I can suggest:
You don't need to wrap <ul> in a <div> if there's nothing else in the div. They're both block-level elements and you could write <ul class="column"> and save yourself some unnecessary markup. It's redundant as-is.
You might be able to simplify your CSS a lot if you're not using class names to mean different things in different places. For example, if you only use the "column" class in under #mainmenu .mega then there's really no need to specify it every time. Just saying .column h3 a will get there just the same.
If you want simplicity in jquery you could also take advantage of the CSS3 selectors like :not() to sort things out for you. For example instead of $("#mainmenu li.mega .column li") you could instead do $("#mainmenu li:not(.mega)")
Those are my thoughts.

Resources