Find first CSS class on page - css

I have a page full of elements. I simply just want to match the first element in my CSS selector.
I have tried sibling selector, first-child and first-of-type but they all only work in a structure where there are siblings. In my case I have different depths which makes it harder.
.match ~ .match {
background:red;
}
.match:first-child {
background: green;
}
.match:first-of-type {
background: yellow;
}
<div>
<ul>
<li>List item</li>
</ul>
<div>
<div class="match">Match - First match should be red</div>
</div>
<div class="match">Match</div>
<button></button>
<div>
<div>
<div class="match">Match</div>
</div>
</div>
</div>
It should find the first element with the class .match.
I will not accept answers like div > div > .match because then it does not find the element because we tell it where to look.

That is not possible with pure CSS. If the HTML is static, you can add an ID or another class, as Snake_py suggested. If you're okay with using a script, the document.querySelector method returns the first match of the selector, so you could do something like this: (see snippet)
document.querySelector('.match').classList.add('match-active')
.match-active {
background:red;
}
<div>
<ul>
<li>List item</li>
</ul>
<div>
<div class="match">Match - First match should be red</div>
</div>
<div class="match">Match</div>
<button></button>
<div>
<div>
<div class="match">Match</div>
</div>
</div>
</div>

Related

Css :not pseudo class is not taking effect

I want to use the :not pseudo class as an exception where the css should apply to everything except any element with a certain class including all its children elements.
But in my example, the :not selector is affecting everything, but only should affect the class inside the :not selector. I'm using chrome browser.
fiddle
SCSS:
.ql-editor :not(.not-ql-editor){
ul > li {
background:blue;
}
}
HTML:
<div class="ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
<div class="not-ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
</div>
I would have expected the top <ul><li> to have blue background, while the lower <ul><li> would not have a background because it has the .not-ql-editor class, but something seems wrong since no li elements get the background.
Update:
After the answer by Johannes I learned that the upper ul needs to be wrapped inside some element because the :not(.not-ql-editor) represents an element even if it doesn't match the selector.
But then I noticed that the "not-ql-editor" element has to be directly underneath the "ql-editor" element. My aim was to target a class at any level beneath "ql-editor".
Normally when you but a space between two selectors, the second selector should target elements at any level beneath the first one. Is this not the case with the :not selector?
update2:
Here is a modified version of the fiddle:
fiddle2
If the html looks like this (with the same css):
<div class="ql-editor">
<div>
<div class="not-ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
The li's become blue. Despite the css: .ql-editor :not(.not-ql-editor)
The problem in your code is that the first list is on a different "descendant level" than the second list: Your CSS selector is valid only for li elements inside a ul which is child of an element that does not have the .not-ql-editor which again is child of an element that has the .ql-editor class.
For this to work you need another div (or other) wrapper around your first ul:
.ql-editor :not(.not-ql-editor) ul>li {
background: blue;
}
<div class="ql-editor">
<div>
<ul>
<li>hello></li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
<div class="not-ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
</div>
ADDITION after comments and edit of question:
In the first code example you posted, your ul elements were on different descendant levels from the .ql-editor DIV element: The first ul was a directchild, the second one a grandchild, with the .not-ql-editor DIV as a wrapper between .ql-editor and the ul. My answer was directed at this situation, and it worked.
In the second code example you posted, you added another level: A DIV without any class in between the .ql-editor DIV and the .not-ql-editor DIV. This changes things. In the fiddle you added, the .not-ql-editor DIV is the direct parent of the ul. So you need to use that relationship to define a CSS rule that only applies if the ul is a direct child of a DIV that does not have the .not-ql-editor class.
in plain CSS that rule would be as follows:
.ql-editor *:not(.not-ql-editor) > ul > li {
background: blue;
}
Here's your second code example combined with that CSS rule in a snippet, The background does * not* become blue:
.ql-editor *:not(.not-ql-editor) > ul > li {
background: blue;
}
<div class="ql-editor">
<div>
<div class="not-ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
And here's your second fiddle with this CSS applied as SCSS: https://jsfiddle.net/e7d0h4yc/
You can do this with the original HTML you had. Since the top ul element and the div.not-ql-editor element are siblings, you can just attach the not rule to a wildcard element, and instead of targeting ul > li just target li
.ql-editor>*:not(.not-ql-editor) li {
background: blue;
}
<div class="ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
<div class="not-ql-editor">
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
</div>
</div>
.ql-editor :not(.not-ql-editor){
ul > li {
background:blue;
}
}
Correct this to remove the space between ql-editor and :not
.ql-editor div :not(.not-ql-editor){
background:blue;
}

Partial grouping of a CSS selector

