1

I have an issue with css counter-reset in a selector on a dynamic property, but only in Safari browser.

<p numbered="1">para</p>
<p numbered="1">para</p>
<p numbered="1">para</p>
<p numbered="1">para</p>
<p numbered="1" id="test" restart-numbering="true">para</p>
<p numbered="1">para</p>
<br><br><br>
<button onclick='toggle()'>
    Toggle
</button>

js:

function toggle() {
let el = document.querySelector('#test');
let restarting = !!el.getAttribute('restart-numbering');
if (restarting) {
    el.removeAttribute('restart-numbering');
} else {
    el.setAttribute('restart-numbering', true);
  }
}

css:

p[numbered="1"] {
    counter-increment: numbered1;
}
p[numbered="1"]:before {
  content: counter(numbered1)'.';
}
p[numbered="1"][restart-numbering="true"] {
  counter-reset: numbered1;
}

When loaded the first time, paragraph numbering is reset correctly: 1,2,3,4,1,2

Press the toggle button twice, which brings the html to the original state and get 1,2,3,4,4,5

Here is the fiddle

mishap
  • 8,176
  • 14
  • 61
  • 92
  • So what is the issue in Safari then, that it doesn’t toggle back correctly in Safari? Probably less of a CSS issue, and more one with setting the attribute, I would guess. (Also, please use `data-` attributes at least, instead of crapping non-existent fake attributes all over the place.) – 04FS Feb 22 '19 at 10:32
  • Have you tried `el.setAttribute('restart-numbering', 'true')`? – 04FS Feb 22 '19 at 10:33

1 Answers1

0

Found this related S.O. post: How can I force WebKit to redraw/repaint to propagate style changes?

Seems that in an effort to be fast and efficient, browsers sometimes take shortcuts when evaluating CSS. Using the answer from that post we can modify the fiddle to toggle some props on a container div that make the browser evaluate the CSS a little deeper:

html:

<div id="container">
  <p numbered="1">para</p>
  <p numbered="1">para</p>
  <p numbered="1">para</p>
  <p numbered="1">para</p>
  <p numbered="1" id="test" restart-numbering="true">para</p>
  <p numbered="1">para</p>
</div>

js:

function toggle() {

  let el = document.querySelector('#test');
  let restarting = !!el.getAttribute('restart-numbering');
  if (restarting) {
    el.removeAttribute('restart-numbering');
  } else {
    el.setAttribute('restart-numbering', true);
  }

  let ctr = document.querySelector('#container');
  ctr.style.display='none';
  ctr.offsetHeight; // no need to store this anywhere, the reference is enough
  ctr.style.display='';

}

Here's the updated fiddle

Steve
  • 1,326
  • 14
  • 21