Έχω προβλήματα
Ενώ απολάμβανα αυτήν την πολύ διαδικτυακή εφαρμογή μου, έχω παρατηρήσει πάντα ότι το περιεχόμενο στο πάνω μέρος στο κινητό σαφάρι ήταν κάπως σπασμένο. Εάν φορτώσετε ξανά τη σελίδα, θα δείτε ότι το πρώτο περιεχόμενο που φορτώνεται για κάθε ανάρτηση ιστολογίου περιέχει τα ακόλουθα στοιχεία:
- Τίτλος της θέσης
- Υπότιτλος με σύντομη περιγραφή
- Υποσέλιδο με συγγραφέα, κατηγορία & ημερομηνία
Αυτό το υποσέλιδο προορίζεται να είναι πάντα ορατό στο κάτω μέρος της θύρας προβολής κατά τη φόρτωση της σελίδας, μιμείται μια προβολή εξωφύλλου που μοιάζει με περιοδικό. Φαίνεται ωραίο, μεταδίδει ένα σαφές μήνυμα (δηλαδή σχετικά με αυτό το άρθρο) και αποφεύγει τυχόν παραμορφώσεις. Όλος αυτός ο ήρωας υλοποιείται με έναν απλό τρόπο χρησιμοποιώντας το ύψος τιμής 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