Select div by contains with css - css

I have a simple markup and I would like to select a div by it's content. Here is my code...
<div class="parent">
<h4>Child of parent</h4>
<div>
<div>I'm red!</div>
<h4>I'm red's sister</h4>
<div>I'm blue!</div>
<h4>I'm blue's brother</h4>
</div>
</div>
and selecting <div>I'm red!</div> with the following CSS...
div:contains("I'm red!") {
color: red;
}
since contains() is deprecated or never got implemented, I can do the following...
.parent div:nth-child(1) {
color: red;
}
.parent dh4:nth-child(2) {
color: red;
}
to target just the first two elements, and it worked, but I would like to know if it is a way I can target just the first two element which happened to be <div> and <h4> in one CSS line of code? I need to do this without javascript. Eventually I need to target just 3rd and 4th.

Yes. Use :nth-child(-n+2).
For the 3rd and 4th you can use :nth-child(n+3):nth-child(-n+4) or just :nth-child(-n+4) and let specificity fix it for you.
The logic is easy:
:nth-child(-n+a) selects the a-th element and its previous siblings
:nth-child(n+a) selects the a-th element and its following siblings
:nth-child(n+a):nth-child(-n+b) selects the a-th and b-th elements, and the siblings in-between.
.parent > div > :nth-child(-n+4) {
color: blue;
}
.parent > div > :nth-child(-n+2) {
color: red;
}
<div class="parent">
<h4>Child of parent</h4>
<div>
<div>I'm red!</div>
<h4>I'm red's sister</h4>
<div>I'm blue!</div>
<h4>I'm blue's brother</h4>
</div>
</div>

I don't think I understand your question. You can do that to have it on one line anyway.
.parent div:nth-child(1), .parent dh4:nth-child(2) {color: red;}
or you could apply a red class on the first two divs and do :
.red{color:red}

Related

In CSS, how may I select elements which are *not* the descendants of a container element with a class conforming to a recognisable pattern?

Imagine that the HTML and CSS below is already set.
What CSS rules can I add beneath the already-written CSS to make the red paragraphs display as red?
body,
div {
display: flex;
flex-wrap: wrap;
}
p {
margin: 6px;
}
.one-filter-one p,
p[class^="one-filter-one"] {
color: blue;
}
.two-filter-two p,
p[class^="two-filter-two"] {
color: green;
}
.four-filter-four p,
p[class^="four-filter-four"] {
color: orange;
}
<p class="another-class">This is red.</p>
<p>This is red.</p>
<div class="one-filter-one">
<p>This is blue.</p>
<p class="one-filter-one--paragraph">This is blue.</p>
</div>
<p class="two-filter-two">This is green.</p>
<p>This is red.</p>
<p class="another-class-two">This is red.</p>
<div class="three-filter-three">
<p>This is unstyled (black).</p>
<div><p>This is unstyled (black) too.</p></div>
</div>
<div class="four-filter-four">
<p class="four-filter-four--sentence">This is orange.</p>
</div>
<p class="five-filter-five">This is also unstyled (black).</p>
<div class="another-class-three">
<p>This is red.</p>
<p class="another-class-four">This is red.</p>
</div>
My best guess is to use the :not() pseudo-class.
But I'm not entirely convinced this is the right approach, principally because I'm not sure that :not() can handle this case.
My attempt at a solution, using :not():
body,
div {
display: flex;
flex-wrap: wrap;
}
p {
margin: 6px;
}
.one-filter-one p,
p[class^="one-filter-one"] {
color: blue;
}
.two-filter-two p,
p[class^="two-filter-two"] {
color: green;
}
.four-filter-four p,
p[class^="four-filter-four"] {
color: orange;
}
p:not([class*="-filter-"]) {
color: red;
}
<p class="another-class">This is red.</p>
<p>This is red.</p>
<div class="one-filter-one">
<p>This is blue.</p>
<p class="one-filter-one--paragraph">This is blue.</p>
</div>
<p class="two-filter-two">This is green.</p>
<p>This is red.</p>
<p class="another-class-two">This is red.</p>
<div class="three-filter-three">
<p>This is unstyled (black).</p>
<div><p>This is unstyled (black) too.</p></div>
</div>
<div class="four-filter-four">
<p class="four-filter-four--sentence">This is orange.</p> </div>
<p class="five-filter-five">This is also unstyled (black).</p>
<div class="another-class-three">
<p>This is red.</p>
<p class="another-class-four">This is red.</p>
</div>
Clearly this is not it, because I am not correctly selecting:
NOT descendant elements of [class*="-filter-"].
But I'm not clear how to do this at all.
Is there any way to do this, or am I looking to achieve the impossible in 2020, given CSS's contemporary capabilities?
Notes:
Although, in 2020, the pseudo-class :not() has been around for the best part of a decade I've always tended to avoid using it. The only thing I do know is that the :not() pseudo-class function can only take simple (ie. not compound) selectors.
Added:
Based on #G-Cyrillus' brilliant suggestion (in the comments, immediately below), I have come up with the following:
body > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]) {
color: red;
}
On the plus side this does work. (So, infinitely better than anything I had before).
On the minus side:
it's verbose
it's inelegant
it only works to the fourth level of element-nesting
I can of course carry on adding levels, but that only makes it verboser and ineleganter
This has been a educational exercise.
The most significant thing it's taught me is that, given that :not() cannot accept compound selectors, it's very far from straightforward to handle subsequent nested levels of markup after applying :not().
Given the following:
.filter-1 {
color: red;
}
:not([class^="filter-"]) p {
color: blue;
}
<div>
<div>
<p>Test.</p>
</div>
</div>
<div class="filter-1">
<div>
<p>Test.</p>
</div>
</div>
the second <p> still shows up blue.
Why? Because even though its grandparent has the class .filter-1, its immediate parent does not... and that's enough to satisfy the any descendant selector (ie. the [SPACE]) preceding the p in the CSS Rule:
:not([class^="filter-"]) p
The only way to get around this is to replace the rule with:
:not([class^="filter-"]) > * > p
and this now works:
.filter-1 {
color: red;
}
:not([class^="filter-"]) > * > p {
color: blue;
}
<div>
<div>
<p>Test.</p>
</div>
</div>
<div class="filter-1">
<div>
<p>Test.</p>
</div>
</div>
But...
the CSS Rule is now tightly bound to the HTML structure and the amended CSS rule above won't now apply to:
<div class="filter-2">
<p>Test.</p>
</div>
See:
.filter-1 {
color: red;
}
:not([class^="filter-"]) > * > p {
color: blue;
}
<div>
<div>
<p>Test.</p>
</div>
</div>
<div class="filter-1">
<div>
<p>Test.</p>
</div>
</div>
<div class="filter-2">
<p>Test.</p>
</div>
Instead, we now need to use two rules:
:not([class^="filter-"]) > p,
:not([class^="filter-"]) > * > p
The following conclusion emerges:
We can only use :not() to exclude descendants when we also explicitly
describe the HTML structure in the CSS.
I now understand much more clearly what #G-Cyrillus meant by:
You need to mind the structure too
Next Steps:
Describing an infinite number of potential descendant structures in my CSS is clearly impractical, so I've:
1) reconfigured my architecture to allow more complex descendant relationships to be described elsewhere
and
2) optimised my exclusion query to:
body > :not([id^="filter-"]):not([class^="filter-"])
Thanks very much again, #G-Cyrillus - I've only made it as far as this due to your substantial assistance in the comment section.

