How do you make nth-child work with descendant selectors? - html

I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.

There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.

You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.

This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.

Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>

Related

How to exclusively style parent or child when hovering over either of them?

I have some very simple HTML that looks like
<div id="parent">
Child
</div>
I want to style the parent when hovering over the parent and I want to style the child when hovering over the child. I never want both to be styled at the same time.
I tried various combinations of :hover and :not() selectors in SCSS. Googling didn't bring me far; most solutions I found just tell me how to style the parent when hovering over the child, which is the opposite of what I want.
I found this and this workaround, both from 2013, but I was wondering whether there is a better, more modern way to do this.
If you only intend to support modern, evergreen browsers that support :has, then you can style #parent based on the following conditions:
is hovered
does not have a hovered child
That translates to a selector of such: #parent:hover:not(:has(#child:hover)).
In the example below, the #parent is red only when it is hovered and not its child:
#parent:hover:not(:has(#child:hover)) {
background: red;
}
#child:hover {
background: green;
}
<div id="parent">
Child
</div>

Why ::selection:first-child doesn't work?

Why this code doesn't work?
::selection:first-child{
background-color: #ffa563;
}
This works fine - :first-child:last-child (when element is first child AND last child)
::selection is not an element. try :first-child::selection should work.
:first-child::selection {
color: red;
}
<div>First Child</div>
<div>Second Child</div>
You mixing up pseudo class and pseudo element. ::selection is pseudo element, so it doesn't contain anything and only work with few css attributes.
If you want to style selection in first child, use :first-child::selection instead
When you try to use a selector like "::selection" or ":first-child" it´s better if you specify the container.
<div>
<p>text 1</p>
<p>text 2</p>
</div>
and the css:
div p:first-child::selection {
color: red;
background: yellow;
}
the first 'p' will show different if you select.
Note that :first-child will never adjust to the selectors listed before. For example, p:first-child will not match for a structure of <div><h1></h1><p></p></div> since the p is the second tag.
Similarly, a ::selection:first-child would also not match the first tag in the selection but only a selected element that is also a first child. And at that point, it’s equivalent to :first-child::selection.
As for why it doesn’t work, ::selection is a pseudo element. Using it creates some kind of an element that is matched. But that pseudo element never exists in the DOM, so it cannot be the first child of something. So the whole selector will not match.

How to apply style for first heading only if it more than one?

I may have two types of html...
One:
<div>
<h4></h4><!--not to this-->
<p></p>
</div>
Two:
<div>
<h4></h4><!--this should be styled--->
<h4></h4>
<p></p>
</div>
All styling are the same but just border-bottom to h4 of first h4 tag only if it contains two h4 tags as in the example. How to do without changing html?
You can combine :first-child, :not() and :only-of-type pseudo-classes to achieve that.
Here you go:
h4:first-child:not(:only-of-type) {
background-color: gold;
}
WORKING DEMO.
This selector represents the <h4> element which is the first child of its parent whereas it's not the only of TYPE of elements in the children tree of the parent.
From the MDN:
The :only-of-type CSS pseudo-class represents any element that has
no siblings of the given type.
Let's go Crazy!
If the <h4> element is not the first child of its parent, we can select the first <h4> element and achieve the same effect by using :first-of-type pseudo-class as follows:
h4:first-of-type:not(:only-of-type) {
background-color: gold;
}
UPDATED DEMO.
For further details on :first-of-type vs :first-child you can refer my answer here.
you need to style the border-bottom of your 1st h4 only if the parent contains two adjacent headings
you could then style the border-top of the 2nd h4 and obtain the same effect
h4 + h4 {
border-top: ...
}
When you have one heading only, no style will be applied. If you have two or more adjacent headings, a border between them will be applied
This is what you need:
h4:first-child:nth-last-of-type(n+2)
{
color:green;
}
FIDDLE
You can use the First-child class.
I could look like this:
div h4:first-child{
CODE HERE
}
I think you are better off styling the second h4 if possible, as you would not be able to tell with CSS whether there are one or two h4's in the div.
You can do this with nth-child
div h4:nth-child(2) {
// your styles.
}
Fiddle

css selector for first child element

Let's say my html looks like this:
<div class="container">
<... some html here ...>
</div>
I want to get the first direct child of .container.
I could do .container > div:first-child but that's assuming the it is a div which is not always the case.
Use the :first-child pseudo-class without a tagname:
.container > :first-child
This will grab any element that is the immediate first child, regardless of its tagname. This is similar to the way in which we use other pseudo-classes such as :hover which alone targets any element, while a:hover targets only the hover state of anchors.
Not using the element itself, but a class is a better solution and way more semantic for so many reasons.
And give the class to the children of the element, not only the container like this:
HTML:
<article class="container">
<p class="blah">First paragraph...</p>
<p class="blah">Lorem ipsum...</p>
<p class="blah">Dolor sit amet...</p>
</article>
CSS:
.blah {
background: red;
color: white;
}
.blah:first-child {
background: #000;
}
You can see it in action here: http://jsfiddle.net/Roobyx/ygP4B/

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>