CSS dropdown menu: What is the fastest selector? - html

I have a multi level navigation menu on my page consisting of an unordered list. That list has the class menu, like so:
<ul class="menu">
<li>Category 1</li>
<li>Category 2</li>
<li>Category 3
<ul>
<li>Subcategory 1</li>
<li>Subcategory 2</li>
</ul>
</li>
</ul>
The href attributes are set to # for illustration purposes.
My question is: What is the best Selector to use for that kind of menu regarding speed?
At the moment I am using something along these lines (again, just for illustration, there are rules missing):
.menu {
background-color: #CCC;
}
.menu li {
background-color: #FFF;
}
.menu li > ul li ul {
background-color: #333;
}
Is a class the fastest selector in that case? Or should I use something like .navigation-container ul? Do you have any recommendations?

Simpler selectors are faster than complex selectors. For example .menu is faster than .menu ul, but it's no dramatic difference.
What you have is fine. You could perhaps try to make the .menu li > ul li ul less complex, but don't expect to notice any difference, because you could perhaps shave off a millisecond or two on the rendering time.
Here is some reading about efficient CSS seletors: http://csswizardry.com/2011/09/writing-efficient-css-selectors/

It's quicker to reference with an id, e.g. #menu, #menu li. I would also add an id to the sub ul tags too :)

Related

