Where is Element.clientWidth with fractional number? - javascript

MDN says that Element.clientWidth "will round the value to an integer" and I should use Element.getBoundingClientRect() instead for a fractional value. While the part with the fractional value is correct, that function has a different meaning and cannot be compared.
clientWidth gives me the inner visible width without the vertical scrollbar. getBoundingClientRect gives me the outer width including the vertical scrollbar. These are entirely different sizes.
Is this intentional? Does the MDN article know about that difference? Should that restriction be added to the cross-link? What else can I do to get the desired value, which is the visible width with a fractional value?
My problem is that I'm writing code that hides elements that won't fit in the current view, depending on the view width and the elements' width. Therefore I sum up all elements' widths and compare it with the space I have. At certain window sizes, that can lead to the element width sum of 945.4 (that fits in) and the clientWidth giving me 945 (same value but rounded down, so it's less). getBoundingClientRect however gives me 951.2 in this case which is more than is actually available for the content. In consequence, a horizontal scrollbar appears which I don't want.

Related

scrollTop returns integer in chrome on high dpi devices: is there a way to get the non-rounded value?

Properties such as scrollTop or scrollLeft, as well as many other "old" (dhtml) properties now to-be-standardized in the CSSOM View module, still return integer rather than double (as specified in the draft) in high dpi devices.
For example on such devices if an HTML element is completely scrolled down,
element.scrollTop + element.clientHeight is 1 less than element.scrollHeight even if visually it is completely scrolled. I suppose because the returned offset is rounded down.
Is there an alternative way to get scrollTop (not only on body but any scrollable element) complete of its fractional part?

How to achieve $.width() with precision

How can I compute the exact width of a block element excluding padding, scroll bar, border, and margin? I know I can use $(element).width(), but jQuery does not compute the exact value because it silently rounds up the fractional part. (Please see my previous question here.)
The only way I can think of is to use .getBoundingClientRect().width and subtract what's not needed. There's got to be something better than this, but what is it?
With Javascript you can also use getComputedStyle(). Don't know about jquery alternative
var element = document.getElementById("a");
alert(window.getComputedStyle(element).width);
jQuery is not silently rounding the value. jQuery is returning the browser computed value. Since browsers can not display a fraction of a pixel the browser itself is computing a more appropriate value for the element. jQuery is actually returning the correct and most precise value.
take this code for example:
<div style="width:201px;">
<div style="width:50%;"></div> <!-- this renders as 100px, not 100.5px -->
</div>
There is 1 div with a width of 50% inside an element that is 201px wide.
based on your assumptions, each div should have a width of 100.5px. However, If you inspect the child element using any browsers development tools you will notice that it is actually being rendered as just 100px wide with no fractional value.

Uniformly distribute elements

I need to calculate the position of the elements with variable width and height within an element with a fixed width.
It's like the Pinterest board, but with variable element width (it's not determined by block's content, in my case there's two sizes of the block - 170x140 or 140x170), so i cannot use columns.
Here's the visual example of the desired result
Floating is not an option as it produces gaps that are too large.
display:inline and display:inline-block also does not produce the required result.
It seems like there's a mathematical algorithm, how each box position is calculated?
Calculations will be done in Javascript.

Quick resource to learn more about all the JS height's

