How to apply special style to the element whose first sibling is an UL?

In the code below, I want to place a down arrow to indicate where a menu has child notes. Any ideas how I can do that?

I tried this to no avail…

.menu.top.cat a + ul {background:red;}

	<div class="menu top cat">
		<ul id="menu-my-main-menu" class="menu"><li id="menu-item-12"><a href="site">Home</a></li> 
			<li id="menu-item-13" class="menu-item"><a href="category/services/">Services</a> 
				<ul class="sub-menu"> 
					<li id="menu-item-18" class="menu-item"><a href="category/services/expert-answers/">Expert Answers</a></li> 
					<li id="menu-item-19" class="menu-item"><a href="category/services/our-specials/">Our Specials</a></li> 
				</ul> 
			</li> 
		</ul>
	<div>

Hi,
That is the “adjacent sibling selector” your using there. It would be styling the UL if it was the next sibling to that div.

As your html is now the UL is a child of the div. Are you wanting to the arrow on the div or the UL.

You have an ID on that menu so it can only be used on the page once anyways, you might consider that as a reason to just style that UL itself.

You could use the child selector but it can be buggy in IE7. It will target the immediate child of an element.

.menu.top.cat>ul {background:red;}

There was an “a” in the example you gave, I assume that was just a typo.

Something I do on occassion to get around using the child selector is to apply the child with a descendant selector (a space), then cancelling it for the next level. Such as:


.menu.top.cat ul { background: red; }
.menu.top.cat ul ul { background: none; }

This isn’t the greatest way to do it, but it does get around <=IE7’s buggy-ness with the child selector. An alternative would be to use the child selector, and then use an alternative in an IE-only style sheet (if the rule was important enough).

That will style the ul that is the actual menu and not the parent that contains the menu. There isn’t a css property called :contains but it was proposed and dropped I believe.

If you can’t use IDs or classes as others have mentioned you may be able to cheat and apply an image to the nested ul itself but pull the image into view in the line above.

This means that the image will only be applied where a submenu is present because its applied to the submenu.

Only for modern browsers though (ie8+)
e.g.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
.menu.top.cat a + ul:before {
    content:" v ";
    position:absolute;
    background:red;
    margin:-1.2em 0 0 1em;
}
</style>
</head>
<body>
<div class="menu top cat">
    <ul id="menu-my-main-menu" class="menu">
        <li id="menu-item-12"><a href="site">Home</a></li>
        <li id="menu-item-13" class="menu-item"><a href="category/services/">Services</a>
            <ul class="sub-menu">
                <li id="menu-item-18" class="menu-item"><a href="category/services/expert-answers/">Expert Answers</a></li>
                <li id="menu-item-19" class="menu-item"><a href="category/services/our-specials/">Our Specials</a></li>
            </ul>
        </li>
    </ul>
</div>
</body>
</html>


Of course it does depend on how you have hidden the submenu to start with (if indeed you are hiding it). I don’t really know if it will be usable in a real situation.

I assume you were looking for something automatic otherwise for good browsers you could use nth-of type (or nth-child) to select the exact element you need.

The child selector methods mentioned in previous posts will just select elements that are a direct child of the parent but that doesn’t take into account whether that item has a submenu or not :slight_smile:

If the container of the sub-menu (the containing LI e.g. your #ID menu-item-13) only has the one sub menu and one <a> tag you could simply use the general sibling selector ~ like

.menu.top.cat ul ~ a{background:red;}

(note a and ul switched around)

From what I can see of how you’re structuring the menu this might work?

Thanks for all the helpful responses. I’m on a client deadline today but I wanted to check in to let you know I really appreciate the help and I’ll be testing the suggestions later today.

(If my suggestion fits just use the :after or :before property to add the arrow suggested by Paul O’B)

.menu.top.cat ul ~ a:after{
content:" v ";
background:red;
}

Good try but the sibling selector selects siblings and not children so the above would not match the required construct I’m afraid. :slight_smile:

e.g.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
ul ~ a {
background:red;
}
</style>
</head>
<body>
<ul>
    <li><a href="#">I am not red</a>
        <ul>
            <li>test</li>
        </ul>
    </li>
</ul>
<a href="#">I am red because I match</a>
</body>
</html>

Fair dinkum it doesn’t work, and I should read the sitepoint reference more carefully.

Though in light of this feel ‘sibling’ ought to be renamed ‘subsequent-sibling’ (or something less wordy but accurate) - I didn’t finish my comp sci degree but know enough about trees to know that ought to have…

(since the UL and A in question most certainly are siblings and not parent/child)

If you can’t use IDs or classes as others have mentioned you may be able to cheat and apply an image to the nested ul itself but pull the image into view in the line above.

Rather than cheating :), you could also just utilize the existing class (menu-item) that is on the LI with the sub-ul. That keeps it’s location where it actually is.

