Home > front end >  More selector condition (AND operator)
More selector condition (AND operator)

Time:06-25

I made few lines project to explain my problem. Is there a way in .scss file, how to make condition like: "(1)FIRST type/child that (2)DOESN'T CONTAIN some class"? I tried pile of variants, like this:

// SCSS:
&:first-of-type:not(.banned) {
   background-color: yellowgreen;
}

OR:

// CSS:
circle::first-of-type:not(.banned) {
     background-color: yellowgreen;
  }

But nothing worked for me.

Here is the whole code of my super-tiny project where I am simulating this problem:

body {
  margin-top: 2rem;
  text-align: center;
}

.circle {
  width: 30px;
  height: 30px;
  background-color: blue;
  border-radius: 100%;
  display: inline-block;
  
  &:first-of-type:not(.banned) {
    background-color: yellowgreen;
  }
}

.banned {
  background-color: brown;
}

// .circle::first-of-type:not(.banned) {
//   background-color: yellowgreen;
// }
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle'></div> // <= this one I want to collor yellowgreen, but mainly in correct way I have described.
<div class='circle'></div>
<div class='circle'></div>

My codepen (Sass syntax works here): https://codepen.io/radekjakgit/pen/jOZgYGg

CodePudding user response:

You can't use first-of-type for that as it will always return the first of that type of element among it's siblings - in your case always the first circle

If your banned always comes before the not banned circles, then you can use an adjacent sibling selector:

body {
  margin-top: 2rem;
  text-align: center;
}

.circle {
  width: 30px;
  height: 30px;
  background-color: blue;
  border-radius: 100%;
  display: inline-block;
  
  &:first-of-type:not(.banned) {
    background-color: yellowgreen;
  }
}

.banned {
  background-color: brown;
}

.banned   .circle:not(.banned) {
  background-color: yellowgreen;
}
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle'></div> 
<div class='circle'></div>
<div class='circle'></div>

If you have a mixture of banned and not banned and you only want the first not banned after a banned, then you would need to use a combination of selectors:

body {
  margin-top: 2rem;
  text-align: center;
}

.circle {
  width: 30px;
  height: 30px;
  background-color: blue;
  border-radius: 100%;
  display: inline-block;
  
  &:first-of-type:not(.banned) {
    background-color: yellowgreen;
  }
}

.banned {
  background-color: brown;
}

.banned   .circle:not(.banned) {
  background-color: yellowgreen;
}


.banned   .circle:not(.banned) ~ 
.banned   .circle:not(.banned) {
  background-color: blue;
}
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle'></div> 
<div class='circle'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle banned'></div>
<div class='circle'></div> 
<div class='circle'></div>
<div class='circle'></div>

  • Related