skip to Main Content

Why is the gold color being applied to the elements with the background color? The :not([class*="bg-"]) selector doesn’t seem to be working. What am I missing?

<html data-bs-theme="dark">

<head>
  <style>
    .link-primary {
      color: blue;
    }
    
    .bg-light {
      background-color: #f8f9fa;
    }
    
    .bg-yellow {
      background-color: yellow;
    }
    
    [data-bs-theme="dark"] body {
      background: #333333;
    }
    
    [data-bs-theme="dark"] :not([class^="bg-"]) .link-primary {
      color: gold;
    }
  </style>
</head>

<body>
  <div class="bg-light">
    <a class="link-primary">Link in blue</a>
  </div>
  <div class="bg-yellow">
    <a class="link-primary">Link in blue</a>
  </div>
  <div>
    <a class="link-primary">Link in gold</a>
  </div>
</body>

</html>

4

Answers


  1. You need to add div – because even if the div was class="bg-" the anchor tags still don’t match so it gets applied on the anchors.

    [data-bs-theme="dark"] div:not([class^="bg"]) .link-primary

    <html data-bs-theme="dark">
    
    <head>
      <style>
        .link-primary {
          color: blue;
        }
        
        .bg-light {
          background-color: #f8f9fa;
        }
        
        .bg-yellow {
          background-color: yellow;
        }
        
        [data-bs-theme="dark"] body {
          background: #333333;
        }
        
        [data-bs-theme="dark"] div:not([class^="bg"]) .link-primary {
          color: gold;
        }
      </style>
    </head>
    
    <body>
      <div class="bg-light">
        <a class="link-primary">Link in blue</a>
      </div>
      <div class="bg-yellow">
        <a class="link-primary">Link in blue</a>
      </div>
      <div>
        <a class="link-primary">Link in gold</a>
      </div>
    </body>
    
    </html>
    Login or Signup to reply.
  2. Because your a is also a child of body which matches :not([class^="bg-"]).

    You should specify that you want to target links that are direct children (>) of elements whithout a background class :

    [data-bs-theme="dark"] :not([class^="bg-"]) > .link-primary
    
    .link-primary {
          color: blue;
        }
        
        .bg-light {
          background-color: #f8f9fa;
        }
        
        .bg-yellow {
          background-color: yellow;
        }
        
        [data-bs-theme="dark"] body {
          background: #333333;
        }
        
        [data-bs-theme="dark"] :not([class^="bg-"]) > .link-primary {
          color: gold;
        }
    <html data-bs-theme="dark">
    
    <body>
      <div class="bg-light">
        <a class="link-primary">Link in blue</a>
      </div>
      <div class="bg-yellow">
        <a class="link-primary">Link in blue</a>
      </div>
      <div>
        <a class="link-primary">Link in gold</a>
      </div>
    </body>
    
    </html>
    Login or Signup to reply.
  3. Perhaps this:

    I think when you say :not([class^="bg-"]), when you mean (or are hoping for) is this: "I don’t want ANY tags between here and there to match bg-".

    But what the CSS engine is doing is this: "I’m trying to match any tag that doesn’t have bg-". There is a difference.

    So consider HTML that looks like this:
    <html data-bs-theme="dark"><body><div class="bg-light"><a class="link-primary">

    • The [data-bs-theme="dark"] will match the tag
    • The :not([class^="bg-"]) will match the tag
    • The .link-primary will match the tag
    • Thus it is gold.

    Perhaps what you should do instead is actively color the bg-light links a different color, overriding the dark, instead of trying to ignore it.

    .bg-light .link-primary {
      color: black;
    }
    
    Login or Signup to reply.
  4. You’re likely being too broad. When you use a space character to identify children in css, you are saying "any child or grandchild (excuse me) of any element matching [data-bs-theme="dark"], select :not([class^="bg-"]). body matches that selector, being after html, therefore causing all your other link class elements to be gold, as they are also grandchildren of body.

    if you use more narrow css and change that to either [data-bs-theme="dark"] :not([class^="bg-"]) > .link-primary or [data-bs-theme="dark"] div:not([class^="bg-"]) > .link-primary, or a combination of both, you’ll be fine. Body does not match being a div element, and > means only direct descendants / children and not grandchildren, excluding body.

    <html data-bs-theme="dark">
    
    <head>
      <style>
        .link-primary {
          color: blue;
        }
        
        .bg-light {
          background-color: #f8f9fa;
        }
        
        .bg-yellow {
          background-color: yellow;
        }
        
        [data-bs-theme="dark"] body {
          background: #333333;
        }
        
        [data-bs-theme="dark"] div:not([class^="bg-"]) > .link-primary {
          color: gold;
        }
      </style>
    </head>
    
    <body>
      <div class="bg-light">
        <a class="link-primary">Link in blue</a>
      </div>
      <div class="bg-yellow">
        <a class="link-primary">Link in blue</a>
      </div>
      <div>
        <a class="link-primary">Link in gold</a>
      </div>
    </body>
    
    </html>

    Another fix could involve you moving the attribute to the body, and changing the [data-bs-theme="dark"] body rule to [data-bs-theme="dark"]

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search