nth-child selects everything - css

I'm trying to understand how the :nth-child works but don't understand why it is selecting everything below:
:nth-child(2) {
color: blue;
}
<div>
hello
<h1>test</h1>
<p>one</p>
<p>two</p>
<p>three</p>
<p>four</p>
</div>
<div>
<span>hey</span>
</div>
<p>hello</p>
test
Same happens when I do nth-child(1) but then nth-child(3) selects only "two" and "hello"
:nth-child(3) {
color: blue;
}
<div>
hello
<h1>test</h1>
<p>one</p>
<p>two</p>
<p>three</p>
<p>four</p>
</div>
<div>
<span>hey</span>
</div>
<p>hello</p>
test
Can somebody give me a walkthrough on how it's working so I can understand the concept?

you forgot something. nth-child is a selector is selecting one specific item in your same list.look HTML, the h1 element is the second child of its parent div element, so it is selected and its color is set to blue. The other p elements are also the second child of their parent div element, so they are also selected and their color is set to blue.
so if you need color the "hey" , you need to upgrade the code to ,
div:nth-child(2) {color :blue;}
you need color the "two", you need to upgrade the code to,
p:nth-child(2) {color :blue;}
you not done anything wrong. only you forgot select element in html.
I hope this help you.

You can inspect an element to find out where it's getting its styles from. In Firefox, right-click an element and click Inspect to bring up the Developer Tools (there is a very similar procedure for Chrome):
We see here that <h1> is inheriting the color property from the <body>, which is selected because it's the 2nd child of <html>. Likewise, with :nth-child(1), <html> is matched and everything will inherit color from that. It's smart to use :nth-child() only with a combinator targeting a specific parent/ancestor so you don't have unexpected inheritances like that.

Related

Why does nth-of-type not consider the class? [duplicate]