There're quite a few 'Height' associated properties in JavaScript (clientHeight, Window.height, scrollHeight, offsetHeight, etc.).
I can guess what they do, but I'd like a formal, detailed guide... Generic googling hasn't helped, any good sources I could use?
Answers with the details in 'em earn brownie points!
Two resources worth consulting:
CSSOM View Module
W3C DOM Compatibility - CSS Object Model View
Below is a list of excerpt from the two (only one dimension has been included for each pair):
window.innerWidth & window.innerHeight
The dimensions of the viewport (interior of the browser window). The innerWidth attribute, on getting, must return the viewport width including the size of a rendered scroll bar (if any).
window.outerWidth & window.outerHeight
The dimensions of the entire browser window (including taskbars and such). The outerWidth attribute, on getting, must return the width of the client window. If there is no client window this attribute must return zero.
window.pageXOffset & window.pageYOffset
The amount of pixels the entire pages has been scrolled. The pageXOffset attribute, on getting, must return the x-coordinate, relative to the initial containing block origin, of the left of the viewport.
window.screenX & window.screenY
The position of the browser window on the screen. The screenX attribute, on getting, must return the x-coordinate, relative to the origin of the screen of the output device, of the top of the client window as number of pixels, or zero if there is no such thing.
screen.availHeight & screen.availWidth
The available width and height on the screen (excluding OS taskbars and such). The availWidth attribute, on getting, must return the available width of the rendering surface of the output device.
screen.height & screen.width
The width and height of the screen. The width attribute, on getting, must return the width of the output device.
<element>.clientLeft & <element>.clientTop
The position of the upper left corner of the content field relative to the upper left corner of the entire element (including borders). On getting, the clientTop attribute returns the computed value of the border-top-width property plus the width of any scrollbar rendered between the top padding edge and the top border edge.
<element>.clientWidth & <element>.clientHeight
The width and height of the content field, excluding border and scrollbar, but including padding. On getting, the clientWidth attribute returns the viewport width excluding the size of a rendered scroll bar (if any) if the element is the root element and the width of the padding edge (excluding the width of any rendered scrollbar between the padding edge and the border edge) otherwise.
<element>.offsetLeft & <element>.offsetTop
The left and top position of the element relative to its offsetParent. The offsetTop attribute, when called on element A, must return the value that is the result of the following algorithm: (1) If A is the HTML body element or does not have an associated CSS layout box return zero and stop this algorithm. (2) If the offsetParent of A is null or the HTML body element return the y-coordinate of the top border edge of A and stop this algorithm. (3) Return the result of subtracting the y-coordinate of the top padding edge of the offsetParent of A from the y-coordinate of the top border edge of A, relative to the initial containing block origin. (*) In case of an inline element that consists of multiple line boxes only the first in content order is to be considered for the purposes of the above algorithm.
<element>.offsetWidth & <element>.offsetHeight
The width and height of the entire element, including borders. The offsetWidth attribute, when called on element A, must return value that is the result of the following algorithm: (1) If A does not have an associated CSS layout box return zero and stop this algorithm. (2) Return the border edge width of A.
<element>.scrollLeft & <element>.scrollTop
The amount of pixels the element has scrolled. Read/write. The scrollTop attribute, when called on element A, must return the value that is the result of running the following algorithm: (1) If A does not have an associated CSS layout box return zero and stop this algorithm. (2) Return the y-coordinate of the content at the alignment point with the top of the content edge of A.
<element>.scrollWidth & <element>.scrollHeight
The width and height of the entire content field, including those parts that are currently hidden. If there's no hidden content it should be equal to clientX/Y. The scrollWidth attribute, when called on element A, must return value that is the result of the following algorithm: (1) If A does not have an associated CSS layout box return zero and stop this algorithm. (2) Return the computed value of the padding-left property of A, plus the computed value of the padding-right property of A, plus the content width of A.

When I have width: auto and specific left and right, why does setting min-width to the value of calculated width expand the element by 2px?

I have a page made of elements with width and height set to auto and their dimensions defined with left, right, top and bottom properties. When the page is loaded, all widths and heights are set to their calculated values by the browser, as they should be. However, when I set min-width of the elements to their respective calculated widths, each of those elements is expanded by 2px. The same happens if I set their min-height to be equal to the calculated height. I do it with jQuery, like this
element.css('min-width', element.css('width'));
or
element.css('min-width', element.width());
The effect is exactly the same as it should be, but there should not be the extra 2px if I understand what's happening correctly. Using
element.css('min-width', element.width() - 2);
completely solves the problem but I don't like not understanding why there are the extra 2px. According to specifications, neither width nor min-width nor max-width should include padding, borders or margins.
I've tested in Chrome and FF and both behave the same way.
What browser are you testing and can it be that your document is in quirksmode?
element.css('min-width', element.width()); shouldn't be doing anything in standards mode, because element.width() returns an integer without a CSS unit, and min-width requires a unit in standardsmode.
So put your document in standards mode and then try:
element.css('min-width', element.width() + "px");
If that doesn't help you'll need to show a working example.

Categories