selecting nested first child element without sibling with css - html

I have a chunk of HTML I'm unable to edit (without using JavaScript).
I'm trying to hide a paragraph with CSS. The paragraph doesn't have an id. Is there any way to target only it and not its sibling <p> with CSS?
HTML:
<div id="foo">
<div></div>
<p> this is the paragraph to hide</p>
<p> this one should not be affected</p>
</div>

It depends on your markup structure. If the <p> is the first child of its parent, you can use :first-child pseudo-class as follows:
#foo p:first-child { /* or simply #foo :first-child */
background-color: gold;
}
WORKING DEMO
Note: If you want to select only the direct <p> child, you should use the children selector (a > b) as: #foo > p:first-child.
But if there are other siblings before the first <p> element, you can use CSS3 :first-of-type pseudo-class to select the first <p> element in the children tree of its parent:
#foo p:first-of-type {
background-color: gold;
}
WORKING DEMO
Again, for the direct child, you can use #foo > p:first-of-type.
From the MDN:
The :first-of-type CSS pseudo-class represents the first sibling of
its type in the list of children of its parent element.
You can refer to my answer for further info.

It's the first child of its parent, so you can unambiguously select that:
#foo > p:first-child

Related

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.

css :not selector to target everything but a condition

http://jsfiddle.net/m7qLdstp/1/
<style>
:not(div p), p{
color: red
}
</style>
<p>This is a paragraph that should be red.</p>
<div><p>This is a paragraph that should not be red.</p></div>
Is it possible to use the css :not selector to (in this case) turn all <p> color red, except for any <p> instead a <div>?
I ran a few different variations on jsfiddle but cannot get it to work?!
The following will change the color of all <p> elements that are not direct descendants of a <div>:
:not(div) > p{
color: red;
}
Demo fiddle
You could just target them separately
p{
color: red
}
div p{color:black}
fiddle
it works because div p is more specific than p
According to CSS-Tricks, :not() selector can take only a "simple selector", defined as:
a Type Selector, Universal Selector, Attribute Selector, Class Selector, ID Selector, or Pseudo Class Selector
but:
may not contain additonal selectors or any pseudo-element selectors.
However, as other answers suggest, there are ways you could work around this issue and accomplish the behavior at least in this example case and other simple cases.

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 subchild selector

Both of the following codes seem to work properly to style the span element:
<style>
div p span {
font: 18px arial;
color: red;
}
</style>
<div>
<p>
<span>
Hello, world!
</span>
</p>
</div>
<style>
div span {
font: 18px arial;
color: red;
}
</style>
<div>
<p>
<span>
Hello, world!
</span>
</p>
</div>
But I'm not sure if the second one is the right coding and if there's a difference between them, for example regarding browser support.
Neither of them is a “subchild selector”; there is no such concept in CSS. They are different descendant selectors, or descendant combinators as they are called in the Selectors Level 3 specification. Their meanings are different, so it depends on the purpose which one is better.
The selector div span matches any span element that is a descendant of a div element. The selector div p span matches any span element that is a descendant of a p element that is a descendant of a div element. Both selectors are rather theoretical as such; they are hardly useful in practical situations without some additional components such as class selectors.
They both work because the elements selected by div p span are a subset of the ones selected by div span.
If you include a <span> as a child of the <div>, the second one will select it, but the first one will not. If you don't include a <span> as a child of the <div>, they will select exactly the same elements.
For example:
<div>
<span>Only the second selector will make this text red</span>
<p>
<span>Hello, world!</span>
</p>
</div>
Well, it really depends on the context. For example, this selector...
div p span
will only apply to all span elements that are children of a p element which in turn, are children of a div element. Consider, this html...
<div>
<span class="title">Title</span>
<span class="desc">Description</span>
<p>
<span>Content</span>
<p>
</div>
the following css declaration will color the content span in blue
div p span
{
color:Blue;
}
however the style is not applied to the title and the description because they are not children of a p element. Now by using this css declaration...
div span
{
color:Blue;
}
will cause both the title, description and the content to be coloured in blue because this selector targets all span elements that are nested within a div element
As for performance, that's hard to determine because it all depends on implementation and how well different browsers traverse through a DOM hierarchy and apply the style. But, I'd guess that the more specific you can be the better so that the HTML parser can target elements directly. With that in mind, this css selector...
div p span
should perform faster than
div span
because it will cause the rendering engine to look for all div element, then p elements ignoring all other elements (including span elements that are direct children) and finally it'll look for span elements
both of them will work but
div p span {
font: 18px arial;
color: red;
}
is more correct, and you are less likely to have problems like when you decide to add a span in an li for some other possible purpose.
div > p > span {
font: 18px arial;
color: red;
}
First method is correct way.The styles work only span that inside of the p tag and you can give/edit/change specific styles on this item ...but the second method's style work all span inside of div tag..

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

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>