How to detect a virtual keyboard position & dimensions?

Løs Virtuel Tastatur UI-Problemer på Mobil

17/07/2023

Rating: 4.25 (13652 votes)

Som webudviklere og designere støder vi ofte på en frustrerende udfordring på mobile enheder: faste elementer, såsom headere, footere eller svævende handlingsknapper (FABs), forsvinder under det virtuelle tastatur, når det aktiveres. Dette har længe været en standardadfærd på nettet, men det skaber en dårlig brugeroplevelse, da vigtige dele af brugergrænsefladen pludselig bliver utilgængelige. I denne artikel vil vi dykke ned i problemet, forklare hvorfor det sker, og vigtigst af alt, vise hvordan vi kan løse det i dag ved hjælp af det nye og kraftfulde Virtual Keyboard API. Lad os komme i gang og genvinde kontrollen over vores mobile layouts.

How to detect a virtual keyboard position & dimensions?
Thanks to the virtual keyboard API, we can define that both the visual and layout viewports are equal. With that, we can detect the keyboard position and dimensions with the following CSS environment variables: By using the above variables, we can alter a layout when the virtual keyboard is active.
Indholdsfortegnelse

Problemet: Faste Elementer Forsvinder

Forestil dig et typisk mobil-UI med en fast header øverst og en svævende handlingsknap (FAB) i nederste højre hjørne. Når en bruger trykker på et inputfelt for at indtaste tekst, popper det virtuelle tastatur op. Hvad sker der så? Browseren ruller typisk indholdet opad for at sikre, at inputfeltet forbliver synligt over tastaturet. Som et resultat forsvinder den faste header og FAB'en ud af syne. Dette adfærdsmønster, hvor browseren tilpasser layout viewporten for at gøre plads til tastaturet, kan føre til en forringet brugeroplevelse, især når de skjulte elementer er relevante for den handling, brugeren er i gang med.

Teknisk set er den synlige del af skærmen kendt som den 'visuelle viewport', mens den samlede del, der inkluderer det, der er synligt og det, der er skjult af tastaturet, kaldes 'layout viewport'. Det primære problem er, at den visuelle viewport skrumper i størrelse, når det virtuelle tastatur er aktivt, og traditionelt har vi ikke haft en nem måde at programmatisk reagere på denne ændring på en pålidelig måde.

Løsningen: Virtual Keyboard API

Takket være Virtual Keyboard API kan vi nu definere, at både den visuelle og layout viewport forbliver lige store, selv når tastaturet er aktivt. Dette giver os mulighed for at 'overlejre' indholdet over tastaturet, i stedet for at skubbe det op. Endnu bedre er det, at API'et giver os adgang til tastaturets position og dimensioner gennem en række nye CSS-miljøvariabler. Disse miljøvariabler kan bruges til dynamisk at justere vores layout, når det virtuelle tastatur er synligt.

De nye CSS-miljøvariabler:

MiljøvariabelBeskrivelse
keyboard-inset-topAfstanden fra tastaturets øverste kant til viewportens øverste kant.
keyboard-inset-rightAfstanden fra tastaturets højre kant til viewportens højre kant.
keyboard-inset-bottomAfstanden fra tastaturets nederste kant til viewportens nederste kant.
keyboard-inset-leftAfstanden fra tastaturets venstre kant til viewportens venstre kant.
keyboard-inset-widthTastaturets bredde.
keyboard-inset-heightTastaturets højde.

Ved at bruge disse variabler kan vi ændre et layout, når det virtuelle tastatur er aktivt, og dermed undgå, at faste elementer skjules. Dette åbner op for en række nye designmuligheder og forbedrer interaktionen markant for mobilbrugere.

Aktivering af Virtual Keyboard API'et

På nuværende tidspunkt er dette API ikke aktiveret som standard. Vi skal bruge JavaScript for at slå det til. Dette gøres ved at sætte overlaysContent-egenskaben til truenavigator.virtualKeyboard-objektet:

if ("virtualKeyboard" in navigator) { navigator.virtualKeyboard.overlaysContent = true; }

Selvom det fungerer, finder mange udviklere det lidt mærkeligt at skulle bruge JavaScript til at aktivere en sådan grundlæggende adfærd. Der har været forslag om at bruge en meta-tag i HTML-hovedet, lignende dette:

<meta name="viewport" content="width=device-width, initial-scale=1.0, virtual-keyboard=overlays-content" />

Eller en CSS-egenskab:

html { virtual-keyboard: overlays-content; }

Disse alternative metoder ville give en mere deklarativ måde at styre tastaturets adfærd på, hvilket ville være en fordel for både udviklere og ydeevne. Det er dog værd at bemærke, at der er en ny interactive-widget-egenskab i viewport meta-tagget, som hjælper med at ændre resizing-adfærden, hvilket er et skridt i den rigtige retning.

Browserunderstøttelse

På tidspunktet for denne artikels skrivning er Virtual Keyboard API'et desværre kun understøttet i Chrome til Android. Dette begrænser dets umiddelbare anvendelse på tværs af alle mobile platforme, men det er et vigtigt skridt fremad, og vi kan forvente, at andre browsere vil følge trop over tid. På browsere, der ikke understøtter API'et, vil env()-funktionen falde tilbage til dens standardværdi (som typisk er 0), og den traditionelle adfærd vil fortsætte.

Anvendelsestilfælde for Virtual Keyboard API'et

Lad os nu udforske nogle konkrete eksempler og use cases, hvor Virtual Keyboard API'et kan være utroligt nyttigt for at forbedre din mobile brugergrænseflade.

1. Faste handlingsknapper i bunden

På en mindre viewport er det almindeligt at have en 'call to action'-knap (CTA) eller en footer, der er fastgjort til bunden af brugergrænsefladen. Uden Virtual Keyboard API vil denne knap ofte blive skjult under tastaturet, når et inputfelt aktiveres. Med API'et kan vi nemt løse dette:

input { font-size: 16px; } .cta { /* Flytter CTA-knappen opad med tastaturets højde */ bottom: env(keyboard-inset-height, 0); }

På mobil vil værdien af bottom blive lig med tastaturets højde, hvilket forskubber CTA-knappen med denne værdi. Hvis browseren ikke understøtter API'et, vil den falde tilbage til nul, og knappen forbliver, hvor den var. Du undrer dig måske over den reducerede plads, hvis både en header og en fast bund er til stede. Her kan du bruge vertikale mediespørgsmål til kun at vise headeren, hvis der er tilstrækkelig vertikal plads.

2. Scrolling til slutningen af siden er ikke mulig

Når der er et element med position: fixed helt nederst i layout viewporten, tilføjer vi normalt en padding-bottom til body for at forskydde siden og tillade brugeren at scrolle helt til bunden. Denne padding-bottom skal være en værdi, der er lig med eller større end det faste elements højde.

body { --cta-height: 60px; padding-bottom: var(--cta-height); } .cta { bottom: env(keyboard-inset-height, 0); }

Men hvad sker der, når vi involverer et virtuelt tastatur? Når tastaturet er aktivt, er padding-bottom-værdien med højden af det faste element ikke nok. Vi er nødt til at tilføje tastaturets højde til det.

/* Anvend padding-bottom kun når et inputfelt er i fokus */ body:has(input:focus) { padding-bottom: calc(var(--cta-height) + env(keyboard-inset-height, 0)); }

På desktop vil env() falde tilbage til 0, og den samlede værdi vil resultere i var(--cta-height), hvilket sikrer korrekt adfærd på tværs af enheder.

3. Svævende handlingsknap (FAB)

I dette eksempel har vi en svævende handlingsknap, der er placeret i nederste højre hjørne af siden. Når tastaturet er aktivt, skal den svævende knap bevæge sig op over det. Uden Virtual Keyboard API vil den ofte ende under tastaturet. Vi kan løse dette ved at bruge env(keyboard-inset-height)-værdien:

.fab { /* Flyt FAB'en op med tastaturets højde plus en lille margin */ bottom: calc(1rem + env(keyboard-inset-height, 0rem)); }

Jeg brugte 1rem plus tastaturets højde for at undgå, at den svævende knap sidder direkte ved tastaturets øverste kant. Det er vigtigt at bemærke, at når du bruger CSS-sammenligningsfunktioner (som min() eller max()) med env(), skal du tilføje en enhed (f.eks. rem) til fallback-værdien for at undgå fejl i Safari.

Forskellige værdier for desktop og mobil

Antag, at vi ønsker at forskydde den svævende knap lidt mere på desktop-browsere. Vi kan bruge max()-sammenligningsfunktionen:

.fab { /* Vælg den højeste værdi: enten 2rem (desktop) eller 1rem + tastaturhøjde (mobil) */ bottom: max(2rem, 1rem + env(keyboard-inset-height, 0rem)); }