I had to use some overrides because that same class was on the sub-ul li’s, I don’t see what they are good for so they could more than likely be removed.

Though I could be missing what the goal is


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<style type=text/css>
[COLOR=Blue]li.menu-item[/COLOR] {
    list-style:none;
}
a {text-decoration:none;}

.menu.top.cat [COLOR=Blue]li.menu-item:before[/COLOR] {
    content:" v ";
    display:inline-block;
    background:red;
    margin:0 .4em 0 -.9em;
}
.menu.top.cat [COLOR=DarkGreen]li li.menu-item[/COLOR] {list-style:disc}
.menu.top.cat [COLOR=DarkGreen]li li.menu-item:before[/COLOR] {display:none}
</style>

</head>
<body>

<div class="menu top cat">
    <ul id="menu-my-main-menu" class="menu">
        <li id="menu-item-12"><a href="site">Home</a></li>
        <li id="menu-item-13" [COLOR=Blue]class="menu-item"[/COLOR]><a href="category/services/">Services</a>
            <ul class="sub-menu">
                <li id="menu-item-18" [COLOR=DarkGreen]class="menu-item"[/COLOR]><a href="category/services/expert-answers/">Expert Answers</a></li>
                <li id="menu-item-19" [COLOR=DarkGreen]class="menu-item"[/COLOR]><a href="category/services/our-specials/">Our Specials</a></li>
            </ul>
        </li>
    </ul>
</div>
</body>
</html>

If I had that many classes and ID’s in a menu I’d put a bullet through my head – lemme guess, turdpress?

Here’s a tip - classes should be used when elements are DIFFERENT, not when they are all the same… if you are resorting to classes like “top” and “cat”, you’re practicing presentational markup, so welcome to 1997.

… and 99% of the time if you have a div around the UL for a menu, you’re just wasting code… and since you are unlikely to be indexing menu entries with # in an anchor – and since I doubt you are targeting each of those ID’s in a unique manner in the CSS, I very much doubt those ID’s need to be in there either.

If you need much more markup than this:


<ul id="mainMenu">
	<li><a href="/">Home</a></li> 
	<li class="hasKids">
		<a href="category/services/">Services</a> 
		<ul> 
			<li><a href="category/services/expert-answers/">Expert Answers</a></li> 
			<li><a href="category/services/our-specials/">Our Specials</a></li> 
		</ul> 
	</li> 
</ul>

You’re probably going about it ALL WRONG… though without a link to a live copy and/or the CSS being applied to that, it’s hard to say one way or the other.

Yes that would be the easiest way of course :slight_smile:

I was just assuming that there would be no identifying class and you had to identify the element by the fact that it contains a sub menu. Which of course isn’t possible in CSS - hence the cheat :wink:

It would have made a good quiz.

I agree with Jason and wordpress really goes to down on those classes and it actually seems to make things harder.

As an aside I wouldn’t be surprised if it doesn’t auto generate a “haschild” class anyway by default that could be used. Not that I’ve ever used wordpress though.

By default Wordpress does generate a lot of junk classes. I use the menu system a lot, but I always use a custom action and/or filter (depending what exactly I’m doing) to clean them up. With a little clean-up they become exceedingly useful (especially if the one using the menu isn’t a tech person).