Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Wed, 05 Feb 2025 22:11:59 +0000 en-US hourly 1 https://wordpress.org/?v=6.9 225069128 HTML & CSS for a One-Time Password Input https://frontendmasters.com/blog/html-css-for-a-one-time-password-input/ https://frontendmasters.com/blog/html-css-for-a-one-time-password-input/#comments Wed, 05 Feb 2025 22:11:57 +0000 https://frontendmasters.com/blog/?p=5067 You know those One Time Password inputs? The UI is typically 4 or 6 numbers with individual inputs. Just from today…

Here’s the UI the Safeway app uses in the Pharmacy section to log in.
Here’s how Substack authenticates.

Brad Frost was blogging about them recently. They certainly have some issue! Here’s one he spells out that I agree with wholeheartedly:

I don’t like the pattern where each digit is its own text box. It’s an affordance that’s supposed to make things clearer, but it doesn’t (for me at least). Can I paste? Where do I paste? Is my paste going to carry over into all of the little boxes? Half the time there’s a dash in the code; does that get included?

It’s awfully tricky to get right, considering the user confusion that can happen before you’re interacting with those little boxes. And once you are, the experience better be awfully accommodating.

A while back I read an article by Phuoc Nguyen about them called Build an OTP input field. I’d say all-in-all, Phuoc did a good job. The design and user experience was considered, like using the arrow keys to move between the inputs and handling “paste”. I’d say accessibility too but I feel like this is complicated enough of an interaction I can’t personally vouch for that.

But I’m also also like — damn — that’s complicated. That’s a lot of JavaScript code. Why is this so hard? And what would happen without JavaScript? Seems like it would be a pretty gnarly experience. A particular thing that makes it hard is making each character a separate <input /> in the HTML.

<div class="otp">
    <input type="text" maxlength="1" />
    <input type="text" maxlength="1" />
    <input type="text" maxlength="1" />
    <input type="text" maxlength="1" />
</div>

That complicates validation, input, pasting, accessibility, navigation… literally everything.

And then I was like… why can’t this just be one input? The rectangles behind the numbers is just visual theater. Just a bit of trendy decoration. It’s just a styling concern, not a semantic, usability, or any other concern.

So I was like… I’m just gonna make those rectangles background-images and see if that works. So I built a demo, but it had a flaw: as you typed the last character, the value would kinda slide one direction and look bad. You can see it here.

But I posed the challenge in our ShopTalk Discord and others had some ideas. Josh Collingsworth had an idea where you could cover up some area at the end and prevent the movement issue (the yellow block would be white or whatever covers up properly). Alex Fimion did it a smidge cleaner by covering the last bit with background-image instead of a pseudo-element. Here’s that:

Is that better than the 4-inputs approach?

I’m giving an only-slightly-hesitant thumbs up 👍. My hesitation is that in order for this to look right, there is a lot of “magic number” usage. That is, numbers that are just visually tweaked by hand to make it all work, and based on finicky things like font metrics (which might change over time and with different fonts) rather than hard foundational layout.

So let’s call this a pretty good take. I think when you consider the HTML used alone you can see using a one-input approach feels best:

<input
  required
  type="text"
  autocomplete="one-time-code"
  inputmode="numeric"
  maxlength="4"
  pattern="\d{4}"
>

In fact, if I started having problems with the look of the “rectangles behind the numbers” approach, I’d just make it a big ol’ single input without the individual rectangles. Like I said, I feel those are just something of a design trend anyway.

What does AI want to do?

Just as a fun little exercise, I used the very generic prompt create a 4 digit PIN input UI with zero rounds of feedback/iteration across a number of different scaffolding tools.

v0 used TSX and four individual inputs and tried to help with dealing with the complex UX. It worked decently once, then two more tries it tried using shadcn and some toast library and all kinds of stuff and just failed to run at all.
Copilot wanted four individual inputs and helped with the moving to the next input after any character typed, but none of the other issues.
Cascade (in Windsurf) went with a single input (!) and got the HTML pretty decent.
Bolt.new used a React/TSX/Tailwind approach with four inputs and handled pasting, input moving, etc pretty nicely.

I’m fairly confident that if you provided a more elaborate prompt with more specific requirements and were willing to go through rounds of iteration, you could get what you want out of these tools. I just found it interesting that by default, based on the code they were trained on, that what you get tends to focus on using multiple inputs, not to mention a heap of tools you don’t ask for.

]]>
https://frontendmasters.com/blog/html-css-for-a-one-time-password-input/feed/ 4 5067
Auto-Sizing Textarea https://frontendmasters.com/blog/auto-sizing-textarea/ https://frontendmasters.com/blog/auto-sizing-textarea/#respond Fri, 05 Jan 2024 19:27:39 +0000 https://frontendmasters.com/blog/?p=357 Credit to Stephen Shaw for the original idea, there is a decently easy way to make an auto-sizing <textarea> element. It is here. But it’s not perfect. There is a frustrating hard-to-replicate iOS bug. Plus it’s just a trick. It requires JavaScript and some pretty specific CSS to pull off.

It’s awesome to see the web platform pick up an easy one-liner way to do this, by way of a new CSS property:

textarea {
  field-sizing: content;
}

Adam Argyle has a simple demo here to play with (note how the field-sizing can apply to inline size as well as block size). As I write, Chrome Canary has it in v122, and should go out in stable in late February. Let’s 🙏 for quick cross-browser support.

At one time when this was being played with, the CSS property was called form-sizing, but I think I like the update to field-sizing. I think of these things as “fields”, and quite notably it works on <input> as well as <textarea>. Fork Adam’s demo and have it apply to an input instead to see it work (in Chrome Canary).

]]>
https://frontendmasters.com/blog/auto-sizing-textarea/feed/ 0 357