Add css class to element if sibling div exists - html

When button with class menu-button is clicked, div with class popover-menu is added to the DOM. When this happens, the popover-menu element becomes active.
Is there a way using CSS to add an additional class to the button whenever popover-menu is within DOM?
<div>
<button class="menu-button">
<span>Clickme</span>
</button>
<div class="popover-menu">
Menu
</div>
</div>

While there is no ability to mutate an element's classes within the context of a stylesheet, in your case the only-child pseudo-class may suffice for what you want to do here.
<style>
.menu-button:only-child {
color: pink;
}
</style>
<div>
<button class="menu-button">
<span>Clickme</span>
</button>
<div class="popover-menu">
Menu
</div>
</div>
https://codepen.io/hamzatayeb/pen/dzKyja

Related

Apply style to only nested class of current element

I am aware in **CSS** we can apply a set of styles to nested classes in elements (demonstrated at this page Apply CSS rules to a nested class inside a div).
I am now trying to apply a style to a nested class in a div. The catch here is I am unable to apply the style to only the nested class of the currently hovered element.
To explain further, here is an HTML snippet:
<div class="link-wrap">
<div class="link"> Github </div>
<hr class="text-underline">
<div>
<div class="link-wrap">
<div class="link"> Facebook </div>
<hr class="text-underline">
<div>
I would like that if I hover over the Github link, I would alter the style of the <hr> for the Github link alone.
Currently, when I do alter the style of the <hr>, both of the <hr>s have their styles altered at the same time.
I am trying to find a non-JS solution.
Is something like this getting close to what you're after?
.link-wrap:hover > .text-underline {
border-color: blue;
}
<div class="link-wrap">
<div class="link"> Github </div>
<hr class="text-underline">
</div>
<div class="link-wrap">
<div class="link"> Facebook </div>
<hr class="text-underline">
</div>
.link-wrap:hover > hr {
your styles
}
this will apply your styles to any <hr> that is the direct descendant of .link-wrap that is hovered

Change another div on hover which is not sibling nor child

My HTML code is similar to this :
<div class="navbar">
<div class="btn-section btn-1">
<p class="section pro">...</p>
</div>
</div>
<div class="navbar">
<div class="btn-section btn-2">
<p class="section notpro">...</p>
</div>
</div>
I'm using this in my CSS code :
.btn-1:hover {
.pro {
...
}
}
It works perfectly.
What I want to do now is to modify my .notpro class inside the btn-1:hover. As .notpro is not child or sibling with btn-1, it doesn't work.
.btn-1:hover {
.pro {
... // works
}
.notpro {
... // doesn't work
}
}
Is there a way to do this ?
Thank you !
There is no way without using javascript to affect a different non-sibling selector. But you an do it if you move the hover up one level.
You need to put the hover on the first navbar and using the direct sibling combinator (+) - target the other navbar and then inside it to get the .notpro element. Note that I added words to your elements to show the hover effect.
The only other CSS way of doing this is to put both elements inside the one navbar - then they are siblings and can be targetted.
.navbar:hover + .navbar .notpro {
color: red;
}
<div class="navbar">
<div class="btn-section btn-1">
<p class="section pro">I am a Pro</p>
</div>
</div>
<div class="navbar">
<div class="btn-section btn-2">
<p class="section notpro">I am Not a Pro</p>
</div>
</div>
I don't think this syntax is valid in CSS, meaning selector inside another selector.
You can add :hover to the 'pro' to get different behaviour than the parent div.

unable to target a button tag inside div

I have html structure like this
<div class="buttons controls">
<button>Next</button>
<button>Previous</button>
</div>
I am targetting the buttons
.controls>button
.buttons.controls>button
but it is not working. I want to know why??
Well, because your <button> element is not a child of div.controls. You could use .controls a > button or .controls > a > button
A > E
Any E element that is a child (i.e. direct descendant) of an A element
MDN Documentation - Selectors based on relationships
EDIT:
.controls > a > button is more specific. So it will only be applied when your HTML looks like this
<div class="buttons controls">
<a href='#'>
<button>MyButton</button>
</a>
</div>`
.controls a button is a more general selector, so it would also be applied with a HTML like this -
<div class="buttons controls">
<div class="myDiv">
<a href="#H">
<button>MyButton</button>
</a>
</div>
</div>
As you see, you could also specify a div as parent of <a> element and the CSS-Style will still be applied.
Because .button is inside of the anchor therefore it is not a direct descendant of the .controls class as you are trying to do in your css
try this:
.controls .button {
/* style here */
}
or like stated in the answer above
.controls > a > button {
font-size: 20px;
}

CSS select first button with same class of the second button

It's as simple as it looks like. I want to display:none; the first button. I have two of them with same parent class. For some reason I can't figure out why I don't achieve the result I want.
.main-content .cbToolBar:first-child button{
display:none;
}
<div class="main-content">
<span class="cbToolBar">
<button class="cbButton"></button>
</span>
<span class="cbToolBar">
<button class="cbButton"></button>
</span>
</div>
There is something wrong with my selection but I can't figure out what.
Thanks.
...there are other tags before but at the same level as 'cbToolBar' span, but I thought it would select the first child called 'cbToolBar'.
CSS's :first-child pseudo-class selector selects specifically the first child, regardless of it's class. The documentation on :first-child states:
Same as :nth-child(1). The :first-child pseudo-class represents an element that is the first child of some other element.
There are several workarounds. The one I'd suggest is that if your .cbToolBar elements are the only span elements within your .main-content parent, you can instead use the :first-of-type pseudo-class selector:
Same as :nth-of-type(1). The :first-of-type pseudo-class represents an element that is the first sibling of its type in the list of children of its parent element.
.main-content .cbToolBar:first-of-type button{
display:none;
}
<div class="main-content">
<p>Hello, world!</p>
<span class="cbToolBar">
<button class="cbButton">Button 1</button>
</span>
<span class="cbToolBar">
<button class="cbButton">Button 2</button>
</span>
</div>
Or, if you know the exact position of your element you want to hide, you can always just use :nth-child(n). In this example, the element we want to hide is the second one, so we use :nth-child(2):
.main-content .cbToolBar:nth-child(2) button{
display:none;
}
<div class="main-content">
<p>Hello, world!</p>
<span class="cbToolBar">
<button class="cbButton">Button 1</button>
</span>
<span class="cbToolBar">
<button class="cbButton">Button 2</button>
</span>
</div>
You can use the general sibling combinator in this case.
Set a rule for all elements with a certain class
Use the combinator to select following siblings and unset the rule
.cbToolBar button {
display: none;
}
.cbToolBar ~ .cbToolBar button {
display: inline-block;
}
<div class="main-content">
<span>span</span>
<span class="cbToolBar">
<button class="cbButton">button</button>
</span>
<span>span</span>
<span class="cbToolBar">
<button class="cbButton">button</button>
</span>
<span>span</span>
</div>

CSS selector for the first element of class

How can I choose only the first button in this code?
It's even more nested in my case, but this code is also a problem for me.
<div class="container">
<div class="some_class">
<span>abc</span>
<button class="btn">...</button>
</div>
<div class="some_class">
<span>abc</span>
<button class="btn">...</button>
</div>
<div class="some_class">
<span>abc</span>
<button class="btn">...</button>
</div>
</div>
You would use the :first-child pseudo class.
EXAMPLE HERE
.container .some_class:first-child button {
background:black;
}
Alternatively, assuming that the markup can be different, you might need to use something like this to ensure that the first button is selected even if .some_class isn't the first element. (example)
.container :first-child button {
background:black;
}
This will work
.container .some_class:first-child button {
/* rules here */
}
http://jsfiddle.net/cUu82/1/
you could just use .some_class:first-child button as well if these are the only ones on the page
The first-child (https://developer.mozilla.org/en/docs/Web/CSS/:first-child) will select the first some_class div which was probably your only issue