Skip to content

Commit ab50bb3

Browse files
authored
fix: handle scrollbar widths correctly (#309)
* Update borders test case to handle scrollbar widths * fix the test * Apply scrollbar dimensions correctly * Fix regression caught by the tests * fix regression in test
1 parent 5f585b8 commit ab50bb3

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

src/compute.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,22 @@ export default (
290290
const borderTop = parseInt(frameStyle.borderTopWidth as string, 10)
291291
const borderRight = parseInt(frameStyle.borderRightWidth as string, 10)
292292
const borderBottom = parseInt(frameStyle.borderBottomWidth as string, 10)
293+
// The property existance checks for offfset[Width|Height] is because only HTMLElement objects have them, but any Element might pass by here
294+
// @TODO find out if the "as HTMLElement" overrides can be dropped
295+
const scrollbarWidth =
296+
'offsetWidth' in frame
297+
? (frame as HTMLElement).offsetWidth -
298+
(frame as HTMLElement).clientWidth -
299+
borderLeft -
300+
borderRight
301+
: 0
302+
const scrollbarHeight =
303+
'offsetHeight' in frame
304+
? (frame as HTMLElement).offsetHeight -
305+
(frame as HTMLElement).clientHeight -
306+
borderTop -
307+
borderBottom
308+
: 0
293309

294310
let blockScroll = 0
295311
let inlineScroll = 0
@@ -341,7 +357,8 @@ export default (
341357
const offset =
342358
0 - Math.min(frameRect.bottom - targetBlock, frame.scrollTop)
343359

344-
blockScroll = frame.scrollTop + offset + borderBottom
360+
blockScroll =
361+
frame.scrollTop + offset + borderBottom + scrollbarHeight
345362
}
346363
}
347364

@@ -369,7 +386,7 @@ export default (
369386
frameRect.bottom,
370387
frameRect.height,
371388
borderTop,
372-
borderBottom,
389+
borderBottom + scrollbarHeight,
373390
targetBlock,
374391
targetBlock + targetRect.height,
375392
targetRect.height
@@ -424,7 +441,8 @@ export default (
424441
const offset =
425442
0 - Math.min(frameRect.right - targetInline, frame.scrollLeft)
426443

427-
inlineScroll = frame.scrollLeft + offset + borderRight
444+
inlineScroll =
445+
frame.scrollLeft + offset + borderRight + scrollbarWidth
428446
}
429447
}
430448

@@ -452,7 +470,7 @@ export default (
452470
frameRect.right,
453471
frameRect.width,
454472
borderLeft,
455-
borderRight,
473+
borderRight + scrollbarWidth,
456474
targetInline,
457475
targetInline + targetRect.width,
458476
targetRect.width

tests/web-platform/custom/borders.html

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,25 +154,34 @@
154154
var tiles = document.querySelectorAll(".scroll-tile");
155155
var outerContainer = document.querySelector(".outer-scroll-container");
156156
var innerContainer = document.querySelector(".inner-scroll-container");
157+
// offsetWidth - borderWidth - clientWidth = scrollbar width!
158+
var borderWidth = 6;
159+
var outerOffsetX = outerContainer.offsetWidth - outerContainer.clientWidth - borderWidth;
160+
var outerOffsetY = outerContainer.offsetHeight - outerContainer.clientHeight - borderWidth;
161+
var innerOffsetX = innerContainer.offsetWidth - innerContainer.clientWidth - borderWidth;
162+
var innerOffsetY = innerContainer.offsetHeight - innerContainer.clientHeight - borderWidth;
157163

158164
[
159165
[0, "start", "start", [{ x: 300, y: 300 }, { x: 55, y: 55 }]],
160166
[1, "start", "center", [{ x: 200, y: 300 }, { x: 100, y: 55 }]],
161-
[2, "start", "end", [{ x: 100, y: 300 }, { x: 145, y: 55 }]],
167+
[2, "start", "end", [{ x: 100, y: 300 }, { x: 145 + innerOffsetX, y: 55 }]],
162168
[3, "center", "start", [{ x: 300, y: 200 }, { x: 55, y: 100 }]],
163169
[4, "center", "center", [{ x: 200, y: 200 }, { x: 100, y: 100 }]],
164-
[5, "center", "end", [{ x: 100, y: 200 }, { x: 145, y: 100 }]],
165-
[6, "end", "start", [{ x: 300, y: 100 }, { x: 55, y: 145 }]],
166-
[7, "end", "center", [{ x: 200, y: 100 }, { x: 100, y: 145 }]],
167-
[8, "end", "end", [{ x: 100, y: 100 }, { x: 145, y: 145 }]],
168-
[0, "nearest", "nearest", [{ x: 23, y: 23 }, { x: 0, y: 0 }]],
169-
[8, "nearest", undefined, [{ x: 100, y: 100 }, { x: 145, y: 145 }]]
170+
[5, "center", "end", [{ x: 100, y: 200 }, { x: 145 + innerOffsetX, y: 100 }]],
171+
[6, "end", "start", [{ x: 300, y: 100 }, { x: 55, y: 145 + innerOffsetY }]],
172+
[7, "end", "center", [{ x: 200, y: 100 }, { x: 100, y: 145 + innerOffsetY }]],
173+
[8, "end", "end", [{ x: 100, y: 100 }, { x: 145 + innerOffsetX, y: 145 + innerOffsetY }]],
174+
[0, "nearest", "nearest", [{ x: 23 + outerOffsetX, y: 23 + outerOffsetY }, { x: 0, y: 0 }]],
175+
[8, "nearest", undefined, [{ x: 100, y: 100 }, { x: 145 + innerOffsetX, y: 145 + innerOffsetY }]]
176+
170177
].forEach(function(suite) {
171178
var target = suite[0];
172179
var block = suite[1];
173180
var inline = suite[2];
181+
174182
var outer = suite[3][0];
175183
var inner = suite[3][1];
184+
176185
test(function() {
177186
window.scrollTo(0, 0);
178187
outerContainer.scrollTop = 0

0 commit comments

Comments
 (0)