Is it possible to use the CSS3 selector :first-of-type to select the first element with a given class name? I haven't been successful with my test so I'm thinking it's not?
The Code (http://jsfiddle.net/YWY4L/):
p:first-of-type {color:blue}
p.myclass1:first-of-type {color:red}
.myclass2:first-of-type {color:green}
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
No, it's not possible using just one selector. The :first-of-type pseudo-class selects the first element of its type (div, p, etc). Using a class selector (or a type selector) with that pseudo-class means to select an element if it has the given class (or is of the given type) and is the first of its type among its siblings.
Unfortunately, CSS doesn't provide a :first-of-class selector that only chooses the first occurrence of a class. As a workaround, you can use something like this:
.myclass1 { color: red; }
.myclass1 ~ .myclass1 { color: /* default, or inherited from parent div */; }
Explanations and illustrations for the workaround are given here and here.
The draft CSS Selectors Level 4 proposes to add an of <other-selector> grammar within the :nth-child selector. This would allow you to pick out the nth child matching a given other selector:
:nth-child(1 of p.myclass)
Previous drafts used a new pseudo-class, :nth-match(), so you may see that syntax in some discussions of the feature:
:nth-match(1 of p.myclass)
This has now been implemented in WebKit, and is thus available in Safari, but that appears to be the only browser that supports it. There are tickets filed for implementing it Blink (Chrome), Gecko (Firefox), and a request to implement it in Edge, but no apparent progress on any of these.
This it not possible to use the CSS3 selector :first-of-type to select the first element with a given class name.
However, if the targeted element has a previous element sibling, you can combine the negation CSS pseudo-class and the adjacent sibling selectors to match an element that doesn't immediately have a previous element with the same class name :
:not(.myclass1) + .myclass1
Full working code example:
p:first-of-type {color:blue}
p:not(.myclass1) + .myclass1 { color: red }
p:not(.myclass2) + .myclass2 { color: green }
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
I found a solution for your reference. from some group divs select from group of two same class divs the first one
p[class*="myclass"]:not(:last-of-type) {color:red}
p[class*="myclass"]:last-of-type {color:green}
BTW, I don't know why :last-of-type works, but :first-of-type does not work.
My experiments on jsfiddle... https://jsfiddle.net/aspanoz/m1sg4496/
This is an old thread, but I'm responding because it still appears high in the list of search results. Now that the future has arrived, you can use the :nth-child pseudo-selector.
p:nth-child(1) { color: blue; }
p.myclass1:nth-child(1) { color: red; }
p.myclass2:nth-child(1) { color: green; }
The :nth-child pseudo-selector is powerful - the parentheses accept formulas as well as numbers.
More here: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
You can do this by selecting every element of the class that is the sibling of the same class and inverting it, which will select pretty much every element on the page, so then you have to select by the class again.
eg:
<style>
:not(.bar ~ .bar).bar {
color: red;
}
<div>
<div class="foo"></div>
<div class="bar"></div> <!-- Only this will be selected -->
<div class="foo"></div>
<div class="bar"></div>
<div class="foo"></div>
<div class="bar"></div>
</div>
As a fallback solution, you could wrap your classes in a parent element like this:
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<div>
<!-- first-child / first-of-type starts from here -->
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
</div>
Not sure how to explain this but I ran into something similar today.
Not being able to set .user:first-of-type{} while .user:last-of-type{} worked fine.
This was fixed after I wrapped them inside a div without any class or styling:
https://codepen.io/adrianTNT/pen/WgEpbE
<style>
.user{
display:block;
background-color:#FFCC00;
}
.user:first-of-type{
background-color:#FF0000;
}
</style>
<p>Not working while this P additional tag exists</p>
<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>
<p>Working while inside a div:</p>
<div>
<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>
</div>
I found something that works
If you have a bigger class which contains something like grid, all of elements of your another class
You can do like that
div.col-md-4:nth-child(1).myclass{
border: 1px solid #000;
}
Simply :first works for me, why isn't this mentioned yet?

:first-child not being applied

On this page, I want to hide the incorrect HTML displayed above the logo. It is generated by an old plugin we are replacing soon.
To start with, I tried the CSS:
.vine-home-block-grapes:first-child {display: none;}
but this does not remove the highlighted block below:
Can you help me determine why please?
Use css :first-of-type selector
.vine-home-block-grapes:first-of-type{
display:none;
}
That selector won't work as the element you are attempting to select is not the :first-child of its parent.
One way to do what you want is select all elements with that class name, set their styles as you wish and then, using a new rule with the sibling selector, override those styles for any element of that class appearing later in the parent.
.vine-home-block-grapes{
display:none;
}
.vine-home-block-grapes~.vine-home-block-grapes{
display:block;
}
Add this script. It would work fine without any problem:
<script>
var fourthChild = document.body.getElementsByTagName("div")[0];
document.body.removeChild(fourthChild);
</script>
Thanks to #FelixKling
Try wrapping the child elements in a <div> so the element can BE the first child of its wrapping element. Right now, your element is not the first child of <body> See the experiment here to show how :first-child doesn't work as expected, because really it's not the first child of its parent.
p:first-child {
background-color: aqua;
}
.vino:first-child {
background-color: lightgreen;
}
WORKS
<p>First</p>
<p>Second</p>
<p>Third</p>
DOESN'T WORK (because none of these are the first child of its parent, in this case, <body>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
Adding a wrapping div works.
<div>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
</div>

hide a div by clicking a non-parent div

In my site there're two different div, but they have the same parent div (two child div). So, I want to do this: div.1:hover -> div.2{display:none}. How can I do it using CSS?
Depending on the way your HTML is laid out it can work. The divs need to be next to each other like so:
<div class="first">
First div
</div>
<div class="second">
Second div
</div>
Then use this CSS:
div.first:hover + div.second { display: none; }
Fiddle here: http://jsfiddle.net/CyT2N/
You can easily accomplish that with JQuery.
$(document).ready(function(){$("#first").hover(function(){$("#second").hide();}, function(){$("#second").show();});});
Explanation:
this code adds a "hover" handler for the first element on document.ready, when the mouse enters we hide the second element, and when the mouse leaves, we show it again.
This way, it will work no matter where the elements are within the layout.
See here: http://jsfiddle.net/avrahamcool/RenK2/
Edit
If you want the second div to hide when the first one is clicked, use $("#first").click(function(){$("#second").hide();}) instead of hover(..)
See here: http://jsfiddle.net/avrahamcool/RenK2/1/
Here is a simple way of doing it:
If you have HTML similar to this:
<div class="wrap">
<div class="first">First div</div>
<p>some other element...</p>
<div class="second">Second div</div>
</div>
your CSS would be:
.first:hover ~ .second {
display: none;
}
Demo at: http://jsfiddle.net/audetwebdesign/HQN6n/
The one limitation that .first and .second must be sibling elements within the same parent element, .wrap in this example.
The general sibling combinator ~ is supported for IE7+
Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors

selector to match elements not nested within another selector?

I have a bunch of divs which I nest arbitrarily:
<div>
<div>
<div>Apple</div>
<div>
<div>Banana</div>
<div>Grape</div>
</div>
</div>
<div>Craisin</div>
</div>
I make their contents pink with a rule like this:
div { color: pink; }
I want to be able to add the special class to any of those divs to cancel out the pink rule for it and all of its children. For example, if I add the special class to this div,
<div>
<div class="special">
<div>Apple</div>
<div>
<div>Banana</div>
<div>Grape</div>
</div>
</div>
<div>Craisin</div>
</div>
then "Apple," "Banana," and "Grape" should no longer be pink.
Can I tweak my rule to only match divs that aren't nested inside a .special?
I'm not looking for a solution involves writing a rule for .special that cancels out every style defined on div. For example, this is not a good solution even though it works:
.special, .special div { color: black !important; }
My actual styles are more complicated than just changing the color, and there are other rules with selectors like div span which I would also like to disable with the special class.
You cannot prevent children/descendants from inheriting inheritable style properties using CSS.
The style properties for the descendants have to explictly be reset.

Tricky CSS conditional sibling > child selector > Can this be done?

In the markup below, I'm looking for a way (perhaps using css selector's) to style the content div differently depending on the presence of menu? Menu may or may not be present in that location in the markup and if it is there, I need to add some top margin to content.
I believe sibling and descendent selector rules might not go this far...
"When menu is present as a child of header set the top margin of content (whose parent is a sibling of header) to 100 pixels. Otherwise, set it to zero"
<div class="header">
<div class="sitetitle">site title</div>
<div class="tagline">tagline</div>
<div class="menu">menu</div>
</div>
<div class="main">
<div class="content">content goes here</div>
</div>
If css allowed groupings, I would do it this way...
(.header ~ .menu) + (.main > .content) {margin-top:100px;}
Not possible in your markup.
CSS selectors can only look at the ancestor and at the sibling axes. You cannot look inside ("what children do I have") - only upwards ("what are my parents") and sideways ("what's next to me").
Examples. This:
div.header div.menu
refers to any <div class="menu"> one of whose ancestors is a <div class="header">.
This:
div.header > div.menu
refers to any <div class="menu"> whose direct ancestor (i.e. "parent") is a <div class="header">.
This:
div.header ~ div.menu
refers to any <div class="menu"> that has a <div class="header"> among its preceding siblings, i.e. they have the same parent and occur one after another, but not necessarily adjacent to each other (that's "looking sideways").
This:
div.header + div.menu
refers to any <div class="menu"> whose direct preceding sibling is a <div class="header">.
There are no other traversing selectors in CSS (this statement refers to CSS2) and certainly there are no conditionals.
You could use jQuery:
​$('.header:has(.menu) + .main > .content')​.css('margin-top', '100px');​​​​​​​​​​​
Unfortunately the :has() selector didn't find its way into css3.
But why don't you simply apply a margin-bottom to div.menu?
You could possibly use some javascript to detect that. Check if menu is under header at load, and if it is, then set the margin-top of content to 100px
I used this CSS code in a conditional formatting.
Format index by counting from the end.
#stk-service-account-menu ul li:nth-last-child(1):before {

Resources