Her vil sammenligningsfunktionen vælge den største af de to værdier. Da env(keyboard-inset-height) evaluerer til nul på desktop, er den maksimale værdi 2rem. På mobil er den maksimale værdi den anden, som inkluderer tastaturets højde.

4. Chatlayout

Inspireret af eksempler fra andre udviklere kan Virtual Keyboard API'et også bruges til at forbedre chatlayouts. Overvej et chatvindue, hvor både headeren og meddelelsesfeltet skjules, når tastaturet er aktivt. Vi kan bruge env(keyboard-inset-height) som en værdi for grid-row-egenskaben i et CSS Grid-layout:

.layout { display: grid; /* Auto for header, minmax for indhold, auto for inputfelt, tastaturhøjde for ekstra plads */ grid-template-rows: auto minmax(0, 1fr) auto env(keyboard-inset-height, 0); height: 100dvh; /* Brug dynamisk viewport højde */ }

Dette sikrer, at chatinputfeltet og indholdet forbliver synligt og korrekt placeret, selv med det virtuelle tastatur åbent.

How do I get a viewport size without a virtual keyboard?
Using the following code after initiating the soft keyboard: viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute('content', 'height=auto'); And then getting the height using jquery shows CORRECT results on Android - aka the visible viewport size WITHOUT the virtual keyboard, but not on iOS.

Brug Virtual Keyboard API'et med omtanke

Det er vigtigt at understrege, at Virtual Keyboard API'et kun bør bruges, når det er nødvendigt. At aktivere det i enhver kontekst kan faktisk skabe problemer. Forestil dig en kontaktside med langt indhold og mange formularinputfelter. Hvis vi vælger at lade det virtuelle tastatur overlejre sidens indhold, vil det måske ikke være muligt at scrolle helt til slutningen af formularen, hvilket kan være yderst frustrerende for brugeren.

I sådanne tilfælde anbefales det ikke at lade tastaturet overlejre indholdet. Vælg i stedet den traditionelle adfærd, hvor browseren scroller indholdet. Brug API'et klogt og overvej altid den specifikke brugeroplevelse for hver side eller komponent.

Avancerede anvendelser og Kreative Muligheder

Morfing af en knap baseret på tastaturets synlighed

Dette er måske ikke en almindelig anvendelse, men det er et interessant eksempel på, hvad der sker, når en funktion bruges til sit fulde potentiale. Ved at blande CSS-sammenligningsfunktioner og Virtual Keyboard API's env()-værdier kan vi skabe dynamiske, morfende elementer.

.fab { --size: 4rem; position: fixed; /* Juster position for at undgå tastaturet */ right: min(1rem, 100vw - env(keyboard-inset-width, 0rem)); bottom: max(1rem, env(keyboard-inset-height, 0rem)); /* Morf bredde og border-radius */ width: max(var(--size), env(keyboard-inset-width, 0rem)); height: var(--size); border-radius: max(0px, min(50px, 100% - env(keyboard-inset-width))); }

Dette virker både på desktop og mobil. Når tastaturet er aktivt, vil knappen fx strække sig over hele bredden (width: max(var(--size), env(keyboard-inset-width, 0rem))) og miste sin border-radius (border-radius: max(0px, min(50px, 100% - env(keyboard-inset-width)))), hvilket skaber en unik visuel effekt.

LinkedIn-inspireret postformular og navigation

Et eksempel, der har stort potentiale for anvendelse af Virtual Keyboard API'et, er hvordan LinkedIn håndterer sin postformular og navigation. De er begge fastgjort i bunden. Når brugeren aktiverer et inputfelt, bliver den vertikale plads meget lille, og navigationen kan blive skjult.

Ved at blande sammenligningsfunktioner og Virtual Keyboard API'et kan vi skjule navigationen, når tastaturet vises, og flytte postformularen op:

.post-form, .nav { position: fixed; left: 0; right: 0; } .post-form { /* Flyt formularen op med tastaturets højde, men mindst 48px */ bottom: max(48px, env(keyboard-inset-height, 0px)); } .nav { /* Skjul navigationen under tastaturet, hvis tastaturet er synligt */ bottom: max(0px, env(keyboard-inset-height, 0) - 100px); }

