CSS multiple :not doesn't work as expected - css

I have the follow code:
a {
color: black
}
a:not(.test1) {
color: red
}
a:not(.test1):not(.test2) {
color: green;
}
a.test {
color: blue
}
<a class='test'>
TEST
</a>
Why the result is green? I expected the result color will be blue

The selectors a:not(.test1):not(.test2) are more specific than just a.test.
If you inspect the element and view the declared styles you will notice that both styles are applicable but the rule with more specificity wins.
You can resolve this issue declaring another pseudo-class to account for a.test as well, e.g:
a:not(.test):not(.test1):not(.test2) {
color: green;
}
However, consider avoiding over-qualifying style rules by declaring them too specifically whenever possible.
:not() - CSS | MDN (Syntax reference)
Code Snippet Demonstration:
a {
color: black
}
a:not(.test1) {
color: red
}
a:not(.test):not(.test1):not(.test2) {
color: green;
}
a.test {
color: blue
}
<a class='test'>
TEST
</a>
<br>
<a class='test1'>
TEST 1
</a>
<br>
<a class='test2'>
TEST 2
</a>
<br>
<a>
TEST (no class)
</a>

Related

How does CSS inherit behave? [duplicate]

This question already has answers here:
What is use of 'initial' value in CSS?
(3 answers)
What's default HTML/CSS link color?
(12 answers)
Closed 2 years ago.
I have seen an example in MDN lesson about inheritance, and I can't understand why the third link's color is black? it should be blue, like a usual link, because the initial value supposes to be the default value!
Thank you for helping me.
Here is the code:
body {
color: green;
}
.my-class-1 a {
color: inherit;
}
.my-class-2 a {
color: initial;
}
.my-class-3 a {
color: unset;
}
<ul>
<li>Default link color</li>
<li class="my-class-1">Inherit the link color</li>
<li class="my-class-2">Reset the link color</li>
<li class="my-class-3">Unset the link color</li>
</ul>
it is because the initial color of attrubutes are black, same with
here is an example from w3schools where they set the color of the division to red, but using initial resets h1 to the base color of attributes.
div {
color: red;
}
#initialH1Color {
color: initial;
}
<div>
<h1 id="initialH1Color">this will be initial color</h1>
<h1>this will be div color: red</h1>
</div>
here is an example of inherit
div{
background: #333;
border: 5px solid orange;
color: lime;
}
.initial {
color: initial;
}
.inherit {
color: inherit;
}
<div>
<h1 class="initial">class initial</h1>
<h1 class="inherit">class inherit</h1>
<h1>no class</h1>
</div>
as you can see here class inherit and no class are the same color, that is because inherit is the automatic/normal/basic/initial value for color
The inherit keyword specifies that a property should inherit its value
from its parent element.
UPDATE
the reason for the a attribute beeing blue by default (which it is not, it is black). is because it is a link. take a look at the example
<a>no href tag = black</a>
has href tag = blue
<a href="#" >same with this one</a>

How to change external links color inside class

is possible change color external links inside some class? I tried this:
.space-page-content a {
background: green;
color: white;
}
.space-page-content a[href^="http://"]:not([href*="mywebsite.com"]):after,
.space-page-content a[href^="https://"]:not([href*="mywebsite.com"]):after{
background: blue;
color: white;
}
<a style="space-page-content" href="http://www.mywebsite.com/page-1/" >internal</a><br>
<a style="space-page-content" href="http://www.google.com" >external</a><br>
<a style="space-page-content" href="http://www.mywebsite.com" >internal</a>
You have some errors in your CSS and HTML code,
in CSS .space-page-content defined as class, while in your HTML its something else.
also when your write like this .space-page-content a , this means that a is a child inside your parent .space-page-content. But in fact, your HTML says that this class is given to a, so you should say select 'a' that has class 'space-page-content' by this way a.space-page-content without any spaces between a and your class.
you want to change the background of your a , so no need to add :after.
a.space-page-content{
background: green;
color: white;
}
a.space-page-content[href^="http://"]:not([href*="mywebsite.com"]),
a.space-page-content[href^="https://"]:not([href*="mywebsite.com"]){
background: blue;
color: white;
}
<a class="space-page-content" href="http://www.mywebsite.com/page-1/" >internal</a><br>
<a class="space-page-content" href="http://www.google.com" >external</a><br>
<a class="space-page-content" href="http://www.mywebsite.com" >internal</a>

CSS selector but not when another class is present

How does one select the class jdgm-paginate__page unless jdgm-paginate__next-page is also applied to the element?
<a class="jdgm-paginate__page " data-page="2">2</a>
<a class="jdgm-paginate__page jdgm-paginate__next-page" data-page="2"></a>
Use the :not() pseudo-class:
.jdgm-paginate__page:not(.jdgm-paginate__next-page):not(.jdgm-paginate__last-page) {
color: red;
}
a {
display: block;
}
<a class="jdgm-paginate__page " data-page="2">select</a>
<a class="jdgm-paginate__page jdgm-paginate__next-page" data-page="2">don't select next</a>
<a class="jdgm-paginate__page jdgm-paginate__last-page" data-page="2">don't select last</a>
You can use the CSS :not pseudo class. For example:
.jdgm-paginate__page {
background: red;
}
This would make all elements with that class red regardless of additional classes.
.jdgm-paginate__page:not(.jdgm-paginate__next-page) {
background: red;
}
All elements with class .jdgm-paginate__page but no with .jdgm-paginate__next-page will be red
Maybe not the best solution, but you can also use attribute selector to select your specific element in case you don't know what are the other classes:
[class="jdgm-paginate__page"] {
color: red;
}
a {
display: block;
}
<a class="jdgm-paginate__page" data-page="2">select</a>
<a class="jdgm-paginate__page jdgm-paginate__next-page" data-page="2">don't select next</a>
<a class="jdgm-paginate__page jdgm-paginate__last-page" data-page="2">don't select last</a>

