Fix mobil webkit 100vh

A Mobile Webkit 100vh-s kezelésére nagyobb figyelmet igényelhet

Vannak problémáim

Élvezve ezt a webes alkalmazásomat, mindig azt vettem észre, hogy a hajtás feletti tartalom kissé megtört. Ha újratölti az oldalt, akkor látni fogja, hogy az egyes blogbejegyzések első betöltött tartalma a következő elemeket tartalmazza:

  • A bejegyzés címe
  • Alcím rövid leírással
  • Lábléc szerzővel, kategóriával és dátummal

Ennek a láblécnek az a célja, hogy az oldal betöltésekor mindig látható legyen a nézetablak alján, utánozva egy magazinszerű borító nézetet. Szépen néz ki, világos üzenetet közöl (vagyis miről szól ez a bejegyzés), és elkerüli az esetleges elhajlásokat. Ez az egész hős egyszerű módon valósul meg a CSS-érték: 100vh használatával, az eszköz képernyőjének összes rendelkezésre álló magasságának felhasználásával.

Amikor a felhasználó kissé lefelé görget, ez a hősborító elhalványul, és helyet ad a tényleges tartalomnak. Vicces, hogy ez soha nem működött az iOS rendszeren. Így nézett ki:

Image f1a30a30a13c

Amint láthatja, lábléc nem látható. Valójában a Safari alsó sávja alatt van elrejtve.

Van megoldásom

Miután felvettem a sherlock kalapomat és megkezdtem a vizsgálatot a világhálón, biztosan felfedeztem egy megoldást, mivel másoknak már korábban is volt ilyen problémájuk.

tl; dr: a Webkit -webkit-fill-available használata trükköt tesz. Így néz ki:

.hero-container {
  min-height: 100vh;
  /* fix for mobile webkit */
  min-height: -webkit-fill-available;
}

Ennek a sablonként való használata a JSS megoldásomnál nem sikerült 100% -osan. A magasság csak csökkentette a konténer belső magasságát. Ezért fel kell derítenem, hogy milyen eszközön vagyok, és feltételesen alkalmazom a megfelelő stílust.

/**
 * 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;
}

Ami most megmaradt, az a feltételes használat:

// 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,
  },
}))

A fenti javítást alkalmazva minden most szépen működik. Köszönöm az olvasást! Az említett eredeti bejegyzések forrásai az alábbi függelékben.

  • Tom