Thursday, May 23, 2024
HomeCSSThe digital keyboard API - Ahmad Shadeed

The digital keyboard API – Ahmad Shadeed


Have you ever come throughout a difficulty the place there’s a fastened component on cell, and when the keyboard is activated, that component will likely be hidden beneath the keyboard?

This has been a default habits on the net for years. On this article, we’ll discover the issue, why it occurs, and the way we are able to resolve it at present with the digital keyboard API.

Let’s dive in.

The issue

Earlier than diving into the nice particulars, allow us to stroll by means of an instance. This can be a UI that has the next:

  • Sticky header
  • Sticky floating motion button (FAB)

When the consumer focuses on the enter, the digital keyboard will present. Are you able to count on what is going to occur?

The browser will scroll upwards to make the enter above the keyboard, and thus the sticky header and floating button will disappear.

It seems just like the next:

This can be a default habits in cell browsers typically. From a UX perspective, it is perhaps annoying to cover elements of the UI, particularly these elements which can be associated to the present motion I’m doing whereas the keyboard is energetic.

Behind the scenes, what occurs is one thing just like the next determine.

In technical phrases, the seen half is known as the visible viewport, and the hidden elements together with what’s at the moment seen is the structure viewport.

The principle downside is that the visible viewport shrinks in dimension when the digital keyboard is energetic.

Repair content material hidden below the keyboard with the digital keyboard API

Because of the digital keyboard API, we are able to outline that each the visible and structure viewports are equal. With that, we are able to detect the keyboard place and dimensions with the next CSS setting variables:

  • keyboard-inset-top
  • keyboard-inset-right
  • keyboard-inset-bottom
  • keyboard-inset-left
  • keyboard-inset-width
  • keyboard-inset-height

By utilizing the above variables, we are able to alter a structure when the digital keyboard is energetic.

Browser help

On the time of writing this text, the VirtualKeyboard API is supported solely in Chrome for Android.

Within the subsequent part, I’ll discover just a few examples and use-cases the place it may be useful.

Enabling the digital keyboard API

This API isn’t obtainable by default. We have to use Javascript to allow it.

See the next:

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

I discovered this a bit bizarre; utilizing Javascript to allow such habits. I agree with Bramus in his article in regards to the matter. He steered utilizing a meta tag like this:

<!-- Proposal -->
<meta
  title="viewport"
  content material="width=device-width, initial-scale=1.0, virtual-keyboard=overlays-content"
/>

Or CSS property:

html {
  virtual-keyboard: overlays-content;
}

Replace: 2 Aug 2023

Bramus kindly famous that there’s a new interactive-widget within the viewport meta tag which helps in altering the resizing habits.

See MDN for particulars.

I attempted to check that in Chrome on Android (v113), but it surely’s not working. I’ll replace the article as I do know extra about this.

Use circumstances for the VirtualKeyboard API

Backside-fixed actions

On a smaller viewport, you may have to have a name to motion button or footer that’s fastened to the underside of the UI.

Take into account the next determine the place now we have a CTA button that’s fastened to the underside. In the course of the display screen, there may be an enter discipline.

When the enter discipline is energetic, the checkout button will likely be below the digital keyboard, thus it’s hidden.

We will repair that simply with the digital keyboard API.

enter {
  font-size: 16px;
}
.cta {
  backside: env(keyboard-inset-height, 0);
}

On cell, the worth of backside will likely be equal to the keyboard peak, thus offsetting the CTA button with that worth. If the browser doesn’t help the API, it should default to zero.

You is perhaps questioning in regards to the decreased house as a result of presence of the header and stuck backside. We will use vertical media queries to indicate the header if the vertical house is sufficient.

Scrolling to the very finish of the web page isn’t potential

When there may be an merchandise with place: fastened on the very backside of the viewport, we normally add a padding-bottom to offset the web page and permit the consumer to scroll to the very finish.

physique {
  --cta-height: 60px;
  padding-bottom: var(--cta-height);
}

.cta {
  backside: env(keyboard-inset-height, 0);
}

The padding-bottom ought to be a worth that is the same as or larger than the fastened component peak.

Cool, proper? What occurs once we contain a digital keyboard? Let’s have a look.

Take into account the next determine:

When the digital keyboard is energetic, the padding-bottom worth with the peak of the fastened component isn’t sufficient. We have to add a keyboard to it.

To visualise the difficulty higher, here’s a video:

To repair that, we have to detect when the enter is concentrated and alter the padding-bottom based mostly on that.

physique:has(enter:focus) {
  padding-bottom: calc(
    var(--cta-height) + env(keyboard-inset-height, 0)
  );
}

You may surprise, what is going to occur on desktop? Good query. The env() will fall again to 0 and the overall will outcome within the worth of var(--cta-height).

Floating motion button

On this instance, now we have a floating motion button that’s positioned on the backside proper nook of the web page.

When the keyboard is energetic, the floating button ought to transfer above it. As within the very first instance, the floating button will likely be below the keyboard.

To repair that, we are able to use the env(keyboard-inset-height) worth.

Let’s stroll by means of the answer:

.fab {
  /* different kinds */
  backside: calc(1rem + env(keyboard-inset-height, 0rem));
}

I used 1rem plus the keyboard peak, to keep away from having the floating button immediately on the prime fringe of the keyboard.

