If you have this HTML
<div>
<span class="style-me">i want to be styled</span>
</div>
<div class="ignore-my-descendants">
<span class="style-me">i want to be styled but my parent prevents it</span>
</div>
then this CSS selector
.style-me:not(.ignore-my-descendants *) {
color: red;
}
will not match anything. Maybe because :not() only accepts simple selectors which is not given here (I'm not sure, hope you can tell me the true reason).
Is there a pure css way to filter out those elements that have a parent matching a given criteria?
EDIT: i don't want to apply any values to the elements to be ignored.
This is important because the desired display property value of an element cannot be foreseen.
umm... you are selecting a child and asking to match its parent. Won't work
There is an easy way
.style-me {
color: red;
}
.ignore-my-descendants .style-me {
color: white;
}
Related
This question already has answers here:
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Closed 2 years ago.
span {
color: purple;
}
.title {
color: blue;
}
.title:nth-of-type(2) {
color: red;
}
<span class="title">Test #1</span>
<span>Some text</span>
<span class="title">Test #2</span>
In the above simple example, why is the text Test #2 not in red color? It is the second child of a parent and is declared as a title class too. If I delete the second row <span>Some text</span>, it is selected though.
This is not possible in css. You can style a specific element by it tag (e.g.<p>) but you can't style a specified element by counting its class. This happens because CSS selects the <p> element that is the specified appearance of the paragraph type within its parent and it skips other elements when counting. But this is not possible to count elements with a certain class name.
So as described above this isn't possible in CSS. If you are looking for a CSS only answer and based on your markup you can do something like this.
Example 1
.title ~ .title {
color: red;
}
Example 2
span:nth-of-type(3) {
color: red;
}
Here is a great article on this topic.
This can be done easily with JS.
I hope I have been helpful
var x = document.getElementsByClassName("title");
x[1].setAttribute("style", "color: red;");
<span class="title">Test #1</span>
<span>Some text</span>
<span class="title">Test #2</span>
You can't set a class with the nth-of-type() selector. You can only set its parent.
Suppose if I say {.title:nth-of-type(odd)}, then we are selecting all those parent elements which are odd in the count and have class as "title".
Now, in your case:
By {.title:nth-of-type(2)}, it understands that you are selecting 2nd of the type span(which is the parent here) and which have class as "title".
So no element will get selected here.
I hope you understood.
Structural pseudo-classes
W3.ORG
Selectors introduces the concept of structural pseudo-classes to permit selection based on extra information that lies in the document tree but cannot be represented by other simple selectors or combinators.
Standalone text and other non-element nodes are not counted when calculating the position of an element in its list of siblings; index numbering starts at 1.
According to developer.mozilla.org
The :nth-of-type() CSS pseudo-class matches elements of a given type (tag name), based on their position among a group of siblings.
That means it high Specificity for take to matches elements . for the reason it will not work.. if you want expected result you need to write below code..
title:nth-of-type(3) {
color: red !important;
}
The nth-of-type pseudo-class is specified with a single argument, which represents the pattern for matching elements.
.title:nth-of-type(2) means while it is 2nd type element, and it have a title class.
but This has no effect, because the .title class is on the 3th span element, not the 2nd.
but if you remove the second element, the .title class becomes 2nd element, so :nth-of-type(2) works on the text Test #2
to make it easy
when webpage see this code .title:nth-of-type(2)
<span class="title">Test #1</span>
<span>Some text</span>
<span class="title">Test #2</span>
let's see what is the element it have a class .title?
oh there's two!
first and third.
but because of this :nth-of-type(2) it have to be a second type element.
oh it is this --> <span>Some text</span>
huh, but it doesn't have a .title class!
--> so no element got selected
according to MDN https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type
The :nth-of-type() CSS pseudo-class matches elements of a given type (tag name), based on their position among a group of siblings. :nth-of-type( )
where
= | even | odd
so you need to change your css code from
span {
color: purple;
}
.title {
color: blue;
}
.title:nth-of-type(2) {
color: red;
}
to bellow code
span {
color: purple;
}
.title {
color: blue;
}
.title:nth-of-type(3n) {
color: red;
}
the second way you can do.
span {
color: purple;
}
.title {
color: blue;
}
.title:not(:first-child) {
color: red;
}
Is it possible to add conditional formatting to change class on using hover effect on a div:
.resize:hover {
height: 360px;
z-index: 1;
.font_white {
color: blue;
}
}
.font_white{
color: white;
}
Is it possible to override font_white while hovering div with resize class? These classes are independent div's.
No it's not, not using pure CSS that is.
You can use JS, but without the code of your markup, it's hard to say what the best way is.
(Of course, if the font color is to be applied inside the div you hover, it is doable using CSS only, although not the way you describe it. But I assume you want to trigger style changes across the page by hovering a div.)
There is no generic way to achieve that with CSS.
If you can write a selector that matches both the element that is a member of the resize class and the element that is a member of the font_white class (which you would do using a combinator such as descendant, child or sibling) then you can use the combinator to achieve it.
For example:
.resize:hover ~ .font_white { ... }
would work if your HTML looked something like:
<button class="resize">Hover Me</button>
<section id="first">...</section>
<section id="second" class="font_white">...</section>
<section id="third" class="font_white">...</section>
You would need to select apropriate combinators for your particular HTML.
If you rewrite your CSS, you'll see that your desired effect is possible - and achievable without redefining the style declarations of your class.
Example:
.primary-text {
color: white;
}
.resize:hover {
height: 360px;
z-index: 1;
}
.resize:hover .primary-text {
color: blue;
}
How can I set the style of only the first div that has class "bla"? (not the second).
<div class="outer">
<div>
....(more div's, unknown how many)
<div class="bla">
....
<div class="bla">some content</div>
</div>
....
</div>
</div>
I'm assuming with this answer that by adjacent elements you mean sibling elements. If you were referring to parent-child elements then go with N1xx1's answer. That being said...
You can't target the first bla with css selectors alone. But you can target all the blas but the first. So, one possibility is to set the styles you want only on the first bla on all blas. Then override those styles by targeting all blas but the first. Like so:
.bla {
...styles for the first bla..
}
.bla ~ .bla {
...override styles set on first bla that you dont want on the others
}
The tilde between the two ".bla"'s is called the general sibling selector. If you've never heard of it, head on over to css selectors spec.
You can do simple workaround for this since you can't do that with any special selector:
.bla {
/* style here, example: */
background-color: #f00;
}
.bla .bla {
/* negate the style, example: */
background-color: transparent;
}
I hope this is what you were looking for.
According to pure css, you can't select according to the ordering of the html elements. Search the spec (here: http://www.w3.org/TR/CSS2/selector.html). There is nothing that refers to how many or in what order html elements match the given selectors.
Javascript:
getElementsByClass('bla')[0].style
EDIT: JOPLOmacedo provided a CSS only (better) answer
I've also found a way to select for instance the second <p> after a <h1> tag:
h1 + p + p{
background: red;
}
Just thought I'd share that.
I created fiddle to show the example: I think I am setting parent CSS and then I apply the child's CSS. But it seems like it is being ignored.
http://jsfiddle.net/8PWNw/2/
<div id="displaybox" class ="displaybox" style="display: none;">
<div class = "parent" >
Parent 1
</div>
<span class ="child" style="padding: 0 10 ">Child 1</span>
<div class = "parent" >
Parent 2
</div>
<span class ="child" style="padding: 0 10 ">Child 1</span>
</div>
Please advise. I am new to CSS, so there are many things that I need learn.
Line 23 in your CSS:
/* this is actually saying element with both 'parent' and 'a' class */
.displaybox .parent.a {
color: black;
}
You probably meant:
/* this is actually saying all 'A' elements within element with 'parent' class */
.displaybox .parent a {
color: black;
}
That is why your 'A' element style is being ignored.
padding: 0 10 isn't valid (use a validator) so browsers are required to ignore it.
Lengths, other than zero, must have units (such as px or em).
You shouldn't be able to tell this though, since display: none hides everything.
Your class displaybox is set on display: none, which basically hides the entire container.
On another note, you use classes parent-child, but your children aren't nested properly into their parents. You need to put them before the end </div> tags so they be a part of that container.
I edited your fiddle and this should work now: http://jsfiddle.net/8PWNw/
This is what I changed:
I removed the display:none so your displaybox is shown again. I then changed some CSS:
Changed this, because your syntax didn't work before. The "." indicates you're addressing a class, in this case class displaybox with a child class parent, and you want to address all a elements in that class.
.displaybox .parent a
{
color: black;
}
I also added this one so you're links are showing as white:
.child a
{
color: white;
}
With those changes, you should be able to get it working like you want.
You may have multiple classes on an element separated by a space:
<div class="header contaminated">...</div>
and you can target that div using .header.contaminated selector.
That's fine when both classes are directly applied to an element. i want to target an element with CSS that has both styles, but one style comes from the parent:
Example
<div class="contaminated">
<div class="header">...</div>
</div>
Normally i want to style a header as blue:
.header { background-color: #99FFFF; }
But if a div is contaminated then i color the entire background red:
.contaminated { background-color: Pink; }
.contaminated.header { background-color: HotPink; }
Except i don't think the css selector syntax .contaminated.header is valid for "inherited" styles.
Note: The reason i don't think it's valid is because it doesn't work
Is it possible to target an element with CSS if it only contains two classes, and some of the classes are "inherited" ?
jsFiddle sandbox
This is basic CSS - separate the class names by a space, that implies/applies the cascade:
.contaminated .header { ... }
Anything wrong with that?
Cheers
I'm confused as to your question, wouldn't this do it?
.contaminated .header { background-color: HotPink; }
Notice the space, saying "look for an element with a class of .header within an element with a class of .contaminated"
.contaminated>.header{}
will only target element header that are direct children of .contaminated