I can't seem to find an answer to this so either it's not possible or i'm not wording my searches correctly - i'm hoping someone on here can help? :)
I have some HTML (UL in my example) who's grand-parent (div) occasionally has a sibling and occasionally doesn't. An example of this might be :
No Sibling Example
<section>
<div>
<div id="item">
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</div>
</section>
Sibling Example
<section>
<div id="sibling1">xxx</div>
<div>
<div id="item">
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</div>
<div id="sibling2">yyyy</div>
</section>
I want to select the UL element only when it's grandparent (div) has siblings.
I was going to use the preceding selector.. something like
section div div#item ~ ul
{
background: #ff0000;
}
but I cant seem to get it to work.
Any guidance greatly appreaciated!
section div~div div#item ul
{
background: #ff0000;
}
You need to select the parent div if it has a sibling. I'm not sure what your original selector was doing, but it was wrong.
Snippet with:
section div~div div#item ul
{
background: #ff0000;
}
<section>
<div id="sibling1">xxx</div>
<div>
<div id="item">
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</div>
<div id="sibling2">yyyy</div>
</section>
Snippet without:
section div~div div#item ul
{
background: #ff0000;
}
<section>
<div>
<div id="item">
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</div>
</section>
You can do this:
section>div:not(:only-child) ul{
background: red;
}
Here is a pen with two sections so you can see it works: http://codepen.io/vandervals/pen/qdqMvq
This has 2 advantages from the ~ method:
-It selects all ul from divs not only from one div.
-It is more readable.

Selecting the second occurrence of a class with CSS?

Given the following (dynamic) markup, I need to match the second occurrence of the class orange, regardless of how many divs have the class apple.
<div>
<div class="apple"></div>
<div class="apple"></div>
<div class="orange"></div>
<div class="apple"></div>
<div class="apple"></div>
<div class="orange"></div> <--
<div class="apple"></div>
</div>
Can it be done with CSS? Thanks.
You can use this with selectors level 3 to select those that aren't the first one :
.orange ~ .orange {
}
Demonstration
The best is to complete the style with a rule describing the other .orange elements :
.orange, .orange ~ .orange ~ .orange {
}
Demonstration
Select second instance of class in HTML like:
<div>
<ul>
<li class="classname">text</li>
<li>text</li>
...
<li>text</li>
<li class="classname">text</li>
<li>text</li>
</div>
Using this CSS (tested in Chrome).
div ul li.classname ~ .classname:not(.classname ~ .classname ~ .classname)
In this particular case :nth-child(2) or :nth-of-type(2) not works.

Why last-child isn't working?

I got a problem for you to solve, as you know.
I ripped off all my hair trying to figure out why the heck last-child isn't working.
I tried to remove border-right with last-child but for some reasons, it didn't work out.
Here's is the link
Your selector is #countdown .num:last-child.
Your HTML is
<ul ID="countdown">
<li> <div ID="days" class="num">00</div> <div CLASS="text">days</div> </li>
<li> <div ID="hours" class="num">00</div> <div CLASS="text">hours</div> </li>
<li> <div ID="mins" class="num">00</div> <div CLASS="text">minutes</div> </li>
<li> <div ID="secs" class="num">00</div> <div CLASS="text">seconds</div> </li>
<div class="clear"></div>
</ul>
Think: is .num the last child of its parent? Answer: no.
Your selector should be more like #countdown > li:last-of-type .num, selecting .num inside the last li in #countdown.
Note that in this case last-of-type must be used rather than last-child because you've got that <div class="clear"></div>, which is invalid HTML (you can't have a div directly inside a ul).
The main reason why the last-child is not working because in your #countdown UL the last-child is <div class="clear"></div> not LI. So it's better to use last-of-type instead of last-child. Like this:
#countdown li:last-of-type .num,
#countdown li:last-of-type .text{
border:0;
}
Check this http://jsbin.com/apuhep/4/edit#html,live
Inside your ul element, there is a div element after the last li element. This is invalid markup and may have unpredictable effects. Moreover, it probably makes browsers treat the div element the last child of the ul element.

CSS Last-Child Selector - affecting all my DIVs?

I have the following
CSS
.streamBox {
font-size:12px;
background-color:#EDEFF4;
border-bottom:1px solid #E5EAF1;
margin-top:2px;
padding:5px 5px 4px;
}
.streamBox:last-child {
border: none;
}
HTML
<ul id="activityStream">
<li class="story">
<div class="streamBox nobkgcolor" id="">
Stuff
</div>
</li>
<li class="story">
<div class="streamBox nobkgcolor" id="">
Stuff
</div>
</li>
<li class="story">
<div class="streamBox nobkgcolor" id="">
Stuff
</div>
</li>
</ul>
I thought the last-child selector would make it so the last DIV doesn't hav ea border... But instead all DIVs now don't have borders? y?
Suggestions on how w CSS to make it so JUST the last div doesn't have the border?
Thanks,
For updated question:
Your selector needs a tweak, it should be:
li:last-child .streamBox {
border: none;
}
The <div class="streamBox"> is both the first and last child of its parent, so your current selector matches all of them, instead you want the <div> inside the last <li>, so use the :last-child on the <li>, you can test it here (I changed the border to black to make it more obvious).
For previous question:
It's because you're missing a quote on the class="" attribute, fix it like this:
<div class="box">blah blah</div>
<div class="box">blah blah</div>
<div class="box">blah blah</div>
<div class="box">blah blah</div>​​​​
It'll then work as intended, the first 3 having borders, you can test it here.

Resources