Mobile Optimization: The Surprisingly Tricky World of Mobile UX

 


When a Desktop-Perfect App Falls Apart on Mobile

"It works fine on desktop, though." This might be the most dangerous sentence in frontend development. The first time I opened Tarot Master on my phone, the bottom of the screen was cut off. Card flip animations stuttered. Text was too small to read. Where did that elegant desktop experience go?

Over half of all web traffic comes from mobile devices. For a lightweight entertainment app like Tarot Master, that proportion is even higher. On the commute, in bed, during coffee with a friend -- "Want to try a tarot reading?" happens on a phone. A bad mobile experience means losing the majority of your users.

Bottom Tab Bar: Borrowing Native App Sensibility

The most natural navigation pattern on mobile is a bottom tab bar. Instagram, WhatsApp, practically every native app uses bottom tabs. Placing primary actions where the thumb naturally rests is the foundational principle of mobile UX.

I added a bottom tab bar to Tarot Master: Home, Reading, History, Settings. Four tabs. Implementing a bottom tab bar in a web app isn't technically hard. CSS position: fixed and bottom: 0 and you're done. But that's where the real problems begin.

Mobile browsers have their own UI. Address bars, bottom toolbars. These elements consume screen space and collide with our bottom tab bar. Especially when scrolling causes the browser UI to appear and disappear, the layout dances unpredictably.

The CSS environment variable env(safe-area-inset-bottom) helped. This value reports the size of system UI areas like notches and home indicators. Adding it to the tab bar's padding positions tabs in a safe zone that avoids system UI overlap. But that was just the beginning.

Chrome Mobile's Infamous Bottom Bar Bug

The most painful issue was Chrome mobile's bottom bar positioning bug. Chrome shows and hides the bottom URL bar based on scroll direction, dynamically changing the viewport height. The problem is that this height change isn't always reflected in the CSS 100vh value.

The result: our bottom tab bar hides behind Chrome's bar, or when Chrome's bar disappears, an awkward empty gap appears at the bottom. I scrolled up and down dozens of times muttering "Why is this happening?"

Here's how I tackled it. First, I tried CSS's 100dvh (dynamic viewport height) instead of 100vh. This newer CSS unit reflects dynamic browser UI changes. It improved most situations, but certain Android Chrome versions still misbehaved.

Eventually I added JavaScript-based viewport height detection. Using window.innerHeight to calculate the actual available height, then injecting it as a CSS custom property. Combined with the resize event and visualViewport API, this also handles keyboard appearance.

When I asked Claude about "fixing the position of a bottom-fixed element affected by browser UI changes on Chrome mobile," I received several approaches. But which one actually works could only be determined by testing on real mobile devices. AI solutions are theoretically correct but frequently behave differently on actual hardware. The bug-hunting process drove that point home.

Touch Interfaces: A World Without Hover

On desktop, mouse hover is a powerful feedback mechanism. Hover over a button and it changes color; hover over a card and it enlarges. On mobile, hover doesn't exist. The moment a finger touches the screen, it's a tap, not a hover.

Every hover-dependent interaction needed redesign. The card hover zoom was replaced with a momentary scale-up on touch before flipping. Tooltips moved to long-press triggers. Button hover color changes became active-state (press-moment) styles.

Touch target size was another critical issue. Both Apple and Google recommend minimum touch targets of 44x44 points. Small icon buttons that work fine with a mouse cursor are too small for fingertips. I ensured every interactive element -- card selection, menu buttons, share icons -- met minimum size requirements.

Scroll behavior needed attention too. Horizontal swipe to navigate cards conflicted with the browser's back-gesture. The solution: swipes starting from the screen edge yield to the browser, while swipes starting from the center area trigger card navigation. The kind of fine-grained adjustment you only discover through actual use.

The Reality of Responsive Design: Shrinking Isn't Enough

Initially I thought responsive design was simple. Take a large-screen layout and shrink it for smaller screens. Right? Wrong.

The three-card layout displaying cards side by side on desktop becomes microscopic if you just scale it down on mobile. Stacking vertically means they don't fit on one screen. I ended up building a separate slide-based layout where users swipe left and right to view one card at a time.

The Celtic Cross spread's ten-card layout was even more challenging. Desktop can show the traditional arrangement (cross formation in the center, four cards to the side), but that's impossible on mobile. I designed a mobile-specific layout converting it to a scrollable list. Same information, different presentation.

The lesson: true responsive design isn't "shrinking the layout." It's "designing optimal experiences for each screen size." It's not always solvable with a media query. Sometimes it means rendering entirely different components.

Linear-Inspired UI Overhaul: Modern and Clean

As features accumulated, the UI grew cluttered. More buttons, more information, more visual noise. That's when I drew inspiration from Linear's interface and decided on a full redesign.

Linear is a project management tool with a strikingly clean UI. It exercises extreme restraint in removing unnecessary elements, uses whitespace boldly, and achieves elegance through minimal icons and smooth animations. I adopted this philosophy for Tarot Master.

Specific changes: from rounded card-style layouts to sharp, linear design. From colorful gradient buttons to minimal outline buttons. From packed layouts to breathable ones with ample whitespace. Each change was small, but the overall impression shifted from "amateur side project" to "properly crafted product."

When I asked Claude to help "redesign with a Linear-style minimal UI," I received concrete guidelines for whitespace ratios, font-size scales, and color minimization. But applying them and making the judgment call on "does this much whitespace feel empty?" was ultimately mine. Design isn't completed by rules alone; it requires sensibility built on top of rules.

The Reality: Most Users Are on Mobile

Tarot Master's usage data shows a dominant mobile proportion. This isn't unique -- it's reality for most content-driven web services. Tarot, being personal and casually consumed, skews even more mobile.

Accepting this reality reshapes priorities. Not "build on desktop, adapt for mobile" but "build for mobile, expand to desktop." The so-called mobile-first approach. You hear it everywhere, but actually developing this way requires a conscious shift.

Development habits changed too. Instead of relying on Chrome DevTools' mobile simulation while coding on a wide desktop monitor, I built a habit of frequently checking on an actual smartphone. DevTools simulation reproduces a lot, but it can't perfectly replicate real device touch responsiveness, scroll inertia, or keyboard behavior.

What Mobile Optimization Taught Me

The biggest lesson from mobile optimization: mobile support isn't "extra work." It's "the work." If I had designed mobile-first from day one, I could have saved half the time I spent retrofitting later.

AI helped with mobile optimization but had clear limits. It suggests CSS properties and layout patterns well, but it cannot judge "how does this actually feel on a real phone?" Touch response timing, scroll smoothness, transition naturalness. These sensory validations can only happen at the fingertips of an actual person.

Ultimately, mobile optimization isn't a code problem. It's an experience problem. Code is the tool; the core question is what experience you're building with it. And that judgment can only be made by holding a real device in your hands.

What's Next

Features built, mobile optimized. But through all of this, one important question lingered: do I actually understand the code AI generated? In the next part, I discuss the trap of "vibe coding" and why I chose a different path I call "intent-based collaboration."

댓글

이 블로그의 인기 게시물

사랑을 직접 올리지 않는 설계

시작의 충동 — "타로 웹앱을 만들어볼까?"

감정을 변수로 옮기다 — 3계층 감정 모델