0

Is it possible to use an html element class as a condition for if statement or relative way in sass css?

In many cases in programming it is necessary to combine a loop and an if test to check if something is in the desired state, and if it is then increase the value that will be used. I was wondering if this could be done in scss?

First of all I know I can do it with JS, so please don't post js related answers here - just wondering if it can be done with SCSS or SASS and have just pure CSS

Why I want to do this? I have a dropdown menu with multiple options, but some products have fewer options than others and the list changes dynamically. So I'm adding a class ".hidden" to options that shouldn't be visible.

Each option has a button and a list that appears when you hover over the button. What I want to do is to level all the lists to the bottom line, but for this I have to apply the "bottom" style with the multiplication of 100% of the relative parent height style, but only to the element without the ".hidden" class.

my html looks something like this:

<ul class="dropdown-menu  components" role="dropdown">
    <li class="dropdown-item hidden"> <!-- pass $c increasment -->
        <button class="btn icon"></button>
        <div class="list"></div>
    </li>
    <li class="dropdown-item">  <!-- $c = 4 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-400% - 2rem) -->
    </li>
    <li class="dropdown-item hidden"> <!-- pass $c increasment -->
        <button class="btn icon"></button>
        <div class="list"></div>
    </li>
    <li class="dropdown-item">  <!-- $c = 3 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-300% - 2rem) -->
    </li>
    <li class="dropdown-item">  <!-- $c = 2 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-200% - 2rem) -->
    </li>
    <li class="dropdown-item hidden"> <!-- pass $c increasment -->
        <button class="btn icon"></button>
        <div class="list"></div> 
    </li>
    <li class="dropdown-item"> <!-- $c = 1 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-100% - 2rem) -->
    </li>
</ul>

I was hoping something as logical as this would work:

$elements: 10;
$c:0;
@for $i from 0 to $elements {
    &:not(.hidden){
        $c: $c + 1;
        &:nth-last-child(#{$c}){
            .list{
                bottom: calc(calc(-100% * #{$c}) - 2rem);
            }
        }
    }
}

However, the scss "for" statement seems to ignore the "&:not(.hidden)" and increment $c with each iteration.

Obviously, I can do this with JS when adding the ".hidden" class, but I will have to loop throu all the objects every time, and was wondering if it could be done in a more efficient and convenient way with CSS?

However, if anyone is interested how to do it in JS than:

function CheckAlignAllOptionLists(){
    let _menu = document.querySelector(".dropdown-menu.components");

    if(_menu == null){ return;}

    let _options = _menu.querySelectorAll(".dropdown-item");
    let _hidden = _menu.querySelectorAll(".dropdown-item.hidden");
    
    let _count = _options.length - _hidden.length; // we want to trigger children counting from bottom to top but in html li elements by default are one after or under another...
    // if you use  flex-direction: column-reverse; than you can just write let _count = 0 and later on _count++;
    _options.forEach((_o)=>{
        let _list = _o.querySelector(".list");      
        if(_list != null){      
            _list.style.bottom = "0px";
            if(!_o.classList.contains("hidden")){
                _count--;
                _list.style.bottom = "calc(calc(-100% * "+_count+") - 2rem)";
            }
        }
    });
}
Mironek
  • 11
  • 2
  • You should post the JavaScript you're using. Even if you demand a solution with no JS, the JS you already have is relevant. – inwerpsel Aug 17 '22 at 08:58
  • First of all I'm not demending anythihing just asking is it possible to use a html element class as a condition for if statement or relative way in sass css. The JS has nothing to do and its so complex and long that it would dimm entire inquiry as its based on mix of ajax. I am aware that "No, it is impossible to do it in CSS because ..." is possible but i just want to be sure. – Mironek Aug 17 '22 at 09:18
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Aug 17 '22 at 09:40
  • Maybe the problem is :not selector check this https://stackoverflow.com/questions/22650270/sass-not-selector – Емил Цоков Aug 17 '22 at 10:07
  • @ЕмилЦоков I think :not() doesn't do much with the scss iteration - it doesn't work as if it were a condition ... and it's understandable - scss is just a compiler and :not is a part of css code element that alwys needs to be written.. so in that way it doesn't limit the incrementing and creating of css code. I just wonder is there other way to achive what i want with css.. – Mironek Aug 17 '22 at 10:28

1 Answers1

1

the scss "for" statement seems to ignore the "&:not(.hidden)" and increment $c with each iteration

You answer this yourself in the comments:

scss is just a compiler

This loop will just run at compile time and output everything inside it for every iteration. The SCSS counter variable is only local to SCSS as it's compiling. It doesn't exist anymore after that. It cannot possibly be affected by whatever HTML you end up using the output CSS with.

I was wondering if this could be done in scss?

Since the question is titled on looping HTML elements, definitely not. CSS has no way to increment a counter in JS.

It's still unclear exactly what you're trying to achieve, maybe a sketch drawing could be useful?

Possibly you're trying to use a fix which depends on nth-child numbers being correct? And hence end up needing to provide it with the right numbers?

In that case maybe you can use other CSS selectors that don't depend on these numbers?

If you really do want to increment a JS variable inside of CSS, then no, you can't do that.

inwerpsel
  • 2,677
  • 1
  • 14
  • 21