لدي مشاكل
أثناء الاستمتاع بتطبيق الويب هذا الخاص بي ، لاحظت دائمًا أن المحتوى في الجزء المرئي من الصفحة في رحلات السفاري على الهاتف المحمول كان معطلاً إلى حد ما. إذا قمت بإعادة تحميل الصفحة ، فسترى أن المحتوى الأول الذي تم تحميله لكل منشور مدونة يحتوي على العناصر التالية:
- عنوان المنشور
- عنوان فرعي مع وصف قصير
- تذييل مع المؤلف والفئة والتاريخ
يهدف هذا التذييل إلى أن يكون مرئيًا دائمًا في الجزء السفلي من منفذ العرض عند تحميل الصفحة ، لتقليد عرض غلاف يشبه المجلة. يبدو لطيفًا ، وينقل رسالة واضحة (أي ما يدور حوله هذا المنشور) ويتجنب أي انحرافات. يتم تنفيذ هذا البطل بأكمله بطريقة مباشرة باستخدام ارتفاع قيمة CSS: 100vh ، باستخدام كل الارتفاع المتاح لشاشة الجهاز.
عندما يقوم المستخدم بالتمرير لأسفل قليلاً ، يتلاشى غطاء البطل هذا مما يجعله مكانًا للمحتوى الفعلي. الشيء المضحك هو أن هذا لم ينجح أبدًا على نظام التشغيل iOS. هذا هو الشكل الذي بدت عليه:
كما ترى ، لا يوجد تذييل مرئي. في الواقع ، إنه مخفي أسفل شريط Safari السفلي.
لدي حل
بعد ارتداء قبعة شيرلوك الخاصة بي وبدء تحقيق في شبكة الويب العالمية ، اكتشفت بالتأكيد حلاً لأن الآخرين واجهوا هذه المشكلة من قبل.
tl ؛ dr: استخدام Webkit's -webkit-fill-available يفي بالغرض. هذا ما يبدو عليه:
.hero-container {
min-height: 100vh;
/* fix for mobile webkit */
min-height: -webkit-fill-available;
}
ومع ذلك ، فإن استخدام هذا كقالب لحل JSS الخاص بي لم ينجح بنسبة 100٪. تم تقليل الارتفاع فقط من الارتفاع الجوهري للحاوية. لذلك ، لا بد لي من اكتشاف الجهاز الذي أستخدمه وتطبيق التصميم الصحيح بشكل مشروط.
/**
* Check if current session runs in
* a mobile webkit instance.
*/
export function isMobileWebkit() {
const ua = window.navigator.userAgent;
const iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
const webkit = !!ua.match(/WebKit/i);
return iOS && webkit && !ua.match(/CriOS/i);
}
/**
* As I'm using Next.js, window is undefined
* on the server, therefore we need to call
* 'isMobileWebkit' after mounting.
*/
export function useIsMobileWebkit() {
const [flag, setFlag] = useState(false);
useEffect(() => setFlag(isMobileWebkit()), []);
return flag;
}
ما تبقى الآن هو الاستخدام الشرطي:
// We're using 'clsx' for classname merging.
import clsx from "clsx";
function Hero(){
const classes = useStyles();
return (
<div
className={clsx(classes.hero, {
[classes.heroCssWebkitFix]: isMobileWebKit,
})}>
...
</div>
);
}
// ... slice of the styling:
const useStyles = makeStyles(theme => ({
hero: {
minHeight: "100vh",
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "stretch",
paddingBottom: theme.spacing(2),
paddingTop: theme.spacing(2),
},
heroCssWebkitFix: {
// mobile viewport bug fix
minHeight: "-webkit-fill-available",
paddingBottom: 0,
},
}))
بتطبيق الإصلاح أعلاه ، كل شيء يعمل الآن بشكل جيد. شكرا على القراءة! مصادر المشاركات الأصلية المذكورة أدناه في الإضافة.
- Tom