0

I have a bit of a puzzling issue. I am trying to set the CSS top using jQuery 3.5.1 in Firefox and I was expecting to be able to retrieve it again as the same value. Try this on any div element:

$('#test-div').css('top', 1.11111);
alert(parseFloat($('#test-div').css('top')));

The alert is:

1.11667

It is not the same as 1.11111 due to the way different browsers handle fractional pixels. It seems to work alright in other browsers I've tested it with (Edge and Chrome, for example, which seem to have a six digit granularity).

When I inspect the HTML, the value is set correctly from the jQuery side to 1.11111. Is there any way to fetch this value exactly as it is set in the DOM such that I get back 1.11111?

Alexandru
  • 12,264
  • 17
  • 113
  • 208
  • Short answer: no. You're entirely at the mercy of the browser. – Rory McCrossan Jul 27 '20 at 14:33
  • using vanilla js the same result? – s.kuznetsov Jul 27 '20 at 14:36
  • @RoryMcCrossan But, I see the value is correct in `$('#test-div').parent().html()`, so arguably, I could parse that...but I am looking for a more elegant solution as to how to parse that... – Alexandru Jul 27 '20 at 14:40
  • Exactly my point. You could hack around the HTML text in the DOM, but that's ugly and not an acceptable solution. The alternative is to use the value returned from the CSS engine of the browser, which is what gives you the unreliable sub-pixel values. Do you *really* need sub-pixel accuracy? In terms of the UI There's no difference between `1` and `1.11111` – Rory McCrossan Jul 27 '20 at 14:41
  • @RoryMcCrossan Yup. In this case, I really do. I am okay with parsing the DOM as a solution. Just want something a bit more performant. – Alexandru Jul 27 '20 at 14:43
  • Would it be possible to use a `data-top="1.1111"` attribute instead? Then the value is guaranteed to no lose precision and you can set `top` in CSS however you need – Rory McCrossan Jul 27 '20 at 14:48
  • @RoryMcCrossan I guess I could also just store it in a variable as someone pointed out. – Alexandru Jul 27 '20 at 14:54
  • I can explain why I need it...so, I am writing a virtualized table in JavaScript. It supports millions of rows, and has custom vertical scrollbars. Upon mouse wheel move, I move the scroll bar down by a height relative to the height of one row, thus adjusting its top value. Obviously in Firefox, one row’s height relative to itself is too granular with a data set of large enough size...seems to work okay on Safari, Edge, and Chrome, though. Even mobile. So, I’m alright with people cranking the mouse wheel on Firefox just to meet minimum granularity! – Alexandru Jul 27 '20 at 15:03
  • Using a variable works okay in my situation...I'll go with that. Actually its working really well for me. – Alexandru Jul 27 '20 at 17:50
  • @RoryMcCrossan Here’s how it turned out in the end. A real beauty IMHO. https://www.nocturis.com/liquid-data-tables/demo.html – Alexandru Jul 27 '20 at 18:46
  • Just ran it (outside SO, with jQuery 3.5.1 on **W10-x64**): Firefox Developer Edition v.79.0b8-64bits **1.11111**, Chrome/Edge **1.11111**, IE11 **1.11**, Vivaldi 3 (Chrome) **1.11111**, Pale Moon 28.11 (old FF clone) **1.11667** – Rene van der Lende Jul 28 '20 at 09:24
  • Ditto **Android 9**: Firefox SE **1.11667** Chrome **1.11111** Samsung internet **1.11111** Edge **1.11111** For now I would say that it is a Firefox Standard Edtion problem... – Rene van der Lende Jul 28 '20 at 09:24
  • Same results for `alert(parseFloat(window.getComputedStyle(document.querySelector('#test-div')).top));` – Rene van der Lende Jul 28 '20 at 09:35

1 Answers1

0

Try using window.getComputedStyle(element).top

This was exact for me.

Axwabo
  • 49
  • 7