skip to Main Content

Sorry, I posted incorrectly the last time.

I’m trying to make a code where if class x is present, class y is disabled/invisible. I’m just a little lost on how to do it. I tried a bit of jquery, but it didn’t work.

This is what I tried:

The script:

<script>
if (element.classList.contains('img-1')) {
    element.classList.remove('ani');
}
</script>

The CSS:

.ani {
     width: 120px;
     height: 120px;
     background: red;
}
 .img-1 {
     width: 120px;
     height: 120px;
}

The HTML:

<div class="ani"></div> 
<img src="" class="img-1">

I was expecting the "ani" class to disappear when the "img-1" class is present. So if ani div appeared on it’s own without the img-1 class, it would be visible, but the moment the img-1 class appears, I was expecting the ani class to disappear.

Again, I’m so sorry, english isn’t my first language.

2

Answers


  1. Disclaimer: I took into account the very question you were asking (a class that would prevent another class from taking effect). The answer from @jla doesn’t go that way and proposes further changes to the CSS. If your scenario applies, I agree that you should consider applying their changes to your code – but I’m gonna leave this here either way to answer the question at hand.


    As per your requirements, you could achieve your objective by appending the :not CSS pseudo-class to the .ani selector:

    .ani:not(.img-1) {
      width: 120px;
      height: 120px;
      background: red;
    }
    
    .img-1 {
      width: 120px;
      height: 120px;
    }
    <div class="ani"> Hi, I'm <code>.ani</code> </div>
    <div class="ani img-1"> I'm <code>.ani</code>, too, but ain't red </div>
    <h1 class="ani"> Yay, I'm <code>.ani</code> and red, too </h1>
    <div class="img-1"> Eh, I am neither </div>
    <img src="https://picsum.photos/120/120" class="img-1" title="I'm just an image" />

    By appending :not(.img-1), it will only ever select an element that does not match .img-1 – so any element bearing the class will not be affected.


    By the way, just for the sake of clarity – your JavaScript approach would work if you were to fix a few things:

    // select every .ani element which also has a .img-1 class
    const elements = document.querySelectorAll('.ani.img-1');
    
    // loop through all the elements
    for (const element of elements) {
      // remove class from each element inside elements
      element.classList.remove('ani');
    }
    .ani {
         width: 120px;
         height: 120px;
         background: red;
    }
    .img-1 {
         width: 120px;
         height: 120px;
    }
    <div class="ani"> <code>ani</code> </div>
    <div class="ani img-1"> <code>ani</code> + <code>img-1</code> </div>
    <img src="https://picsum.photos/120/120" class="img-1 ani" title="img-1 + ani">
    <img src="https://picsum.photos/120/120" class="img-1" title="img-1">

    Maybe you didn’t share the whole code, but the way it was, element was not an existing variable and therefore couldn’t have anything in it. In my above snippet, I created an elements variable, then selected every element that had both .ani and .img-1 classes.

    Then it was just a matter of looping through each of the elements and then applying .classList.remove('.ani') to each of them.

    Login or Signup to reply.
  2. It seems that using JavaScript to remove classes is an over-engineered solution for you situation. It would be better to use CSS specificity and overrides, as this is exactly the intent of CSS.

    In CSS, the more specific the rule’s selector is, the higher priority it is given. If there are two CSS rules that target the same element, one giving it a background of red, and the other a transparent background, the CSS rule with the most specific selector will be used.

    For example, a CSS rule that sets the background red might look like:

    .ani {
         width: 120px;
         height: 120px;
         background-color: red;
    }
    

    We could make a second rule that is more specific like so:

    .ani.img-1 {
        background-color: transparent;
    }
    

    In CSS when you see two classnames together with no space, it means "target elements that have both of the classnames". A selector with two classnames is more specific that a selector with one. So in the above example, if there was an element <img src="" class="ani img-1">, the CSS rules with selector .ani.img-1 would override the corresponding rules with selector .ani, and the background would be transparent.

    Note that there are no width or height rules in .ani.img-1. Because the example <img ...> element has the class ani, all of the rules in .ani that are not overridden by .ani.img-1 will still be applied to it.

    You can test the code in the snippet below. For easier viewing .ani.img-1 has been given a blue background rather than transparent.

    .ani {
        width: 40px;
        height: 40px;
        margin: 10px auto;
        background-color: red;
    }
    .ani.img-1 {
        background-color: blue;
    }
    <div class="ani"></div>
    
    <div class="ani img-1"></div>

    For in-depth information on CSS specificity, see the MDN article.

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