Is there a CSS parent selector?

    |
  • Added:
  • |
  • In: Wordpress

How do I select the <li> element that is a direct parent of the anchor element?

In example my CSS would be something like this:

li < a.active { property: value; } 

Obviously there are ways of doing this with JavaScript but I'm hoping that there is some sort of workaround that exists native to CSS Level 2.

The menu that I am trying to style is being spewed out by a CMS so I can't move the active element to the <li> element... (unless I theme the menu creation module which I'd rather not do).

Any ideas?

This Question Has 23 Answeres | Orginal Question | jcuenod

Has somebody suggested something like this? Just an idea for horizontal menu...

part of HTML

<div class='list'> <div class='item'> <a>Link</a> </div> <div class='parent-background'></div> <!-- submenu takes this place --> </div> 

part of CSS

/* hide parent backgrounds... */ .parent-background { display: none; } /* ... and show it when hover on children */ .item:hover + .parent-background { display: block; position: absolute; z-index: 10; top: 0; width: 100%; } 

Updated demo and the rest of code

Another example how to use it with text-inputs - select parent fieldset

You might try to use hyperlink as the parent, and then change the inner elements on hover. Like this:

a.active h1 {color:red;} a.active:hover h1 {color:green;} a.active h2 {color:blue;} a.active:hover h1 {color:yellow;} 

This way you can change the style in multiple inner tags, based on the rollover of the parent element.

No you cannot select the parent in css only.

But as you already seem to have an .active class, wouldn´t it be easier to move that class to the li (instead of the a)? That way you can access both the li and the a via css only.

Short answer is NO, we don't have a parent selector at this stage in CSS, but if you don't have anyway to swap the elements or classes, the second option is using JavaScript, something like this:

