Css nth-child:hover ~ first-child {...} - html

Im trying to change the first child, when i hover on the second child. How do you do this with html and css only?
(With the tilde/~ i seem to be able to select childeren downwards in the html code, but not upwards. Do i have to use a different selector to go upwards?)
grtz
<div id="container">
<div id="box1"></div>
<div id="box2"></div>
</div>
<style>
#box1 {
height: 100px;
width: 100px;
background-color: red;
}
#box2 {
height: 100px;
width: 100px;
background-color: lime;
}
#box2:hover ~ #box1 {
height: 300px;
width: 300px;
background-color: yellow;
}
</style>

General sibling selectors, this is what the tilde expresses, will only select the siblings following (not preceeding) the matched element.
The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.
Reference: http://www.w3.org/TR/css3-selectors/#general-sibling-combinators
In your case there might be a CSS-only chance to archive this. Actually two ...
Chance 1
On parents :hover, change the children.
#container:hover div:first-child {
background-color: #cff;
}
In your case, this required #container to be display: inline-block;, otherwise the red box would change too, when hovering the empty area right to both boxes.
Bin: http://jsbin.com/dilitucije/1
Works in all modern browsers and most older browsers too.
Chance 2
I'd use flexbox with defined order to reverse the rendering of both items. Since the rendering order of elements is reversed but the DOM order is not, this works.
CSS:
.reversed {
display: flex;
flex-direction: column-reverse; /* reverse rendering */
}
#container div:hover:first-child ~ div {
background-color: #cff;
}
Explanation of the Flexbox rules:
use Flexbox (great explanation, W3C spec)
order the items in rows (the container is a "column"), reverse the order of the items within the .reversed container (first DOM node is rendered last, last DOM node is rendered first)
Add the class to your #container
<div id="container" class="reversed">...</div>
Bin: http://jsbin.com/piyokulehe/1
Works in FF 34, Chrome 39, should work in at least IE 11 too (probably not IE10).
Update:
Fixed wrong row-reverse (the example uses column-reverse, matches your requirement)
Removed unnecessary justify-content (since the items are rendered into rows, this is not necessary)
Added explanaition to the Flexbox solution

To achieved this on hover your element need to be the child of the element or comes after the element that is hovered.
The element whose styles are needed to be changed must be the descendent of the hovered element or comes next to it to work

Related

overwrite if the class select has only 3 children (css or scss) [duplicate]

