This is a follow-up question to - Override parent style if child element exists
As per suggestion and comments, :has is yet to be supported and there's no way to modify a parent's style if a certain child element exists.
Certainly not possible with just css alone.
I was thinking to pass down the z-index property to the child and unset it from the parent.
Here's what I've tried.
div#info {
z-index: unset !important;
}
div#info > div.label {
z-index: 109;
}
div#info > div.pop-up {
z-index: 110; /* Pop-up should always appear on top */
}
But still didn't work. Is this even possible?
The idea is: making the parent element have no style and z-index will be declared in the child elements.
NOTE: by just using CSS3, no scripts involved. HTML elements and style properties are generated by the API.
Finally got it working!
Given this HTML Structure:
<div id="info">
<div class="pop-up">...</div>
</div>
<div id="info">
<div class="label">...</div>
</div>
I just forced the parent to have no style properties and marked the z-index property for each child as !important
div#info {
z-index: unset !important;
}
div#info > div.label {
z-index: 109 !important;
}
div#info > div.pop-up {
z-index: 110 !important; /* Pop-up should always appear on top */
}
This works for my need. Not sure if it will be useful in general since a parent may have different styles that will be inherited by the child element.
Good thing I only have to worry just one property, the z-index.
Related
Just wondering, can I make CSS inheritance skip a generation?
For example if I had this code:
Code:
.grandfather {
background-color: #fff;
}
.parent {
background-color: #333;
}
.child {
background-color: inherit;
}
<div class='grandfather'>
<div class='parent'>
<div class='child'>
Is there a way for the inherit command to take the background-color from the grandfather and completely ignore the parent? Or would i need to use a variable for that?
The short answer is no, you cannot. The inherit property always takes its value from its parent.
You can read more here: CSS inherit property
It touches on this issue with a specific note:
Note: Inheritance is always from the parent element in the document
tree, even when the parent element is not the containing block.
The simple solution is to have a class in the color you wish to use e.g. .blue {background: blue;} and add that into the HTML or use CSS custom properties (CSS variables) to effectively do that too.
I have a div within a webpage I am trying to target with the following code to create a flexbox:
div.my-div-class {
display: flex;
flex-wrap: wrap;
}
div.my-div-class > label {
fl
Originally I had a problem with the User Agent Styles overriding the div and causing it to automatically display block. I fix that per this question by adding the following code:
div {
display: inherit;
}
Which I assumed, perhaps naively, that this would cause the div to "inherit" the styles of what I set to the class.
I check the console, and sure enough see:
div { display: inherit; }
instead of what was there before for the User Agent which was:
div {display: block;}
Which is what I assumed was messing with my style originally.
I tried !important to see if that would at least cause a change and it didn't.
So I'm thinking I don't fully understand the behavior of inherit or how to target this particular div correctly.
Can someone explain this a little bit? I should mention this div is wrapped in a form, and the HTML of that form is like below:
<div id="form-container">
<form id="form">
<div class="my-div-class" id ="the-target-div">
/*Rest of the HTML*/
</div>
</form></div>
Generally you don't really need to target the div tag, you should instead use a class.
If you are creating your own CSS and not using some library, such as bootstrap, it's a good idea to use a CSS reset to make sure you are writing CSS on a clean slate. This is a popular one.
To answer your question, the inherit property sets a css property to inherit the value from its parent. A div tag by default is a block level element, so setting anything to inherit below it will also set it to display: block.
Just target whatever you need to be flex with the class name, such as:
.my-div-class {
display: flex
}
It seems that you didn't copy all of your html code, cos it looks like it's broken in the middle.
If you want to target this particular div you should do it by refering to it's class or id. Property value "inherit" inherits ONLY the property from its parent element that it is set as a value to.
For example:
.parentElement {
display: flex;
background: yellow;
height: 200px;
width: 100%;
}
.childElement {
display: flex;
height: 100px;
width: 70%;
background: blue;
}
.childElement:hover {
height: inherit;
}
<div class="parentElement">
<div class="childElement">
</div>
</div>
In this example when we hover over the child element we are setting height value to "inherit" which inherits the value ONLY for height property, but the width for example doesn't change.
In short: if you want your div to inherit all styles his parents has you should set "inherit" as a value for every property it's parent has.
I have a html page which has a div looking like this:
<div class="get-this"> blah blah </div>
I have a before pseudoelement on the div and I am trying to apply CSS style only to the div which will not be applicable to the pseudo element.
.get-this:not(::before) {
padding-top:2px;
}
The style is applied to the entire div. IS it possible to restrict the style only to the div and not the pseudo element?
This is a straightforward use of the cascade.
The CSS cascade is intended to enable you to apply general styles to more general selectors and overriding styles to more specific selectors.
Hence:
.get-this {
padding-top:2px;
}
.get-this::before {
padding-top:0;
}
Working Example:
.paragraph-one {
color: red;
}
.paragraph-two {
color: blue;
}
.paragraph-one::before {
content: 'Paragraph One: ';
}
.paragraph-two::before {
content: 'Paragraph Two: ';
color: green;
}
<p class="paragraph-one">This is paragraph one. It is red.</p>
<p class="paragraph-two">This is paragraph two. It is blue.</p>
<p>The <code>::before</code> pseudo-element preceding Paragraph Two <em>isn't the same color</em> as the rest of Paragraph Two, because, further down the cascade, an overriding style has been declared for the more specific <code>.paragraph-two::before</code> selector.</p>
if you already applied all of your div element to have before or after css they would require you to type content: ""; in order to show style applied to DOM:before or DOM:after
Which means if you set content to none it won't show that.
to overwrite your div style you can simply do
.get-this:before {
content: none;
}
But I would avoid applying before or after properties to all of your div element of your application. div element is often used on many situation, therefore you will run into problem you are now facing on every div element. which mean writing css to overwrite css. that's just not a good practice in most of case.
Also if your DOM element that has before, after its position is related with parent DOM, that being said, if your DOM's padding, margin, positioning, size changes will effect to before or after of that DOM
I know that there does not exist a CSS parent selector, but is it possible to style a parenting element when hovering a child element without such a selector?
To give an example: consider a delete button that when hovered will highlight the element that is about to become deleted:
<div>
<p>Lorem ipsum ...</p>
<button>Delete</button>
</div>
By means of pure CSS, how to change the background color of this section when the mouse is over the button?
I know it is an old question, but I just managed to do so without a pseudo child (but a pseudo wrapper).
If you set the parent to be with no pointer-events, and then a child div with pointer-events set to auto, it works:)
Note that <img> tag (for example) doesn't do the trick.
Also remember to set pointer-events to auto for other children which have their own event listener, or otherwise they will lose their click functionality.
div.parent {
pointer-events: none;
}
div.child {
pointer-events: auto;
}
div.parent:hover {
background: yellow;
}
<div class="parent">
parent - you can hover over here and it won't trigger
<div class="child">hover over the child instead!</div>
</div>
Edit:
As Shadow Wizard kindly noted: it's worth to mention this won't work for IE10 and below. (Old versions of FF and Chrome too, see here)
Well, this question is asked many times before, and the short typical answer is: It cannot be done by pure CSS. It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
But in most circumstances where this effect is wished, like in the given example, there still is the possibility to use these cascading characteristics to reach the desired effect. Consider this pseudo markup:
<parent>
<sibling></sibling>
<child></child>
</parent>
The trick is to give the sibling the same size and position as the parent and to style the sibling instead of the parent. This will look like the parent is styled!
Now, how to style the sibling?
When the child is hovered, the parent is too, but the sibling is not. The same goes for the sibling. This concludes in three possible CSS selector paths for styling the sibling:
parent sibling { }
parent sibling:hover { }
parent:hover sibling { }
These different paths allow for some nice possibilities. For instance, unleashing this trick on the example in the question results in this fiddle:
div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}
Obviously, in most cases this trick depends on the use of absolute positioning to give the sibling the same size as the parent, ánd still let the child appear within the parent.
Sometimes it is necessary to use a more qualified selector path in order to select a specific element, as shown in this fiddle which implements the trick multiple times in a tree menu. Quite nice really.
Another, simpler "alternate" approach (to an old question)..
would be to place elements as siblings and use:
Adjacent Sibling Selector (+)
or
General Sibling Selector (~)
<div id="parent">
<!-- control should come before the target... think "cascading" ! -->
<button id="control">Hover Me!</button>
<div id="target">I'm hovered too!</div>
</div>
#parent {
position: relative;
height: 100px;
}
/* Move button control to bottom. */
#control {
position: absolute;
bottom: 0;
}
#control:hover ~ #target {
background: red;
}
Demo Fiddle here.
there is no CSS selector for selecting a parent of a selected child.
you could do it with JavaScript
As mentioned previously "there is no CSS selector for selecting a parent of a selected child".
So you either:
use a CSS hack as described in NGLN's answer
use javascript - along with jQuery most likely
Here is the example for the javascript/jQuery solution
On the javascript side:
$('#my-id-selector-00').on('mouseover', function(){
$(this).parent().addClass('is-hover');
}).on('mouseout', function(){
$(this).parent().removeClass('is-hover');
})
And on the CSS side, you'd have something like this:
.is-hover {
background-color: red;
}
In 2022:
This can be now achieved with CSS only, using the :has pseudo-class and the following expression:
div:has(button:hover) {}
Here's a snippet showcasing the original proposition:
div:has(button:hover) {
background-color: cyan;
}
<div>
<p>Lorem ipsum ...</p>
<button>Delete</button>
</div>
See browser support here. At the time of writing, all major browser support it—except Firefox, which still has a flawed experimental implementation.
This solution depends fully on the design, but if you have a parent div that you want to change the background on when hovering a child you can try to mimic the parent with a ::after / ::before.
<div class="item">
design <span class="icon-cross">x</span>
</div>
CSS:
.item {
background: blue;
border-radius: 10px;
position: relative;
z-index: 1;
}
.item span.icon-cross:hover::after {
background: DodgerBlue;
border-radius: 10px;
display: block;
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
content: "";
}
See a full fiddle example here
This is extremely easy to do in Sass! Don't delve into JavaScript for this. The & selector in sass does exactly this.
http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand
I want solution using only CSS
we have 3 circle here.
Whenever I perform mouse-over on circles with class Name Mycircle , the circle with class Name BigCircle should change to red color
html
<div class="BigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
CSS
.mycircle,.BigCircle{width:50px; height:50px; border-radius:30px; background-color:grey; margin:3px}
.mycircle:hover{background:yellow}
.mycircle:hover .BigCircle{background:red}
Here is the demo >http://jsfiddle.net/JGbDs/4/
Thanks in Advance
In your comments you state that you cannot re-arrange the elements, but you can add ones if required.
For that reason the general sibling combintor in the accepted answer is not suitable as the .bigCircle element would have to come after all of the .myCircle elements.
There is no perfect way of achieving this using only CSS but it is possible by adding a "parent" element and using one of the following CSS solutions:
Solution 1
When hovering on the parent element, the .bigCircle child element will be coloured red:
Working example: http://jsfiddle.net/CKRef/
HTML
<div class="parent">
<div class="bigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* Add float to parent to fit width to content */
.parent {
float: left;
clear: both;
}
.parent:hover > .bigCircle{
background: red;
}
The issue with this solution is that the .bigCircle element will be coloured red when you hover anywhere on the parent, not just on .myCircle. Adding the float reduces this effect - but if you hover just outside of the circle then the .bigCircle will still be red.
Solution 2
Using the parent element as a relative container, we can add a new element to the page using the after pseudo selector when a .myCircle element is hovered over:
Working example http://jsfiddle.net/CKRef/1/
HTML
<div class="parent">
<div class="mycircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* replaced .bigCircle with mycircle:hover::after */
.mycircle, .mycircle:hover::after {
....
}
.parent {
position: relative;
}
.mycircle:hover::after {
content: "";
background-color: red;
position: absolute;
top: 0;
left: 0;
margin-top: 0;
}
The imperfection with this solution is that we are targeting the position of the first child of the parent element, rather than the element with the class name .bigCircle. Also, the after pseudo selector is not supported in IE7.
No. That's not possible using just css. "Any sibling" selector is not there in css.
However, if you can move BigCircle to end, you can use general sibling combinator which can select successor siblings.
.mycircle:hover ~ .BigCircle{background:red}