Common Frontend Issues and Solutions for Mobile Browsers
This article compiles a series of practical solutions for frequent frontend problems on mobile devices, covering CSS position‑sticky failures, locale‑dependent date formatting, multiline ellipsis glitches, React useEffect height bugs, dual scrollbar conflicts, iPhone 6 scrolling issues, Android WebView reload quirks, request‑parameter encoding, and iOS 17 input focus jitter.
CSS position‑sticky not working on iPhone 6 Plus – The fix is to add the vendor‑prefixed rule after the standard one:
position: sticky;
position: -webkit-sticky; // vendor prefix must follownew Date().toLocaleDateString() returns Invalid Date on Singapore English – Specify the locale explicitly, e.g., new Date().toLocaleDateString('en-US') , to avoid the issue on mobile browsers.
Two‑line ellipsis showing a stray third line on some phones – The problem stems from line‑height and baseline alignment; avoid setting a fixed height on the text container, or wrap the text in an additional inner box with its own height.
Thai font overflow with a truncated second line – Increase the line‑height for Thai scripts to accommodate their larger glyph requirements.
useEffect initial clientHeight is incorrect – The first measurement may occur before CSS is applied; re‑measure after the component re‑renders or after the navigation header height stabilises, updating state accordingly.
import { useEffect, useState } from "react";
export default function useTop() {
const [top, setTop] = useState(0);
const [bodyHeight, setBodyHeight] = useState(document.body.clientHeight);
const newestTop = (document.getElementById('nav-header')?.clientHeight || 0) - 1;
if (newestTop !== top) {
setTop(newestTop);
setBodyHeight(document.body.clientHeight - (newestTop + 1));
}
useEffect(() => {
const nav = document.getElementById('nav-header');
const navHeight = nav?.clientHeight ?? 0;
setTop(navHeight - 1);
setBodyHeight(document.body.clientHeight - navHeight);
}, []);
return { top, bodyHeight };
}Two scrollbars triggering each other – When one uses scrollBy and the other scrollIntoView with behavior: smooth , the smooth animation keeps the first scrollbar in a perpetual state, blocking the second. Set the first scrollbar’s behavior to auto or delay the second call with a short setTimeout (≈100 ms, not exceeding 300 ms).
iPhone 6 cannot scroll horizontally or vertically – The DOM structure may prevent the low‑end iOS device from generating a scrollable area. Adjust the markup so the scroll container is properly recognized.
<div className="list-tabs-wrap">
<div className="list-tabs">
<div className="tab-item">tab1</div>
<div className="tab-item">tab2</div>
<div className="tab-item">tab3</div>
</div>
</div> .list-tabs-wrap { width: 100%; background-color: #fff; overflow: hidden; }
.list-tabs { overflow-x: scroll; overflow-y: hidden; -webkit-overflow-scrolling: touch; display: flex; flex-direction: row; flex-wrap: nowrap; height: 50px; background-color: #fff; }
.list-tabs::-webkit-scrollbar { display: none; }
.tab-item { width: 50vw; }Solution: introduce an inner container with overflow-x: scroll and width: max-content , while keeping the outer wrapper at overflow: hidden . This separates the two scrollbars and restores proper scrolling on iPhone 6.
.list-tabs-container { overflow-x: scroll; overflow-y: hidden; -webkit-overflow-scrolling: touch; width: max-content; }After applying the above, a new issue appeared where the scrollbar style stopped working. Fix by adding an outer box with a fixed height and overflow: hidden , and give the inner scrolling box a bottom padding (e.g., padding-bottom: 10px ) so the scrollbar appears within the padded area.
Android WebView: window.location.reload and replace not working – Use a timestamp query parameter to force a reload:
const reload = () => {
const timeStamp = new Date().getTime();
const oldUrl = window.location.href;
const url = `${oldUrl}${oldUrl.includes('?') ? '&' : '?'}timeStamp=${timeStamp}`;
window.location.href = url;
};
const locationReplace = (url) => {
if (history.replaceState) {
history.replaceState(null, document.title, url);
history.go(0);
} else {
location.replace(url);
}
};Some Android phones encode spaces as “+” in request bodies – Encode the parameter string before sending and decode it on the server side.
iOS 17 input focus causes page jitter – When an input receives focus, add height: 100vh; overflow: hidden; to the body . Remove these styles on blur to restore normal scrolling.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.