scss nesting syntax: nest with parent adjoin class

I want to output:
.selector.another-selector .selector__block{some declaration}
but i want to nest it:
I am using & at the end so I can nest it under __block,
but how can I make it adjoin class with .selector?
code example:
.selector{
&__block{
// i want to put my .another-selector declaration here
.another-selector &{
//syntax issue
//need to make it .selector.another-selector .selector__block
}
}
thanks in advance.
If you nest your selector, then it has to be in the .selector__block context (&).
You have 2 solutions here :
You can repeat the first selector, as such:
.selector {
&__block {
...
.another-selector.selector & {
// Here `&` means `.selector__block`
}
}
}
You can nest differently:
.selector {
&__block {
...
}
&.another-selector &__block {
// Here `&` means `.selector`
}
}
Maybe the second solution is better since it respects the inception rule and is less dependent of the DOM structure.
BTW, you can also try https://www.sassmeister.com/ to play with your selectors
I would suggest that you don't nest BEM at all. Just go with plain declarations for two valid reasons.
1) error tracking nested BEM is hard, let say you get a class from devtools that is .hero__heading. That will not match anything in your code when doing a search. Now the example above is not that hard to figure out anyway but inheriting a project with nested structure is a pain. I suggest reading Harry Roberts article on code smells in css
2) nesting like this will often complicate when wanting to override with other classes like in your case.
Consider this code:
.selector {
background-color: deepskyblue;
}
.selector__block {
color: lightblue;
.another-selector & {
color: lightcoral;
}
}
#Dejan.S I'm not a big fan of BEM (but that's another rant ;-). If however you are using BEM I think nesting will help to illustrate the hierarchy and what to expect
SCSS:
.selector {
// selector styles
color: red;
// default selector block style
&__block { color: green; }
// selector variant selector block styles
&.foo &__block { color: blue; }
&.bar &__block { color: yellow; }
}
CSS Output:
.selector { color: red; }
.selector__block { color: green; }
.selector.foo .selector__block { color: blue; }
.selector.bar .selector__block { color: yellow; }
HTML:
<div class="selector">
Selector <!-- red -->
</div>
<div class="selector">
Selector <!-- red -->
<div class="selector__block">
Selector Block <!-- green -->
</div>
</div>
<div class="selector foo">
Selector <!-- red -->
<div class="selector__block">
Selector Foo Block <!-- blue -->
</div>
</div>
<div class="selector bar">
Selector <!-- red -->
<div class="selector__block">
Selector Bar Block <!-- yellow -->
</div>
</div>

Why are multiple entries of 'color' css attribute active in Safari Dev Tools?

Sometimes I see two entries for the CSS 'color' attribute active on a single element, even when one has !important. The one without !important is taking precedence though, as it should (I am trying to force the element to color: white). See screenshot:
Thanks!
UPDATE: added html markup
<div class="x-button x-button-back x-layout-box-item x-stretched" id="quit-button" style="width: auto !important;">
<span class="x-badge" style="display: none;"></span>
<span class="x-button-icon x-hidden" id="ext-element-1109"></span>
<span class="x-button-label" style="" id="ext-element-1110">Quit</span>
</div>
.peacekeepers-edition is set on the first element inside the body, #playview is a distant descendent.
Regardless of the specificity of the rule all proprieties from the CSSOM will appear in the inspector rule view. The fact that the "color:#ccffff" is not crossed/underline is just an inspector bug.
BTW, you overqualified your selectors: .preacekeepers-edition #playview will have a specificity of 1|1|0|, that is way more that you should have. Adding !important will make things hard to manage later.
I'm making some assumptions about your markup (because you haven't provided any), but I think it's fairly safe to say that this is your issue.
Assuming your markup is something like this...
<div class="peace-keepers-edition">
<div id="playview">
<button class="x-button-back">
<i class="x-button-icon">icon</i>
</button>
</div>
</div>
Your first selector targets the button element...
.peace-keepers-edition #playview .x-button-back {
color: #FFF !important;
}
but your second selector targets an element that is a descendant of your button...
.peace-keepers-edition #playview .x-button-back .x-button-icon {
color: #ccccff;
}
Your !important rule is irrelevant because your selectors are targeting different elements.
Easy fix; add this line after line 769...
.peace-keepers-edition #playview .x-button-back .x-button-icon {
color: #fff;
}
Broken example...
body {
background: #1a1a1a;
}
button {
padding: 15px;
font-size: 30px;
background: green;
}
.peace-keepers-edition #playview .x-button-back {
color: #FFF !important;
}
.peace-keepers-edition #playview .x-button-back .x-button-icon {
color: #ccccff;
}
<div class="peace-keepers-edition">
<div id="playview">
<button class="x-button-back">
<i class="x-button-icon">icon</i>
</button>
</div>
</div>
Working example...
body {
background: #1a1a1a;
}
button {
padding: 15px;
font-size: 30px;
background: green;
}
.peace-keepers-edition #playview .x-button-back {
color: #FFF !important;
}
.peace-keepers-edition #playview .x-button-back .x-button-icon {
color: #fff;
}
<div class="peace-keepers-edition">
<div id="playview">
<button class="x-button-back">
<i class="x-button-icon">icon</i>
</button>
</div>
</div>

Resources