CSS not() with attribute selector doesn't seem to work - html

I have a very simple selector that works, but when adding it to a :not() it no longer seems to recognize it.
h2:not([random-attribute~="value"] h2){
color: red;
}
[random-attribute~="value"] h2{
color: blue;
}
<div class="content">
<h2>Same valid selector, not working</h2>
<div random-attribute="value">
<h2>Valid selector turned blue.</h2>
</div>
</div>
From what I understand, if you put a valid selector inside the not() you will get any h2 element that is not whatever is inside the parenthesis. This is intuitive.
What isn't intuitive, is that the selector within the not() is valid and works when used alone, but when added to the not() it doesn't seem to work.
Is this not a valid way to write this?

You need to style all h2 element that are descendants of elements that are not [random-attribute~="value"] then style h2 that are.
It doesn't hurt to qualify the selector with a direct child combinator too.
Like so:
*:not([random-attribute~="value"]) > h2 {
color: red;
}
[random-attribute~="value"] > h2 {
color: blue;
}
<div class="content">
<h2>Same valid selector, not working</h2>
<div random-attribute="value">
<h2>Valid selector turned blue.</h2>
</div>
</div>
<h2>some other heading</h2>

You have the syntax wrong for ([random-attribute~="value"] h2) It should just be ([random-attribute~="value"]). See below:
h2:not([random-attribute~="value"]){
color: red;
}
[random-attribute~="value"] h2{
color: blue;
}
<div class="content">
<h2>Same valid selector, not working</h2>
<div random-attribute="value">
<h2>Valid selector turned blue.</h2>
</div>
</div>
You are only supposed to put the given attribute in :not(), not the actual element.

In Selectors Level 3, :not only supports a simple selector argument. That will probably change in Selectors Level 4, but browsers don't support it yet.
The negation pseudo-class, :not(), is a functional pseudo-class
taking a selector list as an argument. It represents an element that
is not represented by its argument.
Note: In Selectors Level 3, only a single simple selector was allowed
as the argument to :not().
Meanwhile, you can rewrite
h2:not([random-attribute~="value"] h2)
as
:root:not([random-attribute~="value"]) > h2,
:root:not([random-attribute~="value"]) > :not([random-attribute~="value"]) > h2,
:root:not([random-attribute~="value"]) > :not([random-attribute~="value"]) > :not([random-attribute~="value"]) > h2
/* ... repeat until you get deep enough */
However, instead of using complicated selectors like that, in CSS it's more natural to let the cascade pick the most specific styles. As kristóf baján recommends, you don't even need :not:
h2 {
/* Default styles */
}
[random-attribute~="value"] h2 {
/* Overriding styles */
}

I think you are making your job a little too complicated... :)
You should just use:
[random-attribute="value"] h2{
...
}
h2 {
...
}
This should solve your problem. The reason behind the fact that it is not working as YOU would expect it to is that the selector inside the not operator is supposed to extend the clarification of the element and not its parent.

Related

Why doesn't css :not work in some cases?

Why does the :not selector not work at all in this case:
a {
color:red;
}
div a:not(.special a) {
color: green;
}
In, for example:
<div>
<span>hellolink</span>
</div>
<div class="special">
<span>hellolink</span>
</div>
<p>
something else
</p>
Demo: https://jsfiddle.net/eguecrvz/
:not() currently doesn't allow combinators or any more than one simple selector (such as .special or a) as an argument. A future specification will expand :not() to accept any number of complex selectors, and once browsers support it your selector div a:not(.special a) will work exactly as intended.
In the meantime, it is not possible to write a selector for "an a element that does not have a .special ancestor element." You will need to override with an additional .special a selector in your rule that applies to a elements in general:
a, .special a {
color:red;
}
div a {
color: green;
}
The additional specificity of .special a will ensure that it overrides div a, but if specificity is a problem you will need to rearrange your rulesets.
special is class of div not anchor.
Change css like:
div:not(.special) a{
color: green;
}
Fiddle
Edit:
If you want all link green except .special the do like:
a {
color:green;
}
.special a{
color: red;
}
Updated Fiddle
Why doesn't css :not work in some cases?
div a:not(.special a) {
color: green
}
Because the negation pseudo-class (:not) only takes a simple selector as an argument.
Your argument (.special a) represents a descendant selector which does not qualify.
6.6.7. The negation
pseudo-class
The negation pseudo-class, :not(X), is a functional notation taking
a simple selector (excluding the negation pseudo-class itself) as an
argument. It represents an element that is not represented by its
argument.
What is a simple selector?
4. Selector syntax
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.

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 use first-child?

