diff --git a/app/[lang]/providers.tsx b/app/[lang]/providers.tsx index 767e382..c04ad64 100644 --- a/app/[lang]/providers.tsx +++ b/app/[lang]/providers.tsx @@ -2,6 +2,9 @@ import { Provider } from "jotai"; +import { useDynamicViewportUnits } from "@/hooks/useDynamicViewportUnits"; + export default function Providers({ children }: { children: React.ReactNode }) { + useDynamicViewportUnits(); return {children}; } diff --git a/hooks/useDynamicViewportUnits.ts b/hooks/useDynamicViewportUnits.ts new file mode 100644 index 0000000..5f9928f --- /dev/null +++ b/hooks/useDynamicViewportUnits.ts @@ -0,0 +1,44 @@ +export const useDynamicViewportUnits = () => { + const setVh = function () { + var svh = document.documentElement.clientHeight * 0.01; + document.documentElement.style.setProperty('--1svh', (svh + "px")); + var dvh = window.innerHeight * 0.01; + document.documentElement.style.setProperty('--1dvh', (dvh + "px")); + }; + + const isMobile = function() { + if(/Android|iPhone|iPad|iPod/i.test(navigator.userAgent) || (navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2)) { + return true; + } + + return false; + } + + + // SSR support + if (typeof window === 'undefined') { + return; + } + + // Don't run polyfill if browser supports the units natively + if ('CSS' in window && + 'supports' in window.CSS && + window.CSS.supports('height: 100svh') && + window.CSS.supports('height: 100dvh') && + window.CSS.supports('height: 100lvh') + ) { + return; + } + + // Don't run on desktop browsers + if (!isMobile) { + return; + } + + window.addEventListener('resize', setVh); + setVh(); + + return () => { + window.removeEventListener('resize', setVh); + } +} diff --git a/tailwind.config.js b/tailwind.config.js index ae1fe18..7ae172a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -29,12 +29,13 @@ module.exports = { }, }, minHeight: { - // We use 100svh, falling back to vh for old browsers - // The 9rem is for the header and footer - content: ["calc(100vh - 9rem)", "calc(100svh - 9rem)"], + // We use 100svh, falling back to the the --1svh var that we add as a polyfill for older browsers. + // The 9rem is for the header and footer. + // In the event that the polyfill fails, we fall back to 0.9vh as a guess of how much 1svh is. + content: ["calc(var(--1svh, 0.9vh) * 100 - 9rem)", "calc(100svh - 9rem)"], }, height: { - content: ["calc(100vh - 9rem)", "calc(100svh - 9rem)"], + content: ["calc(var(--1svh, 0.9vh) * 100 - 9rem)", "calc(100svh - 9rem)"], }, }, },