With CSS comparability capabilities, it’s necessary to notice that utilizing a unitless quantity for the fallback worth inside the env() will break the entire thing in Safari. We should add the unit rem.

Utilizing a special worth for desktop

Suppose that we need to offset the floating button a bit extra on desktop browsers, how we are able to try this? Nicely, I considered utilizing the max() comparability perform, and it labored.

.fab {
  /* different kinds */
  backside: max(2rem, 1rem + env(keyboard-inset-height, 0rem));
}

Right here is the way it works:

  1. The comparability perform will evaluate between the 2 values. Because the env(keyboard-inset-height) evaluates to zero on desktop, the utmost worth is 2rem.
  2. On cell, the utmost worth is the second.

To study extra about CSS comparability capabilities, you may learn this text.

Chat structure

I obtained impressed by the instance in this text by Thomas Steiner and wished to indicate you the way it works.

Take into account the next determine:

When the keyboard is energetic, each the header and the message discipline are hidden. We will use the env(keyboard-inset-height) as a worth for the grid-row property.

.structure {
  show: grid;
  grid-template-rows: auto minmax(0, 1fr) auto env(keyboard-inset-height, 0);
  peak: 100dvh;
}

Right here is the way it seems with the repair above:

Use the digital keyboard API correctly

The digital keyboard ought to be used solely when wanted. Utilizing it in every context may trigger issues. Sure, you learn that proper.

Let’s take a easy instance. We now have a contact web page with lengthy content material and kind inputs. If we opt-in for making the digital keyboard overlaying the web page’s content material, it received’t be potential to scroll to the very finish of the shape.

On this case, I don’t advocate having the keyboard overlay the content material. Use it correctly.

See the next video to get a sense of the issue:

Demo on Codepen

Utilizing the comparability capabilities with the digital keyboard API

Morphing a button based mostly on the visibility of the digital keyboard

This is perhaps a ineffective use case or an instance, but it surely’s attention-grabbing to see what occurs when a characteristic is used to its full potential.

I assumed to myself, why not combine CSS comparability capabilities and the digital keyboard env values? I did that, and it labored.

See the video beneath:

How does that work? Right here you go:

.fab {
  --size: 4rem;
  place: fastened;
  /* [1] */
  proper: min(1rem, 100vw - env(keyboard-inset-width, 0rem));
  /* [2] */
  backside: max(1rem, env(keyboard-inset-height, 0rem));
  /* [3] */
  width: max(var(--size), env(keyboard-inset-width, 0rem));
  peak: var(--size);
  /* [4] */
  border-radius: max(
    0px,
    min(50px, 100% - env(keyboard-inset-width))
  );
  /* different kinds */
}

This works on each desktop and cell. Here’s what’s taking place:

  1. The proper worth will likely be both 1rem or zero. The primary is for desktop, and the latter is for cell (when the keyboard is energetic). 100vw is the same as the keyboard width in that case, thus the end result is zero. min(1rem, 0).
  2. The underside worth will likely be both 1rem or the keyboard’s peak.
  3. The width on the desktop dimension is the same as the --size variable, and on cell, it should take the total width, thus why env(keyboard-inset-width, 0) is used.
  4. Lastly, the border-radius could be both 50px or 0.

Neat, proper? I’ve by no means anticipated to give you such a demo. Do you assume it could possibly be helpful? I’m excited to see what you’ll construct.

Demo on Codepen

Linkedin publish kind and navigation

An instance that I noticed good potential for making use of the digital keyboard API is how the publish kind & navigation are proven for a Linkedin publish.

Take into account the next determine:

The publish kind and navigation are fastened to the underside. When the consumer prompts the enter discipline, it seems like this:

Discover how the vertical actual property is just too small. What do to do? By mixing comparability capabilities and the digital keyboard API, we are able to cover the navigation when the keyboard is proven.

Right here is the CSS that does that.

.post-form,
.nav {
  place: fastened;
  left: 0;
  proper: 0;
}

.post-form {
  backside: max(48px, env(keyboard-inset-height, 0px));
}

.nav {
  backside: max(0px, env(keyboard-inset-height, 0) - 100px);
}

Don’t fear, I’ll clarify it little by little.

Publish kind

Within the default state, the shape is offset by 48px from the underside. On this state, the second a part of the max() perform is inactive.

When the keyboard is energetic, the second a part of the max() will work and the backside worth will turn out to be the peak of the keyboard.

The navigation is positioned at backside: 0. The primary a part of the max() perform is what’s energetic now.

When the keyboard is energetic, we’ll transfer the nav below the keyboard. The 100px here’s a random quantity, the purpose is so as to add one thing that’s bigger than the navigation’s peak.

Here’s a video of the way it works:

Demo on Codepen. You may also view all demos within the Codepen collections.

Outro

That’s it for this text. I discovered loads in regards to the digital keyboard API and might’t wait to use it in my subsequent mission. The very last thing I anticipated is to put in writing 1600 phrases on such a subject. If meaning something, it means to by no means belief your interior emotions about one thing you don’t know. Simply begin and the great issues will observe.

Do you’ve gotten any ideas or questions? Please be happy to ping me on Twitter (sorry, X) @shadeed9 or Mastodon or Threads.

Assets

The next sources helped me loads in my preliminary analysis in regards to the matter.

Thanks for studying.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments