This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 5 months ago.
Let's say our html structure looks like this:
<div class="parent">
<div class="child"></div>
</div>
Now on some button action I add active className to child's div.
My question is:
How to style only parent element if child's div has active className
// CSS pseudo code //
if(child.has.className('active')
.parent{
background: red;
}
You can use the :has() pseudo class selector, although that's only supported in newer browsers. Otherwise you'll probably need to use JS.
.parent {
background: #ccc;
}
.parent:has(.active) {
background: steelblue;
color: #eee;
}
/* Ignore below, for stylistic purposes only */
.parent {
margin: 1rem;
padding: 1rem;
border-radius: .5rem;
font-family: Arial, sans-serif;
}
<div class="parent">
<div class="child">Child</div>
</div>
<div class="parent">
<div class="child active">Child (active)</div>
</div>
For a JS-based solution there are two ways:
Recommended: in the code that adds the active class, you also toggle a class on the parent, say has-active-child and style it accordingly
Not recommended: listen to class changes on the child node using MutationObserver API and style the parent node
At the moment not all browsers support the pseudo class selector :has() as Terry explained. A JavaScript solution goes as following.
Example from GeeksForGeeks
$('ul li:has(ul.child)').addClass('has_child');
.parent > li > ul > li {
background:orange;
}
.parent > li.has_child {
background:red;
}
.parent li {
background:blue;
color:black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<style>
.parent li {
background:blue;
color:black;
}
.parent > li > ul > li {
background:orange
}
.parent > li > ul > li > ul >li {
background:pink;
}
</style>
</head>
<body>
<ul class="parent">
<li>I am first</li>
<li>I am second</li>
<li>I am third</li>
<li>I am forth</li>
<li>I have kids.
<ul class="child">
<li>child1</li>
<li>child2
<ul>
<li>child2.1</li>
<li>child2.2</li>
<li>child2.3</li>
</ul>
</li>
<li>child3</li>
<li>child4</li>
<li>child5</li>
</ul>
</li>
<li>I am sixth</li>
<li>I am seventh</li>
<li>I am eight</li>
</ul>
</body>
</html>
Related
This question already has answers here:
What does a space mean in a CSS selector? i.e. What is the difference between .classA.classB and .classA .classB? [duplicate]
(3 answers)
Closed 3 years ago.
I have a navigation item in a div, I just want to target this one with an attribute value, But my CSS does not work so far. Code so far below is:
I am trying to target the navDepts class
HTML
<div class="primary-nav" data-name="about">
<div class="subNav">
<ul class="navDepts">
<!-- <li></li>-->
</ul>
</div>
</div>
CSS
.primary-nav [data-name="about"] .subNav ul .navDepts {
display: none!important;
}
Try removing ul from your CSS. Because ul and .navDepts are on the same level.
.primary-nav[data-name="about"] .subNav .navDepts {
display: none!important;
}
Your CSS inheritance is not proper:
.primary-nav[data-name="about"] .subNav ul.navDepts {
background: red;
}
<div class="primary-nav" data-name="about">
<div class="subNav">
<ul class="navDepts">
<!-- <li></li>-->sadsadsad
</ul>
</div>
</div>
I found two mistakes in your code.
First one is that there should not be any space between attribute selector and related class.
Second, I presume that you mean to select ul with .navDepts class. So I removed the space between them.
So here is the corrected css:
.primary-nav[data-name="about"] .subNav ul.navDepts {
background: red;
width: 100px;
height: 100px;
}
.primary-nav[data-name="about"] .subNav ul.navDepts li{
background: yellow;
}
<div class="primary-nav" data-name="about">
<div class="subNav">
<ul class="navDepts">
<li>list item</li>
</ul>
</div>
</div>
Add this CSS . May it will help you out.
.primary-nav [data-name="about"] >.subNav ul.navDepts {
display: none;
}
I'm not surprised the CSS doesn't work, but I hope you get the idea. There are 2 lists and I'm trying to target the first letter of the first a in the first ul. In this example that's the B of Beauty Salons. Can I do this with CSS without changing the HTML?
CSS:
.tab-pane .category-headings ul:first-of-type a:first-of-type::first-letter {
margin-right: 1px;
padding: 0px 5px;
background-color: #666;
color: #fff;
font-weight: bold;
}
HTML:
<div class="tab-pane" id="b">
<div class="container-fluid category-headings">
<div class="row-fluid">
<div class="span11 offset1">
<div class="row-fluid">
<div class="span4">
<ul class="unstyled">
<li>Beauty Salons & Therapy
</li>
<li>Blinds
</li>
</ul>
</div>
<div class="span4">
<ul class="unstyled">
<li>Book Binders
</li>
<li>Bookkeeping Services
</li>
</ul>
</div>
<div class="span4">
<ul class="unstyled">
<li>Builders
</li>
<li>Building Plans
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
FIDDLE:
http://jsfiddle.net/a4644b8h/2/
It works if you set the <a> tag to be a block display element:
.tab-pane .category-headings ul:first-of-type li:first-of-type a:first-of-type::first-letter {
margin-right: 1px;
padding: 0px 5px;
background-color: #666;
color: #fff;
font-weight: bold;
}
.tab-pane .category-headings ul:first-of-type li:first-of-type a:first-of-type {
display: inline-block;
}
This is because the :first-letter selector will only apply to block elements, and not inline ones.
Here is an example fiddle.
First you need to change a few of those selectors. You aren't looking for ul:first-of-type. This will select the first ul inside each of the <div class="span4"> divs. Instead you want to target the first div with class="span4", like so:
.span4:first-of-type
Next, basically the same thing, you don't want to target a:first-of-type, this will select the first a tag in each of those li elements. Instead, target the first li, like so:
li:first-of-type
And then target the a tag inside that first li
So, to put all that together:
.tab-pane .category-headings .span4:first-of-type li:first-of-type a::first-letter {
}
Also, as Alan mentioned, the parent of the ::first-letter pseudo-element must be a block-level element, so add
.span4 a { /* make this selector as specific as you need it */
display: inline-block;
}
And that should do it. JSFiddle here
My HTML code is as follows:
<div class="c1"> Heading
<div>
<ul style="display:none">
<li>Item1</li>
<li>Item1</li>
</ul>
</div>
</div>
This is my CSS :
.c1:hover > div ul
{
display:block;
}
How do I access lower level children with ">" operator? I basically want the list to be displayed on hover of c1.
You need to remove the inline style (style="display:none") from your markup - inline style will override the styles loaded from the stylesheet.
Instead, put this in your stylesheet:
.c1 > div ul {
display:none;
}
.c1:hover > div ul {
display:block;
}
Do this -
Demo
<div class="c1"> Heading
<div>
<ul>
<li>Item1</li>
<li>Item1</li>
</ul>
</div>
</div>
CSS
ul{ display: none; }
.c1:hover div ul
{
display:block;
}
I'm trying to create a hover link using css but it's not working. Is this the correct way to create css hover links? Thanks,
I have read though this but no luck: http://w3schools.com/css/css_link.asp
Here is the code I have:
CSS
.Footerbullets{
padding:3px 0 3px 25px;
background-image:url(../images/menubar/footer_bullet.jpg);
background-repeat:no-repeat;
}
.Footerbullets a.link {
color:#FFF;
}
.Footerbullets a.hover {
color:#FF0;
}
HTML
<div id="footer"><div class="content">
<ul>
<li class="Footerbullets">Link with Hover Color Change</li>
</ul>
<div class="clear"></div>
</div></div>
Use div#footer ul li.Footerbullets a:hover instead of .Footerbullets a:hover, it seems that div#footer ul li a:hover is overriding other styles.
http://jsfiddle.net/GFec3/14/
I made a jsfiddle with a working example for each anchor pseudo-class. I tested it and it works in the latest version of Safari at least. You can find it here:
http://jsfiddle.net/kylewlacy/DqePq/
You can read about each pseudo-class and what they do here, as well
Try this
.Footerbullets a:hover {
color:#FF0 !important;
}
My code
<style>
.Footerbullets{
padding:3px 0 3px 25px;
background-image:url(../images/menubar/footer_bullet.jpg);
background-repeat:no-repeat;
}
.Footerbullets a.link {
color:#FFF;
}
.Footerbullets a:hover {
color:#FF0;
}
</style>
HTML
<div id="footer"><div class="content">
<ul>
<li class="Footerbullets">Link with Hover Color Change</li>
</ul>
<div class="clear"></div>
</div></div>
To my knowledge, the answer to this is no, can't be done, but I need a second opinion:
If I have the following:
<li>
<a >#</a>
<div class="sub">
#
</div>
</li>
and have a background image that appears on li a:hover is it possible to have that background stay on when hovering on the .sub div? This also has to work pure CSS - no javascript cheats.
My understanding is because .sub isn't a child of the a we can't reference it in css to keep the hover.
Because the image is for only one section of the code, I can't move it to the li and reference li:hover a.
Not sure what all you are trying to achieve, but there are many hover effects that can be done.
SECOND UPDATE: If you don't need to interact (other a tags, etc) at all with anything in the div, then this way cheats to get the effect. Note how the anchor inside the div does not register because of the z-index.
UPDATE I think I understand your issue better now. Can you add a wrapper and do the following?:
Example HTML:
<ul>
<li>
<div>
<a>Some anchor text</a>
<div class="sub">Some div content <a>and anchor</a></div>
</div>
</li>
</ul>
Example CSS:
li:hover {
background-color: cyan;
}
li > div:hover > a {
background-color: green;
}
a:hover {
color: yellow;
display: block;
}
a:hover + .sub {
outline: 1px solid blue;
}
.sub:hover {
color: red;
outline: 1px solid red;
}
If you can't use a class on the li or modify the div.sub to be in the a, you're probably out of luck without Javascript:
Is there a CSS parent selector?
However, if you can, you could use:
<ul>
<li class="sub">
<a>Class #</a>
<div class="sub">#</div>
</li>
<li>
<a>Inner #
<div class="sub">#</div>
</a>
</li>
<li>
<a>None #</a>
<div class="sub">#</div>
</li>
</ul>
li.sub:hover,
li a:hover {
background: url(http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=32&d=identicon&r=PG);
}
li a {
border: 1px solid blue;
display: block;
}
.sub {
border: 1px solid green;
}
http://jsfiddle.net/B7Au2/4/
I don't know if you can modify the html, but if you can, try swapping the div and the a:
<li>
<div class="sub">
#
</div>
<a >#</a>
</li>
Now you can use the adjacent sibling selector:
li a:hover, li .sub:hover + a {background:url('some-image.png')}
Unfortunately there's no way to select the previous element through CSS: that's why you need to swap your elements.