I'm probably answering my own question, but I'm extremely curious.
I know that CSS can select individual children of a parent, but is there support to style the children of a container, if its parent has a certain amount of children.
for example
container:children(8) {
// style the parent this way if there are 8 children
}
I know it sounds weird, but my manager asked me to check it out, haven't found anything on my own so I decided to turn to SO before ending the search.
Clarification:
Because of a previous phrasing in the original question, a few SO citizens have raised concerns that this answer could be misleading. Note that, in CSS3, styles cannot be applied to a parent node based on the number of children it has. However, styles can be applied to the children nodes based on the number of siblings they have.
Original answer:
Incredibly, this is now possible purely in CSS3.
/* one item */
li:first-child:nth-last-child(1) {
/* -or- li:only-child { */
width: 100%;
}
/* two items */
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
width: 50%;
}
/* three items */
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
width: 33.3333%;
}
/* four items */
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
width: 25%;
}
The trick is to select the first child when it's also the nth-from-the-last child. This effectively selects based on the number of siblings.
Credit for this technique goes to André Luís (discovered) & Lea Verou (refined).
Don't you just love CSS3? 😄
CodePen Example:
https://codepen.io/mattlubner-the-decoder/pen/ExaQZQR
Sources:
http://andr3.net/blog/post/142 (André Luís)
http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ (Lea Verou)
No. Well, not really. There are a couple of selectors that can get you somewhat close, but probably won't work in your example and don't have the best browser compatibility.
:only-child
The :only-child is one of the few true counting selectors in the sense that it's only applied when there is one child of the element's parent. Using your idealized example, it acts like children(1) probably would.
:nth-child
The :nth-child selector might actually get you where you want to go depending on what you're really looking to do. If you want to style all elements if there are 8 children, you're out of luck. If, however, you want to apply styles to the 8th and later elements, try this:
p:nth-child( n + 8 ){
/* add styles to make it pretty */
}
Unfortunately, these probably aren't the solutions you're looking for. In the end, you'll probably need to use some Javascript wizardry to apply the styles based on the count - even if you were to use one of these, you'd need to have a hard look at browser compatibility before going with a pure CSS solution.
W3 CSS3 Spec on pseudo-classes
EDIT I read your question a little differently - there are a couple other ways to style the parent, not the children. Let me throw a few other selectors your way:
:empty and :not
This styles elements that have no children. Not that useful on its own, but when paired with the :not selector, you can style only the elements that have children:
div:not(:empty) {
/* We know it has stuff in it! */
}
You can't count how many children are available with pure CSS here, but it is another interesting selector that lets you do cool things.
NOTE: This solution will return the children of sets of certain lengths, not the parent element as you have asked. Hopefully, it's still useful.
Andre Luis came up with a method: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ Unfortunately, it only works in IE9 and above.
Essentially, you combine :nth-child() with other pseudo classes that deal with the position of an element. This approach allows you to specify elements from sets of elements with specific lengths.
For instance :nth-child(1):nth-last-child(3) matches the first element in a set while also being the 3rd element from the end of the set. This does two things: guarantees that the set only has three elements and that we have the first of the three. To specify the second element of the three element set, we'd use :nth-child(2):nth-last-child(2).
Example 1 - Select all list elements if set has three elements:
li:nth-child(1):nth-last-child(3),
li:nth-child(2):nth-last-child(2),
li:nth-child(3):nth-last-child(1) {
width: 33.3333%;
}
Example 1 alternative from Lea Verou:
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
width: 33.3333%;
}
Example 2 - target last element of set with three list elements:
li:nth-child(3):last-child {
/* I'm the last of three */
}
Example 2 alternative:
li:nth-child(3):nth-last-child(1) {
/* I'm the last of three */
}
Example 3 - target second element of set with four list elements:
li:nth-child(2):nth-last-child(3) {
/* I'm the second of four */
}
Working off of Matt's solution, I used the following Compass/SCSS implementation.
#for $i from 1 through 20 {
li:first-child:nth-last-child( #{$i} ),
li:first-child:nth-last-child( #{$i} ) ~ li {
width: calc(100% / #{$i} - 10px);
}
}
This allows you to quickly expand the number of items.
Now we can use the :has() selector to identify the number of items and apply style to the container
.container {
height: 50px;
margin: 10px;
}
.container:not(:has(*)) { /* 0 elements */
background: yellow;
}
.container:has(> :last-child:nth-child(1)) { /* 1 element */
background: red;
}
.container:has(> :last-child:nth-child(2)) { /* 2 elements */
background: blue;
}
.container:has(> :last-child:nth-child(3)) { /* 3 elements */
background: green;
}
/* For N elements
.container:has(> :last-child:nth-child(N)) {
background: red;
}
*/
<div class="container">
</div>
<div class="container">
<div></div>
</div>
<div class="container">
<div></div>
<div></div>
</div>
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Yes we can do this using nth-child like this:
div:nth-child(n + 8) {
background: red;
}
This will make the 8th div child onwards become red. Hope this helps...
Also, if someone ever says "hey, they can't be done with styled using css, use JS!" doubt them immediately. CSS is extremely flexible nowadays
.container div {
background: blue;
}
.container div:nth-child(n + 8) {
background: red;
}
<div class="container">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
<div>div 5</div>
<div>div 6</div>
<div>div 7</div>
<div>div 8</div>
<div>div 9</div>
<div>div 10</div>
<div>div 11</div>
<div>div 12</div>
</div>
In the example the first 7 children are blue, then 8 onwards are red...
[External example]
If you are going to do it in pure CSS (using scss) but you have different elements/classes inside the same parent class you can use this version!!
&:first-of-type:nth-last-of-type(1) {
max-width: 100%;
}
#for $i from 2 through 10 {
&:first-of-type:nth-last-of-type(#{$i}),
&:first-of-type:nth-last-of-type(#{$i}) ~ & {
max-width: (100% / #{$i});
}
}
If you're looking for a way to style all elements if more than N exist (e.g. 2 or more):
li:first-child:nth-last-child(n+2),
li:first-child:nth-last-child(n+2) ~ li {
background-color: red;
}
<ul>
<li>first</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
No, there is nothing like this in CSS. You can, however, use JavaScript to calculate the number of children and apply styles.
You can use :has selector like this:
.parent-element:has(:nth-child(8))
It selects element with .parent-element class that has child number 8. If child number 8 does not exist, rule will not be applied.
Unfortunately :has is not supported in firefox by default. You can still use it and add extra tricky rule for firefox support.
If you are using something like reactJS, you can simply add a class and then style it.
e.g. suppose you are displaying items from an array.
app.jsx
<div className={`items-count-is-${items.length}`}>
{items.map(item => {
return <li>...</li>;
})}
</div>
e.g. CSS: items-count-is-5 {...}

div is not displaying as a flexbox

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.

Is it possible to automatically hide all the range of (a ~ MAX)th children element in pure CSS?

I know it's very easy to do it with JavaScript. For example, if I want to hide all children after 50th, I just need to do:
$("#container").find('div').each(function(){
if ($(this).index() > 50) $(this).hide();
})
But is it possible to do it with pure CSS?
Note:
The total children number is not a fixed one. It may change (by other JavaScript codes
I only need to support Chrome so no need to consider other browsers
I don't have access to the HTML DOM itself (because I am building a Chrome Extension)
Update:
Sorry that I want to hide from a to All the next (the last one) children. I have edited my question. It's NOT from a~b.
div are the only children. There are NO other children in this container.
.container div:nth-child(n+51) {
display:none;
}
n is the cycle number, 51 is the offset so will start on the 51st item, then repeat every 1 item.
Another idea is to use the ~ selector in order to hide all the element after a particular one:
.container div:nth-child(51) ~ * {
display:none;
}
Here is an example:
.container div:nth-child(5) ~ * {
display: none;
}
.container div {
height:20px;
width:20px;
display:inline-block;
border:1px solid;
background:red;
}
<div class="container">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>

Undo hover effect of parent when hovering over child [duplicate]

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

CSS :: Difference between .className and div.className

I write a html element as below ::
<div class="box"> Foo box </div>
and write css like
.box {
width: 400px;
height: 40px;
color: red;
text-align: center;
}
or
div.box {
width: 400px;
height: 40px;
color: red;
text-align: center;
}
I want to ask that how the both css for box class is different than each other.
The difference is that in the first class you tell that all element (div, p, span ...) with class box have that attribute.
Like this:
<span class="box">test</span>
<div class="box">test</div>
<p class="box">test</p>
The second class means that only div with class box has that attribute
Only this elements get second class:
<div class="box">test</div>
The selector before the class specify which type of elements can take this class
One very important difference between div.box and simply .box is in something called selector specificity. It is a set of rules which defines which selector gets more weight once the browser starts going through all the selectors that potentially have influence on a particular element.
What this means is easily demonstrated in the following example (DEMO)
We have a simple div containing some text.
<div class="box">
Zarro boogs found!
</div>
Now we add some CSS selectors to the example.
div.box {
padding:0.8em;
background: #bd0000;
color: #fff;
}
.box {
color: #bd0000;
}
One of the most basic rules of CSS is that selectors can be redefined in a way that whatever definition comes last and has influence on a particular element its the one that is going to be used (the sole exception being when using !important which always takes precedence).
Now in the above example redefining the .box class selector should actually hide the text but instead its still visible. How is that possible if we said that latter rules always take precedence? Its because the div.box rule has a higher specificity that .box since it actually gets points for containing both an element (div) and a class selector (.box) in its selector declaration (div.box).
Of course the div.box rule will be applied only on a div element but since class selectors are often reusable pieces of code there is plenty of situations when they are used on divs.
Although the rules in the official W3 specification are not that hard to understand they are sometimes pretty hard to remember. That's why I would like to recommend an excellent article on CSS selector specificity which can be found here.
In my opinion selector specificity is by far the most important thing to master when it comes to tracing inheritance problems with CSS stylesheets.
.box means any element having class box.
Example:
<div class="box">...</div>
<section class="box">...</section>
<span class="box">...</span>
div.box means only div element having class box.
Example:
<div class="box">...</div>