I would like to select the first div called "aProduct" but I'm a bit confused on how to do this. I already tried this:
<div id="kasticketProducts">
<div class="aProductHeader"></div>
<div class="aProduct"></div>
<div class="aProductHeader"></div>
<div class="aProduct"></div>
</div>
This is my current CSS:
#kasticketProducts:first-child .aProduct {
margin-top: 30px;
background: red;
}
#kasticketProducts:first-child .aProduct
Using above css means first it'll search for id with kasticketproducts in that first-child, here first child refer to aProductHeader from here you are trying to search aProduct but it is not there.
Actually from DOM hierarchy aProduct class div is at second child this will be referred in css as nth-child(2) here and no need of again .aProduct .So the final solution for this is write as #kasticketProducts div:nth-child(2)
First, whats the difference?
From MDN :
:first-child()
The :first-child CSS pseudo-class represents any element that is the first child element of its parent.
:first-of-type()
The :first-of-type CSS pseudo-class represents the first sibling of its type in the list of children of its parent element.
So inshort, :first-child() is somewhat a loose pseudo selector compared to :first-of-type()
Unfortunately :first-child or :first-of-type doesn't respect classes or ids, they are only concerned with the DOM elements. So if you do something like, will fail
#kasticketproducts div.aProduct:first-of-type {
color: red;
}
So in this case the best you can do with CSS is use :nth-of-type() with 2 as a value, now obviously it will fail if your element doesn't have a class of aProduct
#kasticketproducts div:nth-of-type(2) {
color: red;
}
Demo
OR
you can use adjacent selector with :first-of-type()
#kasticketproducts div:first-of-type + div {
color: red;
}
Demo
Second solution is MORE COMPATIBLE as far as IE is concerned
DEMO
Code is not working because aProductHeader class is before first occurrence of aProduct class.
See demo.
You can't target the first element of a class, but you can target the elements that come after, so you can set the styles on all the aProduct elements and then override it on all aProduct that comes after the first one using the ~ opreator:
#kasticketproducts .aProduct {
margin-top: 30px;
background: red;
}
#kasticketproducts .aProduct ~ .aProduct {
margin-top: 0;
background: none;
}
Demo: http://jsfiddle.net/a9W5T/
You can use
:first-child, :nth-of-type(1), :first-of-type or :nth-child(1n)
And why your code donst work, is because you use:
#kasticketProducts:first-child .aProduct
this will take the first element #kasticketProducts, use this instead: #kasticketProducts .aProduct:nth-child(2) {
color: red;
} <-- This will take the first element .aProduct inside your ID element
Another solution would be to style .aProduct, and then override the style for any succeeding occurrences of .aProduct using the general sibling combinator:
#kasticketProducts .aProduct {
// effectively becomes the style for the first occurrence of .aProduct
}
#kasticketProducts .aProduct ~ .aProduct {
// overrides the style set above for all occurrences of .aProduct,
// apart from the first
}
The biggest advantage of this approach is that it doesn't rely on the structure of the markup.
General sibling selectors on MDN
Here's an example
Check the #id, it's case sensitive
Also, be careful with quotes, you are not closing them.
<div id="kasticketProducts">
<div class="aProductHeader">aaa</div>
<div class="aProduct">aaa</div>
<div class="aProductHeader">aaaa</div>
<div class="aProduct">aaa</div>
For the first .aProduct get selected:
#kasticketProducts .aProduct:nth-child(2) {
/* your styles */
}
Sorry for that, thought was for getting the first kasticketProduct. Apologizes.

How to style for first-child of a certain type of element?

For example, I have HTML like :
<div class='page'>
<span>2</span>
<span>2</span>
<a>1</a>
<a>6</a>
</div>
How can I style for first child a
I used like this : .page a:first-child {color:red}
but it doesn't run.
Use first-of-type instead of first-child
.page a:first-of-type{
color:red;
}
The :first-of-type CSS pseudo-class represents the first sibling of its type in the list of children of its parent element.
Taken from MDN Documentation. You can find more details & examples here.
Explanation : :first-child not working as expected
As Pranav c said, you can use
.page a:first-of-type { ... } or .page a:nth-of-type(1) { ... } but neither of them will work in IE8
So if we can assume that the <span> is always going to be there, then
.page span+a { ... }
will ensure that only the first a after the span will be styled and this is as good as you can get cross-browser right now.
Example: FIDDLE

Select the first <h3> element after a class definition

I have the following code:
<div class="wrapper">
<div class="location info">
<h3>Location</h3>
<h3>should be no stlye</h3>
</div>
<div class="skills info">
<h3>Skills</h3>
<h3>should be no stlye</h3>
</div>
</div>
I'm trying to style the first h3 element after an info class. I thought this should work, but it dosen't:
.info:first-child {
color: color: rgb(200,50,50);
}
Why isn't this working? How should I style the first element in . info without adding extra markup in the html?
You need a space:
.info :first-child
The first-child pseudo element describes the element itself, not the children of the element. So, without the space you are selecting elements with a class of info that are the first child of their parent.
The space specifies that you are looking for descendants of .info. Since you are looking for just direct children, you should use the child combinator - >, and probably also specify only h3 elements:
.info > h3:first-child
Edit: I only noticed the problem with the selector. As mentioned in other answers (+1 to user1479606), you have a typo in your style definition as well: color: color: ... should be color: ....
You're not far away, try this:
.info > h3:first-child {
color: rgb(200,50,50);
}
But instead of using something like this, I believe the best approach would be to add a meaningful class to the first h3 - this will make reading the CSS and markup much easier in the future and it will prevent unexpected behavior when editing your markup. For example:
.info-title {
/* your styles here */
}
Your css is not correct, you only need to specify color once. You also need to make a more slightly change to your selector:
.info > h3:first-child {
color: rgb(200,50,50);
}
Demo: http://jsfiddle.net/WSZcS/
I'm trying to style the first h3 element after an info class.
.info > h3 {
color: rgb(200,50,50);
}
If your h3 tag is not the first child element you can use
.info > h3:first-of-type {
color: rgb(200,50,50);
}