eqcss / eqcss

EQCSS is a CSS Reprocessor that introduces Element Queries, Scoped CSS, a Parent selector, and responsive JavaScript to all browsers IE8 and up

Home Page:https://elementqueries.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug: element query style targeting a class is not being removed when class is removed

jorroll opened this issue · comments

commented

Hi there! First off, this is an awesome library and spec! I've checked out a few interpretations of element queries, I like this one by far the best.

Secondly, I think I'm running into a bug in the library.

If I construct an element query like so

@element "#divOne.active" {
  h2 { color: red; }
}

The element query's styles are correctly applied when #divOne gains the .active class, but when #divOne loses the .active class, the element query's styles are not being removed.

You can check out a plunkr here: http://plnkr.co/edit/7wbL5WxOA9wHoQWJsCA1?p=preview

Hi @thefliik :D Thanks for the input!

The reason this is happening is because the moment #divOne.active becomes valid, the EQCSS plugin is marking it with an attribute. There are two workarounds for what you're trying to do with the way EQCSS works as a plugin right now:

  • write the query for #divOne and have the selector resolve the .active class
  • use EQCSS.reset and EQCSS.load after each toggle to reset the attributes

I think the first one will work better for performance, consider my (simplified) demos here and imagine it's your demo code:

<h2>This should be red when #divOne has .active</h2>
<input type=button onclick="divOne.className = divOne.className=='active'?'':'active'" value=Toggle>
<div id=divOne>This is divOne</div>
<style>
  @element #divOne {
    eval('(className.indexOf("active") !== -1) && "h2"') {
      color: red;
    }
  }
</style>
<script src=http://elementqueries.com/EQCSS.js></script>

Here we have the @element query written for the #divOne ID so this applies all the time. Every time EQCSS is recalculated it will resolve the eval(), which in this case is outputting a selector of h2 or `` (nothing). If any elements matching #divOne have a className that includes the text `active`, this rule will output with a selector text of `h2`, otherwise it's just output as `{ color: red; }` with no selector and discarded by the browser (applying to nothing).

The second alternative is less ideal, but seems to be set up more like your demo. If you're desiring to use #divOne.active as the element query, you'll need to run EQCSS.reset(), your class-toggling code, then EQCSS.load() to reload EQCSS. This will likely be slow, and the reset function isn't perfect - so I would recommend not doing this - but I'll include it for completeness so you understand how to work around it :D

<h2>This should be red when #divOne has .active</h2>
<style>
  @element #divOne.active {
    h2 {
      color: red;
    }
  }
</style>
<input type=button onclick="EQCSS.reset();divOne.className = divOne.className=='active'?'':'active';EQCSS.load()" value=Toggle>
<div id=divOne>This is divOne</div>
<script src=http://elementqueries.com/EQCSS.js></script>

Here we have a similar setup with HTML, but the rule is written for #divOne.active. Every time the toggle button is clicked it's resetting EQCSS and reloading it, ensuring that the faulty rule is removed each time.

Hopefully that helps you figure out how to use it in your demo!

commented

@tomhodgins thanks for the explanation! I don't think I ever would have figured that out on my own. I tried both of your methods and they both work. You were also right about the first method being significantly more performant.