mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
UX: Improve sidebar positioning in Safari (#30888)
- Calculate the overscroll amount and subtract it from viewport-based measurements - Only round at the end of calculations, to avoid sub-pixel rounding discrepancies - Compensate for < 1px fluctuations which happen during scroll Before: https://github.com/user-attachments/assets/a1044405-9f4a-46b1-a3b1-bc5fff29bf45 After: https://github.com/user-attachments/assets/212e4a32-aa97-4054-aba0-b7f1d993f007
This commit is contained in:
parent
4a7b98ef6d
commit
4933cfd46c
@ -90,16 +90,28 @@ export default class GlimmerSiteHeader extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clamping to 0 to prevent negative values (hello, Safari)
|
// We expect this to be zero, but when overscrolling in Safari it can have a non-zero value:
|
||||||
const headerWrapBottom = Math.max(
|
const overscrollPx = Math.max(
|
||||||
0,
|
0,
|
||||||
Math.floor(this._headerWrap.getBoundingClientRect().bottom)
|
document.documentElement.getBoundingClientRect().top
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const headerWrapTop =
|
||||||
|
this._headerWrap.getBoundingClientRect().top - overscrollPx;
|
||||||
|
let headerWrapBottom =
|
||||||
|
this._headerWrap.getBoundingClientRect().bottom - overscrollPx;
|
||||||
|
|
||||||
|
// While scrolling on iOS, an element fixed to the top of the screen can have a `top` which fluctuates
|
||||||
|
// between -1 and 1. To avoid that fluctuation affecting the header offset, we subtract that tiny fluctuation from the bottom value.
|
||||||
|
if (Math.abs(headerWrapTop) < 1) {
|
||||||
|
headerWrapBottom -= headerWrapTop;
|
||||||
|
}
|
||||||
|
|
||||||
let mainOutletOffsetTop = Math.max(
|
let mainOutletOffsetTop = Math.max(
|
||||||
0,
|
0,
|
||||||
Math.floor(this._mainOutletWrapper.getBoundingClientRect().top) -
|
this._mainOutletWrapper.getBoundingClientRect().top -
|
||||||
headerWrapBottom
|
headerWrapBottom -
|
||||||
|
overscrollPx
|
||||||
);
|
);
|
||||||
|
|
||||||
if (DEBUG && isTesting()) {
|
if (DEBUG && isTesting()) {
|
||||||
@ -111,16 +123,19 @@ export default class GlimmerSiteHeader extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const docStyle = document.documentElement.style;
|
const docStyle = document.documentElement.style;
|
||||||
|
|
||||||
const currentHeaderOffset =
|
const currentHeaderOffset =
|
||||||
parseInt(docStyle.getPropertyValue("--header-offset"), 10) || 0;
|
parseInt(docStyle.getPropertyValue("--header-offset"), 10) || 0;
|
||||||
const newHeaderOffset = headerWrapBottom;
|
const newHeaderOffset = Math.floor(headerWrapBottom);
|
||||||
if (currentHeaderOffset !== newHeaderOffset) {
|
if (currentHeaderOffset !== newHeaderOffset) {
|
||||||
docStyle.setProperty("--header-offset", `${newHeaderOffset}px`);
|
docStyle.setProperty("--header-offset", `${newHeaderOffset}px`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentMainOutletOffset =
|
const currentMainOutletOffset =
|
||||||
parseInt(docStyle.getPropertyValue("--main-outlet-offset"), 10) || 0;
|
parseInt(docStyle.getPropertyValue("--main-outlet-offset"), 10) || 0;
|
||||||
const newMainOutletOffset = headerWrapBottom + mainOutletOffsetTop;
|
const newMainOutletOffset = Math.floor(
|
||||||
|
headerWrapBottom + mainOutletOffsetTop
|
||||||
|
);
|
||||||
if (currentMainOutletOffset !== newMainOutletOffset) {
|
if (currentMainOutletOffset !== newMainOutletOffset) {
|
||||||
docStyle.setProperty("--main-outlet-offset", `${newMainOutletOffset}px`);
|
docStyle.setProperty("--main-outlet-offset", `${newMainOutletOffset}px`);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user