Styling HTML Child Lists [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I was testing list-style-type changes for child lists and noticed something strange happening. When you try and change the properties of a child list by using a selector like li li it will not work. If you remove the topmost selector in my below example, all styles are removed. If you inspect the element, the styles aren't being applied at all so it's not as though something is overwriting them.
li {
color: purple;
}
li li {
color: red;
list-style-type: circle;
}
li li li {
color: blue;
list-style-type: lower-roman;
}
li li li li {
color: green;
list-style-type: square;
}
<ul>
<li>Parent List</li>
<ul>
<li>1st Child</li>
<ul>
<li>2nd Child</li>
<ul>
<li>3rd Child</li>
</ul>
</ul>
</ul>
</ul>
When you replace li with ul, it works as you'd expect the above to. Why does all of this happen? I've never seen behaviour like this before.
ul {
color: purple;
}
ul ul {
color: red;
list-style-type: circle;
}
ul ul ul {
color: blue;
list-style-type: lower-roman;
}
ul ul ul ul {
color: green;
list-style-type: square;
}
<ul>
<li>Parent List</li>
<ul>
<li>1st Child</li>
<ul>
<li>2nd Child</li>
<ul>
<li>3rd Child</li>
</ul>
</ul>
</ul>
</ul>
I am voting to close this as I'm an idiot and that's the extent of this. I'd hope you vote to close as well.
That's because using li li means a child li of an li. So in this case, that would apply to the second li below:
<li>
<li>foo</li>
<li>
However, in your example, the nested lists are not inside an li, but instead by themselves, so they are not the children of any li.
In your HTML, LIs are not getting nested in the LIs (they are not within each other - <li><li>...</li></li>. Hence, the styling of. li li {...} won't work at all.
The way your HTML is, it is nesting ULs. Hence, ul ul {...} styling will work.
Remember, in CSS to make li li work they should be nested within each other otherwise CSS won't work.
I would recommend just creating classes like .green .red .blue .purple and adding those classes to the <li> tags, because it has better re-usability.
I would recommend you to go trough the essentials of HTML5 again & work on your style of coding.
P.S Regarding your problem, here's another Stack that explains how to properly nest lists.

CSS Child Selector (>) not working with certain properties

When I'm trying to select all direct child of a parent element using ">", it works with some properties like border and all, but not with font-properties like color, font-weight etc..
My HTML is
<ul>
<li>Item 1</li>
<li>
<ol>
<li>Subitem 2A</li>
<li>Subitem 2B</li>
</ol>
</li>
</ul>
CASE1 CSS:
ul>li {
color:#F00;
}
But here the color:#F00 property gets applied to all the "li" elements, But i want it to get applied only for the direct "li"s of "ul".
CASE 2
CSS:
ul>li {
border: solid 1px #000;
}
This one works well for me and the border gets applied only to the direct li child only.
I know it can be resolved by overriding with some other classes and all. But i want to know, why some css properties get inherited and others not.
It's happening due to the default inheritance capability of certain CSS Properties. Values of these kind of properties will be transmitted to the child by default.
This document from W3C gives detailed list of inheritance in various CSS properties. Full property table
try this
Demo
<ul>
<li>Item 1</li>
<li>
<ol>
<li>Subitem 2A</li>
<li>Subitem 2B</li>
</ol>
</li>
</ul>
css
ul > li {
color:#F00;
}
ul > li > ol > li {
color:#000;
}
try this
ul > li ol li {color:black;}
As the listing element has been inheriting the color property from its parent, you need to override it.
You can add below style before yours as like
li {
color: #000;
}
ul>li {
color:#F00;
}
It overrides the color: inherit value.
I think you might find the answer you need here: http://www.w3schools.com/cssref/sel_firstchild.asp
You should be able to select these elements with
ul:first-child {
// css
}
Hope this helps

CSS - hover question

I was wondering how can I keep my main parent category highlighted as when hovered on when viewing the main parents sub categories using CSS?
A quick example or tutorial will help thanks.
Your CSS would look something kind of like this:
.highlighted, a:hover {
/* styles for when the category is hovered or highlighted */
}
Then when viewing the subcategories you need to add the "highlighted" CSS class to the element that represents the parent category. How exactly you do this depends on how your website works, but it could be done with javascript or with server-side code.
EDIT 1: Yes, this can be done with just CSS, but it probably requires a lot of manual labor. If your website is just a bunch of static HTML files you could go in and edit each of them to highlight the parent class. For example, on the page entitled "Sedans" (a subcategory of cars) you could change
<div class="category">Cars</div>
to
<div class="category highlighted">Cars</div>
There should be nothing surprising or special about that to you.
You can use the code from CSS play 1 or CSS play 2 for this.
Each of examples meets your needs.
Main idea is to use pseudo-class for the base class:
#menu li a:hover {border:0; text-decoration:underline;}
#menu li:hover dd, #menu li a:hover dd {display:block;}
#menu li:hover dl, #menu li a:hover dl {padding-bottom:15px;}
#menu li:hover dt a, #menu li a:hover dt a, #menu dd a:hover {color:#c00;}
http://jsfiddle.net/axCPq/
CSS:
.main-parent:hover a.parent { color: green; }
.child-ul a:hover { color: green; }
HTML:
<ul class="main-parent">
<li><a class="parent" href="#">Link Parent</a>
<ul class="child-ul">
<li>Link Child</li>
<li>Link Child</li>
<li>Link Child</li>
<li>Link Child</li>
<li>Link Child</li>
<li>Link Child</li>
</ul>
</li>
</ul>

Why does CSS not allow me to nest selector blocks? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm just trying to create another dropdown menu effect within a dropdown menu.
Observe:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="javascript/class-lib.js"></script>
<script type="text/javascript" src="javascript/script.js"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
<div id="wrapper">
<ul id="nav">
<li>Home</li>
<li>Parent 02
<ul>
<li>Item 01</li>
<li>Item 02</li>
<li>Item 03</li>
</ul>
<div class="clear"></div> <!--".clear" div is nested within the .selected class, outside of the <ul>. Does this provide a buffer??? -->
</li>
<li>Parent 03
<ul>
<li><a name="child" href="#">Child 04</a>
<ul>
<li>Item 01</li>
<li>Item 02</li>
<li>Item 03</li>
</ul>
</li>
<li>Item 05</li>
<li>Item 06</li>
<li>Item 07</li>
</ul>
<div class="clear"></div>
</li>
<li>Parent 04</li>
</ul>
<div class="clear"></div>
</div>
</body>
</html>>
CSS:
#nav li ul li a:hover{
#nav li ul li ul li a{
visibility:visible; /*<-- the only reason why I did that was to see if something like this would actually work. It doesn't. I gotta say I'm really not a fan of this language. While I'm sure there were reasons for not implementing this kind of method and design/scripting pattern, it seems like there are just as well plenty reasons TO implement it. */
}
}
#nav li ul li ul{
display:block;
list-style:none;
}
#nav li ul li ul li{
float:right;
clear:both;
width:50px;
height:100px;
background:#000;
}
#nav li ul li ul li a{
visibility:hidden;
color:#fff;
}
The only reason why I did that was to see if something like this would actually work. It doesn't. I gotta say I'm really not a fan of this language. While I'm sure there were reasons for not implementing this kind of method and design/scripting pattern, it seems like there are just as well plenty reasons TO implement it.
Why does CSS not allow me to nest selector blocks?
Instead of doing:
#nav li ul li a:hover{
#nav li ul li ul li a{
visibility:visible;
}
}
It should be:
#nav li ul li:hover ul li a
{
visibility:visible;
}
You can't nest statements. It's just not the right use for CSS.
From Wikipedia:
Cascading Style Sheets (CSS) is a
style sheet language used to describe
the presentation semantics (the look
and formatting) of a document written
in a markup language. Its most common
application is to style web pages
written in HTML and XHTML, but the
language can also be applied to any
kind of XML document, including plain
XML, SVG and XUL.
CSS isn't a scripting language like JavaScript, so it doesn't behave like one. It just tells the browser what to display and how to display it. That's just the main purpose of it.
There are ways, though, to do what you want in pure CSS. While you can't nest rule declarations, you can still apply them in nifty ways:
element subelement {
display: none;
}
element:hover subelement {
display: block;
}
That's the basic logic behind a dropdown menu in pure CSS. Think of :hover as a thing which adds a class to the element being hovered and work from there.
If you want a full tutorial, here's a promising one: http://csswizardry.com/2011/02/creating-a-pure-css-dropdown-menu/
Other people have shown you how to fix the problem, but you shouldn't really be doing it that way anyways; although it is a nice and clean way to create menus, it crosses the boundaries in the content-presentation-behaviour rule. Although it may not matter much, the code that drops down menus belongs in JavaScript.

CSS selectors: (menu ul li) or (menu li)

which is better for use
.menu{
float:left;
width:600px;
height:25px;
background:url(bg.png) repeat-x;
}
.menu ul{
float:left;
}
.menu ul li{
float:left;
width:150px;
height:25px;
background:#F00;
}
or
.menu{
float:left;
width:600px;
height:25px;
background:url(bg.png) repeat-x;
}
.menu ul{
float:left;
}
.menu li{
float:left;
width:150px;
height:25px;
background:#F00;
}
which tag is right menu ul li or menu li?
When you say which tag is right menu ul li or menu li?, are you talking about a div with class="menu" or are you talking about the deprecated menu tag (<menu>)?
If you are just talking about your css code, those are not tags, they are selectors. And I'd go with the most specific selector available in order to avoid accidental assignments
.menu > ul > li{
// this matches only list items directly inside a ul directly inside a .menu
}
even better would be this:
#menu > ul > li{
// now you are referencing the menu by id, so you know this is a unique assignment
}
or, if you have multiple menus:
#menubar > .menu > ul > li{
}
because otherwise you are in for surprises, you might actually have a structure like this:
(this is ugly, I know, but just to prove a point)
<div class="menu">
<ul>
<li>Menu Item 1</li>
<li>Menu Item 2</li>
<li>Menu Item 3
<ul>
<li id="abc">Menu Item abc</li>
</ul>
</li>
<li>Menu Item 4
<div><div><div><ol><li><div><ul>
<li id="xyz">Menu Item xyz</li>
</ul></div></li></ol></div></div></div>
</li>
</ul>
</div>
(you probably don't want to match items abc or xyz).
It makes no difference until you have to interact with other, similar selectors in the same stylesheet — and then it depends on what those selectors are.
It depends. If you've got an ol and a ul within .menu you'll want to use the more specific .menu ul li. Otherwise, .menu li is fine. You might like to read up on CSS specifity.
Unless you're going to also have ordered lists (<ol>) inside .menu containers, the result is exactly the same. Some will probably say one is faster than the other, but that is irrelevant (and hard to prove as it may differ in every browser)
Your selectors should match your intent - if you mean for any list item, regardless of whether it's inside a UL or OL to be styled the same, then example B. If it's only UL LI's you want to style, then A.
This is a fairly simple example, but this is a useful rule of thumb. Ask yourself "If someone came and stuck an ordered list inside .menu, how would I want it to look?
It's a great way to keep your CSS to just the right level of specificity, while maintaining flexibility in the HTML structure it can apply to.
Mozilla Devcenter recommend to use .menu li. You can red more about Writing Efficient CSS and optimizing css code. Personally, I use <ul id='menu'> and then #menu { display: block; margin: 0; padding: 0 }.