Horizontal scroll doesn’t work, especially in Chrome and iOS Safari
I am currently working on creating a scrollable option list within the settings screen of the drawer. I would like the previously selected option to be automatically scrolled to the center when the list is opened again. (I am using local storage to reflect the selection.)
I have implemented the following code, and it works as expected in Firefox, but scrolling does not occur in Chrome and iOS Safari (although the .theme-input:checked + .theme-swatch selector is working correctly, indicating that the selection itself is done correctly). Additionally, in Firefox, it works as expected when the page is reloaded, but it does not work when the HTML file is initially opened or when accessing the server in a new tab.
<aside class="settings" id="settings">
<header class="settings__header"><label class="settings-close" for="settingsSwitch"></label></header>
<div class="settings__container">
<div class="settings__page">
<ul class="theme-list">
<li class="theme-list__item"><input class="theme-input" type="radio" name="theme" id="themeWhite" value="white"><label class="white theme-swatch" for="themeWhite" title="White"></label></li>
<li class="theme-list__item"><input class="theme-input" type="radio" name="theme" id="themeBlack" value="black"><label class="black theme-swatch" for="themeBlack" title="Black"></label></li>
<!-- 以下11個 -->
</ul>
</div>
</div>
</aside>
<main class="main">
</main>
.settings-input {
display: none;
}
.settings {
overflow: auto;
position: fixed;
top: 0;
left: 0;
z-index: 40;
width: 100%;
height: 100vh;
transition: all .5s ease-in-out 0s;
transform: translateX(100%);
}
.settings-input:checked + .settings {
transform: translateX(0);
}
.theme-list {
display: flex;
overflow-x: scroll;
gap: 1rem;
}
.theme-swatch {
display: inline-block;
width: 70px;
height: 125px;
background: var(--background-gradient);
border-radius: 10px;
}
window.addEventListener('load', function() {
if (window.matchMedia( '(max-width: 600px)' ).matches) {
const themeModes = ['themeFirts', 'themeSecond', 'themethird'];
const themeUls = document.getElementsByClassName('theme-list');
themeModes.forEach((mode, index) => {
const themes = document.getElementsByName(mode);
const themeUl = themeUls[index];
themes.forEach(theme => {
if (theme.checked) {
const selectedSwatch = theme.nextElementSibling;
selectedSwatch.scrollIntoView({inline: 'center'});
}
});
});
}
});
Cause scrollIntoView() is a relatively recent method, I tried replacing the line include scrollIntoView with below but didn’t make a difference.
const swatchRect = selectedSwatch.getBoundingClientRect();
const ulRect = themeUl.getBoundingClientRect();
const xpos = swatchRect.left - (ulRect.left + (ulRect.width / 2)) + themeUl.scrollLeft + (swatchRect.width / 2);
themeUl.scrollLeft = xpos;
When inspecting with Chrome’s debugger, both swatchRect and ulRect have all their values set to DOMRect {x: 0, y: 0, width: 0, height: 0, top: 0, ...}. However, when I retrieve the elements and use getBoundingClientRect() in the console, it returns a DOMRect with correct integer values.
Is this a specific issue with WebKit browsers? Or could it be a fundamental problem, such as the aside element not being within the visible area during loading, which prevents scrolling?
I hope I’m not simply doing stupid…