Is there a CSS parent selector? (ok)

https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector

Đã ok

<!doctype html>
<html>
	<head>
		<title></title>
		<style>
/* accessory */
.parent {
	width: 200px;
	height: 200px;
	background: gray;
}
.parent, 
.selector {
	display: flex;
	justify-content: center;
	align-items: center;
}
.selector {
	cursor: pointer;
	background: silver;
	width: 50%;
	height: 50%;
}
		</style>
		<style>
/* pertinent */
.parent {
	background: gray;
	pointer-events: none;
}
.parent:hover {
	background: fuchsia;
}
.parent 
.selector {
	pointer-events: auto;
}
		</style>
	</head>
	<body>
		<div class="parent">
			<div class="selector"></div>
		</div>
	</body>
</html>

Ask Questionarrow-up-rightAsked 11 years agoActive 2 days agoarrow-up-rightViewed 2.1m times3212467

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

As an example, my CSS would be something like this:

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?cssarrow-up-right css-selectorsarrow-up-rightsharearrow-up-right improve this questionarrow-up-right follow edited Jul 24 '19 at 22:14arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesasked Jun 18 '09 at 19:59arrow-up-rightjcuenodarrow-up-right45k1212 gold badges5757 silver badges9494 bronze badges

  • This question is over a decade old, but if anyone is interested in a way to do this on individual clients (not on a server), I can provide an answer. Just let me know. Please remember that my answer will not work on servers, and thus will not satisfy the most common need. – RockPaperLizardarrow-up-right Jun 10 at 10:17arrow-up-right

add a commentarrow-up-right

33 Answers

Activearrow-up-rightOldestarrow-up-rightVotesarrow-up-right12arrow-up-rightNextarrow-up-right25655

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:

That said, the Selectors Level 4 Working Draftarrow-up-right includes a :has() pseudo-class that will provide this capability. It will be similar to the jQuery implementationarrow-up-right.

However, as of May 2020, this is still not supported by any browserarrow-up-right.

In the meantime, you'll have to resort to JavaScript if you need to select a parent element.sharearrow-up-right improve this answerarrow-up-right follow edited May 10 at 19:52arrow-up-rightarrow-up-rightRoman Pushkinarrow-up-right4,51911 gold badge2929 silver badges4848 bronze badgesanswered Jun 18 '09 at 20:16arrow-up-rightDan Herbertarrow-up-right85.8k4343 gold badges170170 silver badges215215 bronze badges

show 34 more commentsarrow-up-right155

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

But as you already seem to have an .active class, it would 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.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:21arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Jun 18 '09 at 20:08arrow-up-rightjeroenarrow-up-right86.9k2020 gold badges104104 silver badges126126 bronze badges

  • 4You can't shift the pseudo selector to the list item, as it is not a focusable element. He's using the :active selector, so when the anchor is active he wants the list item to be affected. List items will never be in the active state. As an aside, it's unfortunate that such a selector doesn't exist. Getting a pure CSS menu to be fully keyboard accessible seems to be impossible without it (using sibling selectors you can make submenus created using nested lists to appear, but once the list gains focus it becomes hidden again). If there are any CSS-only solutions to this particular conun – user914183 Aug 26 '11 at 13:46arrow-up-right

  • 13@Dominic Aquilina Take a look at the question, the OP is using a class, not a pseudo selector. – jeroenarrow-up-right Aug 26 '11 at 14:34arrow-up-right

add a commentarrow-up-right1291

You can use this scriptarrow-up-right:

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:

Or select it when it's active:

Check out this HTML:

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

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

BTW, it works in Internet Explorer.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:24arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Aug 13 '11 at 10:13arrow-up-rightIderedarrow-up-right1,68711 gold badge1515 silver badges1818 bronze badges

show 2 more commentsarrow-up-right1101

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 jQueryarrow-up-right:

sharearrow-up-right improve this answerarrow-up-right follow edited May 2 '13 at 5:11arrow-up-rightarrow-up-rightAlastairarrow-up-right6,15333 gold badges3232 silver badges2929 bronze badgesanswered Dec 14 '09 at 14:51arrow-up-rightzcrar70arrow-up-right2,89022 gold badges2020 silver badges1616 bronze badges

add a commentarrow-up-right1025

Yes: :has()arrow-up-right

Browser support: nonearrow-up-rightsharearrow-up-right improve this answerarrow-up-right follow edited Jun 10 at 10:20arrow-up-rightarrow-up-rightRockPaperLizardarrow-up-right3,80155 gold badges2626 silver badges5252 bronze badgesanswered Jan 20 '18 at 20:22arrow-up-rightYukuléléarrow-up-right9,63888 gold badges4646 silver badges7171 bronze badgesadd a commentarrow-up-right71

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:

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.

The article Why we don't have a parent selectorarrow-up-right explains it in detail.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:29arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Jan 21 '14 at 8:43arrow-up-rightSalman Aarrow-up-right217k7676 gold badges379379 silver badges475475 bronze badges

add a commentarrow-up-right57

There isn't a way to do this in CSS 2. You could add the class to the li and reference the a:

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:19arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Jun 18 '09 at 20:06arrow-up-rightJosharrow-up-right5,80011 gold badge3131 silver badges5454 bronze badges

add a commentarrow-up-right37

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

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:25arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Nov 23 '11 at 9:03arrow-up-rightRasekoarrow-up-right37933 silver badges33 bronze badgesadd a commentarrow-up-right30

The CSS selector “General Sibling Combinatorarrow-up-right” could maybe used for what you want:

This matches any F element that is preceded by an E element.sharearrow-up-right improve this answerarrow-up-right follow edited Aug 23 '17 at 12:27arrow-up-rightarrow-up-rightCody Grayarrow-up-right♦212k4040 gold badges437437 silver badges513513 bronze badgesanswered Jun 30 '11 at 14:00arrow-up-rightcobaastaarrow-up-right56544 silver badges22 bronze badges

add a commentarrow-up-right26

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.sharearrow-up-right improve this answerarrow-up-right follow answered Jun 18 '09 at 20:09arrow-up-rightMark Hurdarrow-up-right12.3k22 gold badges2323 silver badges2828 bronze badgesadd a commentarrow-up-right24

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:

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):

sharearrow-up-right improve this answerarrow-up-right follow answered May 16 '13 at 22:04arrow-up-rightDavid Clarkearrow-up-right11.4k88 gold badges7777 silver badges100100 bronze badges

  • 3Or use $yourSpan.closest("ul") and you'll get the parent UL of your span element. Nevertheless your answer is completely offtopic imho. We can answer all of the CSS-taged questions with a jQuery solution. – Robin van Baalenarrow-up-right Jul 18 '13 at 17:40arrow-up-right

  • 1As identified in other answers, there is no way to do this using CSS 2. Given that constraint, the answer I provided is one I know is effective and is the simplest way to answer the question using javascript imho. – David Clarkearrow-up-right Dec 19 '15 at 19:27arrow-up-right

  • Given your upvotes, some people agree with you. But the only answer remains the accepted one; plain and simple "it cant be done the way you want it". If the question is how to archieve 60mph on a bicycle and you answer it with "simple; get in a car and hit the gas.", it's still not an answer. Hence my comment. – Robin van Baalenarrow-up-right Dec 19 '15 at 19:36arrow-up-right

  • 1That approach would make SO almost completely useless. I search SO for how to solve problems, not to find the "only answer" doesn't address the issue. That is why SO is so awesome, because there is always more than one way to skin a cat. – David Clarkearrow-up-right Dec 20 '15 at 18:35arrow-up-right

add a commentarrow-up-right24

The pseudo element :focus-within allows a parent to be selected if a descendent has focus.

An element can be focused if it has a tabindex attribute.

Browser support for focus-withinarrow-up-right

Tabindexarrow-up-right

Example

Run code snippetExpand snippet

sharearrow-up-right improve this answerarrow-up-right follow edited Mar 20 '18 at 13:36arrow-up-rightarrow-up-rightroberrrt-sarrow-up-right6,8343636 silver badges5050 bronze badgesanswered Sep 25 '17 at 13:55arrow-up-rightsolarrow-up-right17.6k55 gold badges2525 silver badges3939 bronze badges

  • 2This works fine in my case, thanks! Just a not, the example would be more ilustrative if you change the color to the parent, not to the sibling, this is replace .color:focus-within .change with .color:focus-within. In my case i'm using bootstrap nav-bar that add the class to the children when active and I want to add a class to the parent .nav-bar. I think this is a pretty common scenario where I own the markup but the component css+js is bootstrap (or other) so I cannot change the behavior. Although I can add tabindex and use this css. Thanks! – cancerberoarrow-up-right Jun 29 '18 at 15:13arrow-up-right

add a commentarrow-up-right22

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

For example:

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

But we have to wait for browsers' implementation :(sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:33arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered May 5 '15 at 18:24arrow-up-rightMarco Alloriarrow-up-right2,7682727 silver badges2222 bronze badgesadd a commentarrow-up-right21

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

This way you can change the style in multiple inner tags, based on the rollover of the parent element.sharearrow-up-right improve this answerarrow-up-right follow edited Apr 15 at 21:17arrow-up-rightarrow-up-rightTylerHarrow-up-right18k1212 gold badges5959 silver badges7777 bronze badgesanswered Feb 13 '12 at 11:22arrow-up-rightriverstormarrow-up-right49233 silver badges77 bronze badges

add a commentarrow-up-right14

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 evaluatedarrow-up-right.

Chris Coyier on the talks of Parent selectorarrow-up-right.

Harry Roberts again on writing efficient CSS selectorsarrow-up-right.

But Nicole Sullivan has some interesting facts on positive trendsarrow-up-right.

These people are all top class in the field of front end development.sharearrow-up-right improve this answerarrow-up-right follow edited Nov 2 '17 at 0:38arrow-up-rightarrow-up-rightNathan Tuggyarrow-up-right2,24299 gold badges2727 silver badges3636 bronze badgesanswered Mar 21 '14 at 12:58arrow-up-rightSuraj Naikarrow-up-right50344 silver badges77 bronze badges

add a commentarrow-up-right14

Just an idea for horizontal menu...

Part of HTML

Part of CSS

Updated demo and the rest of codearrow-up-right

Another examplearrow-up-right how to use it with text-inputs - select parent fieldsetsharearrow-up-right improve this answerarrow-up-right follow edited Jun 20 at 9:12arrow-up-rightarrow-up-rightCommunityarrow-up-right♦111 silver badgeanswered Oct 27 '15 at 17:55arrow-up-rightIlya B.arrow-up-right87277 silver badges1313 bronze badges

add a commentarrow-up-right141

Here's a hack using pointer-events with hover:

Run code snippetExpand snippet

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 26 '19 at 1:59arrow-up-rightanswered Jul 31 '18 at 22:47arrow-up-rightJan Kyu Peblikarrow-up-right94088 silver badges1414 bronze badgesadd a commentarrow-up-right12

There's a plugin that extends CSS to include some non-standard features that can really help when designing websites. It's called EQCSSarrow-up-right.

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

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 $parentarrow-up-right and another $parent demo that works in Internet Explorer 8arrow-up-right, as well as a screenshot in case you don't have Internet Explorer 8 around to test witharrow-up-right.

EQCSS also includes meta-selectorsarrow-up-right: $prev for the element before a selected element and $this for only those elements that match an element query, and more.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:43arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Apr 7 '16 at 17:52arrow-up-rightinnovatiarrow-up-right49111 gold badge77 silver badges1212 bronze badgesadd a commentarrow-up-right11

It's now 2019, and the latest draft of the CSS Nesting Modulearrow-up-right actually has something like this. Introducing @nest at-rules.

3.2. The Nesting At-Rule: @nest

While direct nesting looks nice, it is somewhat fragile. Some valid nesting selectors, like .foo &, are disallowed, and editing the selector in certain ways can make the rule invalid unexpectedly. As well, some people find the nesting challenging to distinguish visually from the surrounding declarations.

To aid in all these issues, this specification defines the @nest rule, which imposes fewer restrictions on how to validly nest style rules. Its syntax is:

@nest = @nest <selector> { <declaration-list> }

The @nest rule functions identically to a style rule: it starts with a selector, and contains declarations that apply to the elements the selector matches. The only difference is that the selector used in a @nest rule must be nest-containing, which means it contains a nesting selector in it somewhere. A list of selectors is nest-containing if all of its individual complex selectors are nest-containing.

(Copy and pasted from the URL above).

Example of valid selectors under this specification:

sharearrow-up-right improve this answerarrow-up-right follow edited Jun 20 at 9:12arrow-up-rightarrow-up-rightCommunityarrow-up-right♦111 silver badgeanswered Mar 19 '19 at 14:14arrow-up-rightroberrrt-sarrow-up-right6,8343636 silver badges5050 bronze badgesadd a commentarrow-up-right10

Technically there is no direct way to do this. However, you can sort that out with either jQuery or JavaScript.

However, you can do something like this as well.

jQuery

If you want to achieve this using jQuery here is the reference for the jQuery parent selectorarrow-up-right.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:36arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Oct 14 '15 at 10:08arrow-up-rightPrabhakar Undurthiarrow-up-right5,29011 gold badge3434 silver badges4242 bronze badgesadd a commentarrow-up-right9

The W3C excluded such a selector because of the huge performance impact it would have on a browser.sharearrow-up-right improve this answerarrow-up-right follow answered Aug 16 '11 at 4:43arrow-up-rightrgbarrow-up-right1,04811 gold badge99 silver badges1212 bronze badges

add a commentarrow-up-right9

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

Or a shorter way if you use jQuery in your application:

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:45arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Jun 16 '17 at 18:06arrow-up-rightAlirezaarrow-up-right73.7k1818 gold badges223223 silver badges145145 bronze badgesadd a commentarrow-up-right5

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.htmlarrow-up-right

(compare the two lists on the left styled with standard selectors and the two lists on the right styled with axe selectors)sharearrow-up-right improve this answerarrow-up-right follow edited Feb 18 '17 at 17:19arrow-up-rightanswered Feb 18 '17 at 17:06arrow-up-rightRouninarrow-up-right17.3k33 gold badges3838 silver badges5757 bronze badges

  • 3The project is in an early Beta stage at present. You can (at least currently) activate axe selectors in your CSS styles by including <script src="https://rouninmedia.github.io/axe/axe.js"></script> at the very end of your html document, just before </body>. – Rouninarrow-up-right Jul 12 '17 at 16:40arrow-up-right

add a commentarrow-up-right4

At least up to and including CSS 3 you cannot select like that. But it can be done pretty easily nowadays in JavaScript, you just need to add a bit of vanilla JavaScript, notice that the code is pretty short.

Run code snippetExpand snippet

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:50arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Feb 1 '18 at 14:18arrow-up-rightEduard Florinescuarrow-up-right11.7k2525 gold badges9393 silver badges158158 bronze badgesadd a commentarrow-up-right4

Any ideas?

CSS 4 will be fancy if it adds some hooks into walking backwards. Till then it is possible (though not advisable) to use checkbox and/or radio inputs to break the usual way that things are connected, and through that also allow CSS to operate outside of its normal scope...

Run code snippetExpand snippet

... pretty gross, but with just CSS and HTML it is possible to touch and re-touch anything but the body and :root from just about anywhere by linking the id and for properties of radio/checkbox inputs and label triggers; likely someone'll show how to re-touch those at some point.

One additional caveat is that only one input of a specific id maybe used, first checkbox/radio wins a toggled state in other words... But multiple labels can all point to the same input, though that would make both the HTML and CSS look even grosser.

... I'm hoping that there is some sort of workaround that exists native to CSS Level 2...

I am not sure about the other : selectors, but I :checked for pre-CSS 3. If I remember correctly, it was something like [checked] which is why you may find it in the above code, for example,

... but for things like ::after and :hover, I'm not at all certain in which CSS version those first appeared.

That all stated, please don't ever use this in production, not even in anger. As a joke sure, or in other words just because something can be done does not always mean it should.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 23:02arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Jun 8 '19 at 6:31arrow-up-rightS0AndS0arrow-up-right57111 gold badge44 silver badges1111 bronze badgesadd a commentarrow-up-right3

No, you cannot select the parent in CSS only.

But as you already seem to have an .active class, it would 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.sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:40arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Nov 27 '15 at 21:16arrow-up-rightGaurav Aggarwalarrow-up-right8,34055 gold badges2323 silver badges5757 bronze badgesadd a commentarrow-up-right1

Changing parent element based on child element can currently only happen when we have an <input> element inside the parent element. When an input gets focus, its corresponding parent element can get affected using CSS.

Following example will help you understand using :focus-within in CSS.

Run code snippetExpand snippet

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 7 '19 at 0:56arrow-up-rightarrow-up-rightVFDanarrow-up-right74566 silver badges2222 bronze badgesanswered Jul 5 '19 at 6:34arrow-up-rightSethuramanarrow-up-right52033 silver badges1313 bronze badgesadd a commentarrow-up-right1

It's possible with ampersand in Sassarrow-up-right:

CSS output:

sharearrow-up-right improve this answerarrow-up-right follow edited Jul 24 '19 at 22:47arrow-up-rightarrow-up-rightPeter Mortensenarrow-up-right26.2k2121 gold badges9090 silver badges120120 bronze badgesanswered Aug 3 '17 at 18:19arrow-up-rightRodolfo Jorge Nemer Nogueiraarrow-up-right3,87922 gold badges2828 silver badges2626 bronze badges

add a commentarrow-up-right1

I'd hire some JavaScript code to do that. For example, in React when you iterate over an array, add another class to the parent component, which indicates it contains your children:

And then simply:

sharearrow-up-right improve this answerarrow-up-right follow edited Jan 2 at 15:41arrow-up-rightanswered Jun 13 '19 at 8:25arrow-up-rightDamianoarrow-up-right87422 gold badges1010 silver badges2222 bronze badgesadd a commentarrow-up-right0

There no css (and therefore in css preprocessors) parent selector due to "The major reasons for the CSS Working Group previously rejecting proposals for parent selectors are related to browser performance and incremental rendering issues."sharearrow-up-right improve this answerarrow-up-right follow

Last updated

Was this helpful?