Select one div after another css selectors [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have been trying to do this for a while and feel it should be fairly simple:
<div id = "container">
<div id = "item1" class = "item"> </div>
<div id = "item2" class = "item"> </div>
<div id = "item3" class = "item"> </div>
</div>
How can I select each item one after another and assign each a different background (without using ids)?
What I am trying to achieve:
#item1 {
background: red;
}
#item2 {
background: blue;
}
#item3 {
background: yellow;
}
<div id="container">
<div id="item1" class="item"> </div>
<div id="item2" class="item"> </div>
<div id="item3" class="item"> </div>
</div>
But isn't there a way to select each element in the #container div one by one, regardless of it's id value? By doing something such as the following :
.container:nth-child(1){ /*select first child of .conainter (#item1) ?*/
background: red;
}
or
.item:nth-of-type(2){ /*select second element of type .item (#item2) */
background: blue;
}
If you are trying to do this with only CSS:
.item:nth-of-type(1) { background: #fff}
.item:nth-of-type(2) { background: #000}
.item:nth-of-type(3) { background: #abc}
If you want to grab these after the fact using JS and/or jQuery:
jQuery(".item").each(function(i, el) {
if(i == 0) {
el.style.backgroundColor = "black";
} else {
el.style.backgroundColor = "red";
}
})
i here would be the index of your .item elements so you can target which one you need by this index (hence the conditional)
Also note that you need to set a height on the .item elements or add some content if you want to see the background color change. The height by default is 0
There are several ways to achieve this in CSS and JS. Below, is my variation I would normally use on client websites to achieve this background variation you are attempting to achieve:
#container div {width: 200px; height: 200px;}
#container div:first-child {background-color: red;}
#container div:nth-child(2) {background-color: green;}
#container div:last-child {background-color: blue;}
Im using first child and last childs on the first and last elements inside #container and then for the one in the middle i just tell the browser to find the second div inside #container.
Here is my HTML so my explination and CSS makes sense:
<div id = "container">
<div>ITS RED! </div>
<div>ITS GREEN! </div>
<div>ITS BLUE! </div>
</div>
Feel free to edit and play around with my code in a jsfiddle enviroment: https://jsfiddle.net/x9eouw7z/
For a static page you can use the :nth-child() selector like this:
https://jsfiddle.net/DIRTY_SMITH/6brcg9p7/3/
.item:nth-child(1) {
background: blue;
}
.item:nth-child(2) {
background: red;
}
.item:nth-child(3) {
background: green;
}

CSS style the last element in a document

In the following code I want to add styling specifically to the content of the last "B".
<div class="A">
<div>
I am <span class="B">foo</span>.
</div>
<div>
I like <span class="B">bars</span>.
</div>
<div>
Actually, call me <span class="B">FOOBAR</span>.
</div>
</div>
I have been trying
.B:last-of-type { color: red; }
and all classes "B" get selected because it uses the last occurence in it's immediate parents child elements. i.e. in it's direct siblings
Is there any way to only select the last occurence of "B" in the whole document?
You can do it like this
.A div:last-of-type .B { color: red; }
Fiddle Demo
or
.A div:last-child .B { color: red; }
Fiddle Demo
Try this JsFiddle Demo
.A div:last-child .B{ color: red; }
Found the answer! CSS3 get last element
I was doing a version of this but I found it ugly, I guess this is the only way. I will keep this Question open for a bit to see if anyone has any better suggestions.
.A span.B:last-child
{
background:#999;
}
.A div:last-child .B:last-child
{
background:orange;
}

Is there a CSS selector to locate the 2nd/3rd child or descendant (of a given class/id) under an element (with a given class/id)?

I have something along the lines of this
<div class="menu" style="background-color: transparent;">
<div class="button">
<div class="divider" style="background-color: transparent;"></div>
<a id="apple" class="unselect select" href="/apple">
<span class="apple1">Apple</span>
</a>
</div>
<div class="button">
<div class="divider"></div>
<a id="orange" class="unselect" href="/orange">
<span class="orange1">Orange</span>
</a>
</div>
....
this gives me the first divider
css=div.menu div.button div.divider
I am trying to access the 2nd divider. I have the need to access the buttons as well. I tried reading through the the nth child stuff and noticed that it is not compatible with IE.
Is there a CSS selector to locate the 2nd/3rd child or descendant (of a given class/id) under an element (with a given class/id)?
I am using xPaths now
//div[#class='menu']/descendant::div[contains(#class,'divider')][2]
it works but I want to migrate this to CSS.
The adjacent sibling selector + is able to do that and is compatible with IE7+
Fiddle demonstrating its use with 4 buttons: http://jsfiddle.net/AgNwu/
(no need for "div" if you rely already on id/class everywhere. If you call something "button", expect it to be a link, an input[type="submit|image|button|reset"] or button element ;) )
CSS
.menu > .button {
border: 1px solid darkblue;
padding: 10px;
margin: 5px 0;
}
.menu > .button + .button .divider {
background: Tan;
}
.menu > .button + .button .divider:after{
content: " (2nd or more)";
}
.menu > .button + .button + .button .divider {
background: yellow;
}
.menu > .button + .button + .button .divider:after{
content: " (3rd or more)";
}
edit: adjacent sibling, I thought this was sibling vs. general sibling
You can replace + by ~ (general sibling) if you have other type of nodes in-between your .button nodes/elements. This'd be the equivalent of :nth-of-type that would still work in IE7+
You can write like this:
div.menu div.button + div.button div.divider{
color:red;
}

How to reuse CSS selector?

I have the following CSS:
.foo .bar {
background: red;
}
Which works fine for the following HTML:
<div class="foo">
<div class="bar">I have a red background</div>
</div>
But I can't seem to find a way to reuse the CSS definition when I'm not in a parent/child relationship. For example, how could I apply the same CSS to the following DIV:
<div class="???">I want a red background!</div>
You can add additional selector with comma (,) as specified in W3C selectors grouping
.foo .bar, .foobar {
background: red;
}
this would work in both
<div class="foo">
<div class="bar">I have a red background</div>
</div>
and
<div class="foobar">I want a red background!</div>
You can use a comma to indicate multiple selectors that a CSS rule should apply to
.foo .bar, .??? {
background: red;
}
Use a comma separated list of selectors in the definition:
.foo .bar, .otherSelector, #someID{
background: red;
}
.foo .bar, .redback {
background: red;
}
will do a magic with
<div class="redback">I want a red background!</div>
or get rid of hierarchy and use only
.bar {
background: red;
}
which will work both cases
Try
.foo .bar, .foobar {
background: red;
}
with
<div class="foo">
<div class="bar">I have a red background</div>
</div>
<div class="foobar">I want a red background!</div>
The ".foo .bar" CSS definition is written expressly for a parent-child (more accurately ancestor-decendent) relationship.
You could write the CSS like this:
.alternate-background {
background: red;
}
and the HTML like this:
<div>
<div class="alternate-background">I have a red background</div>
</div>
which would allow you also to use this:
<div class="alternate-background">I want a red background!</div>

Resources