Her vil .post-form normalt have bottom: 48px. Når tastaturet aktiveres, vil max()-funktionen sikre, at formularen bevæger sig op med tastaturets højde. For .nav vil bottom: 0px være standard. Når tastaturet aktiveres, vil env(keyboard-inset-height, 0) - 100px blive en negativ værdi (hvis tastaturet er højere end 100px), hvilket effektivt flytter navigationen ud af syne under tastaturet, da max(0px, ...) vil resultere i 0 eller en negativ værdi, der skubber den væk.

Ofte Stillede Spørgsmål (FAQ)

Hvad sker der, hvis en browser ikke understøtter Virtual Keyboard API'et?

Hvis en brugers browser ikke understøtter Virtual Keyboard API'et (f.eks. Safari på iOS eller Firefox), vil env()-funktionerne, du bruger i din CSS, falde tilbage til den anden værdi, du angiver. For eksempel vil env(keyboard-inset-height, 0) blot evaluere til 0. Dette betyder, at dine faste elementer vil opføre sig som de altid har gjort – de vil enten blive skubbet opad eller skjult under tastaturet, afhængigt af browserens standardadfærd. Din side vil stadig fungere, men uden de forbedrede layoutjusteringer.

Skal jeg altid aktivere overlaysContent?

Absolut ikke. Som diskuteret i afsnittet "Brug Virtual Keyboard API'et med omtanke", kan aktivering af overlaysContent på sider med meget indhold eller lange formularer faktisk forringe brugeroplevelsen. Hvis brugere har brug for at scrolle gennem indhold, mens tastaturet er aktivt, kan det være frustrerende, hvis tastaturet dækker en stor del af skærmen. Brug det specifikt for UI'er, hvor faste elementer er kritiske, og hvor tastaturet primært bruges til korte input, som i chatvinduer eller søgefelt. Overvej altid konteksten og brugerens intention.

Hvordan adskiller dette sig fra ældre metoder til at detektere tastaturet?

Tidligere har udviklere forsøgt at omgå problemet med tastatur-overlay ved hjælp af forskellige, ofte ustabile, metoder. Dette inkluderede at manipulere viewport meta-tagget (f.eks. <meta name="viewport" content="height=auto"/>) eller at lytte til resize-events og forsøge at udlede tastaturets højde ud fra ændringer i window.innerHeight. Disse metoder var ofte inkonsekvente på tværs af browsere (især mellem Android og iOS), upålidelige og kunne føre til visuelle 'hoppen' eller forkert beregnede højder.

Virtual Keyboard API'et giver en standardiseret, pålidelig og mere præcis måde at håndtere tastaturet på. Det giver direkte adgang til tastaturets dimensioner via CSS-miljøvariabler, hvilket er en langt mere robust løsning end at gætte sig frem baseret på viewport-størrelse, og det overvinder de begrænsninger og inkonsekvenser, der var forbundet med ældre, hackede løsninger.

Er der ydeevnepåvirkninger ved brug af Virtual Keyboard API'et?

Generelt er ydeevnepåvirkningen fra Virtual Keyboard API'et minimal. Det er designet til at give browsere mere kontrol over layoutet, hvilket ofte fører til bedre ydeevne, da browseren kan optimere renderingen. Brugen af CSS-miljøvariabler er også ydeevneeffektiv, da browseren håndterer beregningerne. Den største 'påvirkning' vil være den ændrede visuelle adfærd, som er den tilsigtede effekt, ikke en ydeevneudfordring.

Konklusion

Virtual Keyboard API'et repræsenterer et betydeligt fremskridt inden for mobil webudvikling. Det giver os endelig en robust og standardiseret måde at håndtere den irriterende adfærd, hvor faste UI-elementer skjules af det virtuelle tastatur. Ved at udnytte de nye CSS-miljøvariabler og den nye kontrol over overlaysContent kan vi skabe langt mere polerede og brugervenlige mobile oplevelser.

Selvom browserunderstøttelsen stadig er begrænset til Chrome for Android i øjeblikket, er potentialet enormt, og det er et API, som alle front-end udviklere bør holde øje med og begynde at eksperimentere med. Husk altid at overveje konteksten og brugeroplevelsen, når du beslutter, om du vil aktivere "overlay"-adfærden. Med de rette anvendelser kan Virtual Keyboard API'et markant forbedre tilgængelighed og interaktion for dine mobilbrugere, og løse en af de ældste UX-udfordringer på den mobile web.

Hvis du vil læse andre artikler, der ligner Løs Virtuel Tastatur UI-Problemer på Mobil, kan du besøge kategorien Teknologi.

Go up