var activeATag = Array.prototype.slice.call(document.querySelectorAll('a.active')); activeATag.map(function(x) { if(x.parentNode.tagName === 'LI') { x.parentNode.style.color = 'red'; //your property: value; } }); 

or a Shorter way if you use jQuery in your application:

$('a.active').parents('li').css('color', 'red'); //your property: value; 

Technically there is no direct way to do this however, you can sort that with either jquery or javascript.

Howeve,r you can do something like this as well.

a.active h1 {color:blue;} a.active p {color: green;} 

jQuery

$("a.active").parents('li').css("property", "value"); 

If you want to achieve this using jQuery here is the reference for jQuery parent selector

Try to switch a to block display, and then use any style you want. a element will fill li element and you will be able to modify it's look as you want. Don't forget to set li padding to 0.

li { padding: 0; overflow: hidden; } a { display: block; width: 100%; color: ..., background: ..., border-radius: ..., etc... } a.active { color: ..., background: ... } 

Not in CSS 2 as far as I'm aware. CSS 3 has more robust selectors but is not consistently implemented across all browsers. Even with the improved selectors, I don't believe it will accomplish exactly what you've specified in your example.

there isn't a way to do this in css2. you could add the class to the li and reference the a

li.active > a { property: value; } 

There's a plugin that extends CSS to include some non-standard features that can really help when designing websites. It's called EQCSS, and you can find it at http://elementqueries.com

One of the things EQCSS adds is a parent selector. It works in all browsers IE8 and up. Here's the format:

@element 'a.active' { $parent { background: red; } } 

So here we've opened an element query on every element a.active, and for the styles inside that query, things like $parent make sense because there's a reference point. The browser can find the parent, because it's very similar to parentNode in JavaScript.

Here's a demo of $parent: http://elementqueries.com/demos/parent.html

Here's a demo that works in IE8: http://staticresource.com/parent.html

(and a screenshot in case you don't have IE8 around to test with: http://i.imgur.com/QyVAj2u.png )

EQCSS also includes meta-selectors $prev for the element before a selected element, $this for only those elements that match an element query, and more.

You can read more about meta-selectors in EQCSS here: http://elementqueries.com/#meta-selectors

Hope this helps!

In CSS, we can cascade to the properties down the hierarchy but not in the oppostite direction. To modify the parent style on child event, probably use jQuery.

$el.closest('.parent').css('prop','value'); 

As mentioned by a couple of others, there isn't a way to style an element's parent/s using just CSS but the following works with jQuery:

$("a.active").parents('li').css("property", "value"); 

The W3C excluded such a selector because of the huge performance impact it would have on a browser.

There is no parent selector; just the way there is no previous sibling selector. One good reason for not having these selectors is because the browser has to traverse through all children of an element to determine whether or not a class should be applied. For example if you wrote:

body:contains-selector(a.active) { background: red; } 

Then the browser will have to wait until it has loaded and parsed everything until the </body> to determine if the page should be red or not.

This article Why we don't have a parent selector explains it in detail.

The CSS selector “General Sibling Combinator” could maybe used for what you want:

E ~ F { property: value; } 

This matches any F element that is preceded by an E element.

Although there is no parent selector in standard CSS at present, I am working on a (personal) project called axe (ie. Augmented CSS Selector Syntax / ACSSSS) which, among its 7 new selectors, includes both:

  1. an immediate parent selector < (which enables the opposite selection to >)
  2. an any ancestor selector ^ (which enables the opposite selection to [SPACE])

axe is presently in a relatively early BETA stage of development.

See a demo here:

http://rounin.co.uk/projects/axe/axe2.html

(compare the two lists on the left styled with standard selectors and the two lists on the right styled with axe selectors)

I don’t think you can select the parent in css only.

But as you already seem to have an .active class, wouldn’t it be easier to move that class to the li (instead of the a)? That way you can access both the li and the a via css only.

I've certainly come across instances when it would be handy, but unfortunately parent selectors do not exist in CSS.

Can you explain more about what you're trying to achieve? There might be another way in to a solution, e.g. move the style to the li, then disable it in a.active or via a child selector.

There is currently no way to select the parent of an element in CSS.

If there was a way to do it, it would be in either of the current CSS selectors specs:

In the meantime, you'll have to resort to JavaScript if you need to select a parent element.


The Selectors Level 4 Working Draft includes a :has() pseudo-class that works the same as the jQuery implementation. As of April 2017, this is still not supported by any browser.

Using :has() the original question could be solved with this:

li:has(> a.active) { /* styles to apply to the li tag */ } 

Currently there is no parent selector & it is not even being discussed in any of the talks of W3C. You need to understand how CSS is evaluated by the browser to actually understand if we need it or not.

There is a lot of technical explanation here.

Jonathan Snook explains how css is evaluated http://snook.ca/archives/html_and_css/css-parent-selectors

Chris Coyier on the talks of Parent selector http://css-tricks.com/parent-selectors-in-css/

Harry Roberts again on writing efficient css selector http://csswizardry.com/2011/09/writing-efficient-css-selectors/

but this lady has some interesting facts http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/

These people are all top class in the field of front end development.

Just as easy help for whom are trying to get rid of this lack of parent selector: the most simple thing are two lines of jQuery.

Let's figure out the situation in which we want to change the class of the <form> element basing on the validation of hinner inputs:

HTML:

<div class="parent-row"> <label>Form 1</label> <input type="text" name="field1" /> <input type="text" class="validation-error" name="field2" /> <input type="text" name="field3" /> </div> 

CSS:

.make-red { color:red } 

JQuery:

if($( "input" ).hasClass( "validation-error" )) { $( ".parent-row" ).addClass( "make-red" ); } 

http://jsfiddle.net/9c3hrn9y/3/

This is the most discussed aspect of the Selectors Level 4 specification. With this selector will be able to style an element according to its child by using an exclamation mark after the given selector (!).

For example:

body! a:hover{ background: red; } 

will set a red background-color if the user hovers over any anchor.

But we have to wait browsers implementation :(

I know the OP was looking for a CSS solution but it is simple to achieve using jQuery. In my case I needed to find the <ul> parent tag for a <span> tag contained in the child <li>. jQuery has the :has selector so it's possible to identify a parent by the children it contains:

$("ul:has(#someId)") 

will select the ul element that has a child element with id someId. Or to answer the original question, something like the following should do the trick (untested):

$("li:has(.active)") 

You can use this script.

*! > input[type=text] { background: #000; } 

This will select any parent of a text input. But wait, there's still much more. If you want, you can select a specified parent:

.input-wrap! > input[type=text] { background: #000; } 

or select it when it's active:

.input-wrap! > input[type=text]:focus { background: #000; } 

Check out this HTML:

<div class="input-wrap"> <input type="text" class="Name"/> <span class="help hide">Your name sir</span> </div> 

you can select that span.help when the input is active and show it:

.input-wrap! .help > input[type=text]:focus { display: block; } 

There are many more capabilities; just check out the documentation of the plugin.

BTW, it works in IE.


Search
I am...

Sajjad Hossain

I have five years of experience in web development sector. I love to do amazing projects and share my knowledge with all.

Connect Social With PHPAns
Top