Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cssom-view] Expose inner border dimensions #1129

Open
gibson042 opened this issue Mar 27, 2017 · 4 comments
Open

[cssom-view] Expose inner border dimensions #1129

gibson042 opened this issue Mar 27, 2017 · 4 comments

Comments

@gibson042
Copy link

cf. jquery/jquery#3589 (comment)

There seems to be no good method for calculating the dimensions of an element's inner border edge (i.e., content area plus padding plus non-floating scrollbars). One can subtract computed border dimensions from offsetWidth or offsetHeight in the special case of a block-layout HTMLElement, but as far as I can tell it's otherwise impossible.

I think the Element interface should expose something for such calculations, e.g.

  • scrollGutterWidth/scrollGutterHeight (the space lost to scrollbars), or
  • scrollbarWidth/scrollbarHeight (the scrollbar width), along with a method for identifying non-floating scrollbars, or
  • fullClientWidth/fullClientHeight (the dimensions of an inner border edge).

The last one seems most consistent with the rest of CSSOM View.

@zcorpan
Copy link
Member

zcorpan commented Mar 31, 2017

https://drafts.csswg.org/cssom-view/#dom-geometryutils-getboxquads should address some of this I think -- not the scrollbars, but getting the padding-edge area.

@gibson042
Copy link
Author

gibson042 commented Mar 31, 2017

getBoxQuads definitely helps, but is still very clumsy. The problem is that it only covers four boxes, but scrollbars can actually introduce a fifth by separating the padding edge from the inner border edge. So I guess utilization would look something like

function getScrollGutterWidth(elem) {
	let paddingBox = elem.getBoxQuads({box: "padding"});
	let paddingBoxWidth = paddingBox.p2.x - paddingBox.p1.x;

	let borderBox = elem.getBoxQuads({box: "border"});
	let borderBoxWidth = borderBox.p2.x - borderBox.p1.x;

	// Both borders and scrollbars can contribute to the difference between
	// border- and padding-box width.
	// Determine scrollbar width by subtracting border widths from that difference.
	let style = elem.ownerDocument.defaultView.getComputedStyle(elem);
	return borderBoxWidth - paddingBoxWidth -
		parseFloat(style.borderLeftWidth) - parseFloat(style.borderRightWidth);
}

Honestly, that's not really an improvement.

@gibson042
Copy link
Author

Here's how jQuery ended up accounting for scroll gutters when calculating inner border dimensions with the current CSS APIs: https://github.com/jquery/jquery/blob/80f1c8239e9d5f793f3e54e0cb8d7bd0747e4856/src/css.js#L131-L143

// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
// Assuming integer scroll gutter, subtract the rest and round down
delta += Math.max( 0, Math.ceil(
	elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
	computedVal -
	delta -
	extra -
	0.5
) );

@tabatkins
Copy link
Member

getBoxQuads should obviously just add scroll-box as a possible value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants