Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css :hover not working in chrome for delayed dynamically added classes

I have the following code, that simply creates a div, which when hovered over, should change its background color to red:

setTimeout(function() {
  document.getElementById('example-id').className = 'example-class';
}, 1);
.example-class:hover {
  background: red;
}
<body>
  <div id="example-id">example text</div>
</body>

This code seems to work in all of the browsers that I've tested it in, with the exception of google chrome. Specifically, I've tested it with the following operating systems and browsers:

  • Windows 10 Home: Version 1703
    • Chrome: 62.0.3202.94
    • Firefox: 57.0
    • Firefox ESR: 52.5.0
    • Edge: 40.15063.674.0
    • IE11: 11.726.15063.0
  • OS X El Capitan: Version 10.11.6
    • Safari: Version 11.0.1

However, if I remove the use of the setTimeout function, so that the class is added to the div immediately, then the code works as expected in all browsers.

So why is this happening? Is this a bug in google chrome, or an ambiguity in some spec somewhere, or is it something else?

like image 846
thejonwithnoh Avatar asked Nov 20 '17 13:11

thejonwithnoh


1 Answers

It's definitely a bug in Chrome, props for finding it.

I've filed it here and in less than 24 hours it was marked as duplicate of another bug, which is a duplicate of another bug, in the end tracing back to this one. It appears to have to do with a constants naming conflict, or at least that's what I made of it. (I've spent a fair amount of time last evening following the bug trail, out of sheer curiosity).

It has been reported as fixed by this revision, but I don't know enough on Chromium/Chrome versioning to tell you when that will make it into stable Chrome.


Meanwhile, the fix I found is to force a repaint on the element, after the :hover rule has been declared. For example: transform:scale(1);.

Test for fix, until proper bugfix makes it into stable Chrome:

setTimeout(function() {
  document.getElementById('foo').className = 'bar';
});
.bar:hover {
  color: red;
}
.bar {
  transform: scale(1);
}
<div id="foo">example text</div>
like image 176
tao Avatar answered Nov 14 '22 23:11

tao