Skip to content

Instantly share code, notes, and snippets.

@tak-dcxi
Last active April 30, 2024 14:43
Show Gist options
  • Save tak-dcxi/9d87a29d60f55c79cc2b49a440f8de70 to your computer and use it in GitHub Desktop.
Save tak-dcxi/9d87a29d60f55c79cc2b49a440f8de70 to your computer and use it in GitHub Desktop.
backfaceFixed
const backfaceFixed = (fixed: boolean): void => {
const scrollBarWidth = getScrollBarSize()
const scrollPosition = getScrollPosition(fixed)
document.body.style.borderInlineEnd = fixed ? `${scrollBarWidth}px solid transparent` : ''
applyStyles(scrollPosition, fixed)
if (!fixed) restorePosition(scrollPosition)
}
const isWritingModeVertical = (): boolean => {
const { writingMode } = window.getComputedStyle(document.scrollingElement!)
return writingMode.includes('vertical') || writingMode.includes('sideways')
}
const getScrollBarSize = (): number => {
const scrollBarXSize = window.innerHeight - document.body.clientHeight
const scrollBarYSize = window.innerWidth - document.body.clientWidth
return isWritingModeVertical() ? scrollBarXSize : scrollBarYSize
}
const getScrollPosition = (fixed: boolean): number => {
if (fixed) {
return isWritingModeVertical() ? document.scrollingElement!.scrollLeft : document.scrollingElement!.scrollTop
}
return parseInt(document.body.style.insetBlockStart || '0', 10)
}
type AllowedStyles = 'blockSize' | 'insetInlineStart' | 'position' | 'insetBlockStart' | 'inlineSize'
const applyStyles = (scrollPosition: number, apply: boolean): void => {
const styles: Partial<Record<AllowedStyles, string>> = {
blockSize: '100dvb',
insetInlineStart: '0',
position: 'fixed',
insetBlockStart: isWritingModeVertical() ? `${scrollPosition}px` : `${scrollPosition * -1}px`,
inlineSize: '100dvi',
}
Object.keys(styles).forEach((key) => {
const styleKey = key as AllowedStyles
document.body.style[styleKey] = apply ? styles[styleKey]! : ''
})
}
const restorePosition = (scrollPosition: number): void => {
const options: ScrollToOptions = {
behavior: 'instant',
[isWritingModeVertical() ? 'left' : 'top']: isWritingModeVertical() ? scrollPosition : scrollPosition * -1,
}
window.scrollTo(options)
}
export default backfaceFixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment