Mobile CTA Hidden on Some Phones: 7 Fixes for 2026

Fix Mobile CTA Hidden on Some Phones fast: 7 causes, copy-and-paste code, and QA checks for iOS/Android. Boost conversions, read the guide.

mobile cta hidden on some phones

TL;DR

A mobile CTA hidden on some phones is a usability defect where a primary action button (“Add to Cart,” “Book a Demo,” “Checkout”) becomes invisible or untappable on certain devices. The most common culprits are the 100vh viewport bug, missing safe-area insets on notched phones, on-screen keyboards covering fixed elements, and third-party overlays like cookie banners or chat widgets blocking taps. This guide walks through every root cause with copy-and-paste code fixes, a diagnostic workflow, and instrumentation to prove the problem exists.

What “Mobile CTA Hidden on Some Phones” Means

A mobile CTA hidden on some phones describes any situation where your primary call-to-action works fine on desktop (and maybe even on some mobile devices) but disappears, gets clipped, or becomes untappable on others. The button might be pushed below the visible area by browser chrome, buried under a chat launcher, trapped behind an invisible cookie-banner backdrop, or simply never rendered due to personalization rules that don’t recognize the visitor.

This isn’t a single bug. It’s a category of bugs with at least seven distinct causes, each requiring a different fix. The frustrating part is that Chrome DevTools device emulation won’t catch most of them, because it doesn’t fully replicate mobile browser engines, virtual keyboards, or safe-area behavior.

The business impact is straightforward: if visitors can’t see or tap your primary action, they don’t convert. Typical websites already convert at just 1 to 3 percent, so losing even a fraction of mobile users to a hidden CTA can meaningfully hurt revenue. For a deeper look at mobile-specific conversion thinking, the guide on mobile-first conversion strategies covers the broader strategic picture.

The Seven Root Causes (and One-Line Fixes)

Here’s what actually hides CTAs on mobile. Each cause maps to a specific class of device or browser behavior.

1. The 100vh Viewport Lie

Symptom: Sections sized with height: 100vh clip content when the mobile browser’s URL bar is visible. The CTA ends up below the fold, invisible until the user scrolls.

Why it happens: On mobile browsers, 100vh maps to the “largest possible viewport,” which is the height after the address bar hides. But the address bar is visible on page load, so your 100vh section is taller than what the user actually sees. Developers on Reddit’s r/Frontend have flagged this for years, calling it one of the most persistent mobile CSS frustrations.

One-line fix: Replace height: 100vh with min-height: 100dvh (dynamic viewport height), which adjusts as browser chrome shows and hides. Use a fallback for older browsers:

.hero {
  min-height: 100vh;    /* fallback */
  min-height: 100dvh;   /* modern browsers */
}

The dynamic viewport units (dvh, svh, lvh) were created specifically for this problem. Use svh (small viewport height) when you want the CTA to always be visible, even with the address bar showing.

2. Safe-Area Insets on Notched Phones

Symptom: Bottom-pinned CTAs sit under the iPhone home indicator or Android gesture bar, making them partially obscured or hard to tap.

Fix: Opt into full-bleed rendering and pad for safe areas. This requires two changes:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.cta-bar {
  padding-bottom: calc(env(safe-area-inset-bottom) + 12px);
}

Apple’s WebKit team documented this approach when the iPhone X introduced the notch. Without viewport-fit=cover, env(safe-area-inset-bottom) returns zero and does nothing.

Some developers report edge cases where env(safe-area-inset-bottom) returns 0 unexpectedly, particularly in PWA standalone mode on iOS 15 and newer. Always test on real hardware.

3. On-Screen Keyboard Covering CTAs

Symptom: User fills out a form on your checkout page, the keyboard appears, and the “Submit” or “Pay” button is completely hidden behind it.

This is the most discussed cause on UX forums. Practitioners on UX StackExchange describe the exact scenario: a long mobile form where the CTA at the bottom becomes unreachable once the keyboard opens.

The fix differs by platform:

Android/Chrome: Add interactive-widget=resizes-content to your viewport meta tag. This tells the browser to resize the layout when the keyboard opens, keeping your CTA in the visible area:

<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">

iOS/Safari: There’s no equivalent meta tag. Instead, use the Visual Viewport API to detect the keyboard and reposition your CTA. Practitioners on r/webdev consistently recommend this approach for iOS, since position: fixed elements behave unpredictably when the keyboard is open.

For checkout-specific form patterns that account for keyboard behavior, the ecommerce checkout optimization guide covers additional techniques.

4. Overlays Blocking CTAs (Cookie Banners, Chat Widgets)

Symptom: The CTA is technically visible, but tapping it does nothing because an invisible overlay or a chat widget is sitting on top of it.

This is more common than most teams realize. One developer shared on Reddit that their GDPR cookie banner was leaving an invisible backdrop that blocked their checkout CTA. Users couldn’t complete purchases, and the team only discovered it after customer complaints.

Cookie banners and modal backdrops often leave residual elements with pointer-events: auto even after being “dismissed.” Chat launchers (Drift, Intercom, and similar tools) frequently anchor to the bottom-right corner, directly over sticky CTA bars.

Fixes:

drift.config({ verticalOffset: 120, horizontalOffset: 16 });
  • For cookie banners, audit the DOM after dismissal. Check that no invisible backdrop remains. Set pointer-events: none on dismissed overlays and confirm z-index values don’t block underlying content.

  • Store offsets in your design system tokens (like --safe-bottom-offset) so they won’t regress when the vendor pushes updates.

5. Stacking Context and Z-Index Conflicts

Symptom: The CTA appears behind an image, video, or slider on some devices but not others.

This happens because CSS properties like transform, opacity, filter, and will-change create new stacking contexts. When a parent element forms its own stacking context, a child’s z-index: 9999 only applies within that context, not globally.

Fix: Inspect the CTA’s ancestor chain for any element creating an unintended stacking context. Either remove the offending property or move the CTA outside that context entirely.

6. Personalization and Targeting Rules

Symptom: The CTA shows for returning visitors but is missing on “fresh” devices with no cookies.

This isn’t a CSS bug at all. Platforms like HubSpot can hide CTAs based on targeting rules that require an identified contact or a specific cookie. On a new phone or in a private browser, the CTA simply never renders.

Fix: Check your CTA platform’s targeting settings before chasing layout bugs. Test in incognito mode across devices.

7. Text Scaling and Zoom

Symptom: Users with increased OS-level text size see the CTA pushed off-screen or wrapped into an untappable state.

iOS and Android both allow users to increase system text size. Rigid layouts break under this pressure, expanding vertical rhythm until the CTA lands under an overlay or below the viewport.

Fix: Design fluid layouts that accommodate text scaling. Ensure tap targets meet WCAG 2.2’s requirement of 24 by 24 CSS pixels minimum (or adequate spacing between targets). Test with your phone’s accessibility text size set to the largest option.

Quick Diagnosis: Five Tests in Ten Minutes

When a mobile CTA is hidden on some phones, run this triage in order. Each test isolates a different class of failure.

Test 1: Overlay and stacking check. In DevTools (connected to a real device via remote debugging), toggle visibility on chat widgets, cookie banners, and modal backdrops. Temporarily add pointer-events: none and z-index: 1 to suspected overlays. If the CTA becomes tappable, you found your culprit.

Test 2: Viewport unit check. Search your CSS for 100vh. If the CTA is inside a 100vh container, switch to 100dvh or 100svh with a vh fallback. Reload and check whether the CTA is visible with the browser’s address bar showing.

Test 3: Keyboard check. Open a form on your page and tap the last input field. On Android, adding interactive-widget=resizes-content to your viewport meta should push the CTA above the keyboard. On iOS, attach a resize listener to window.visualViewport and log visualViewport.height. If it drops when the keyboard appears but your CTA doesn’t move, that’s your fix path.

Test 4: Safe-area check. Add a temporary debug overlay to visualize safe-area insets:

:root::after {
  content: '';
  position: fixed;
  inset: auto 0 0 0;
  height: env(safe-area-inset-bottom);
  background: rgba(255, 0, 0, 0.25);
  pointer-events: none;
}

If your CTA sits in the red zone, add safe-area padding.

Test 5: Personalization check. Open your page in an incognito window on a device that has never visited. If the CTA is missing, review your CTA platform’s targeting rules.

Want to validate CTA visibility issues across your key pages without manual testing? Run a free Conversion Score audit to flag mobile CTA visibility and above-the-fold clarity problems in under two minutes, no script installation required.

Drop-In Code Patterns

Sticky Bottom CTA Bar (Safe-Area Aware, CSS Only)

Place the CTA as the last child inside your main scrolling container. Use position: sticky instead of fixed to avoid iOS quirks with fixed positioning during scroll:

.cta-bar {
  position: sticky;
  bottom: 0;
  z-index: 1000;
  padding: 12px 16px calc(env(safe-area-inset-bottom) + 12px);
  background: #fff;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

This pattern keeps the CTA pinned to the bottom of the viewport while respecting the home indicator on notched phones. Make sure your viewport meta includes viewport-fit=cover for the safe-area values to work.

Keyboard-Aware CTA for iOS Safari

This JavaScript listens to the Visual Viewport API and shifts the CTA upward when the keyboard reduces visible space:

const vv = window.visualViewport;
const bar = document.querySelector('.cta-bar');

function adjust() {
  const scale = vv.scale || 1;
  const keyboardOverlap = (window.innerHeight - vv.height) / scale;
  bar.style.transform = `translateY(-${Math.max(0, keyboardOverlap)}px)`;
}

vv.addEventListener('resize', adjust);
vv.addEventListener('scroll', adjust);
adjust();

Android: Let the Browser Handle It

For Chrome on Android, the simplest approach is telling the browser to resize the layout when the keyboard opens:

<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">

If you need finer control, set navigator.virtualKeyboard.overlaysContent = true and reposition elements manually using the geometrychange event. Chrome’s documentation on viewport resize behavior explains the tradeoffs.

Prevent 100vh Clipping

For any full-height section that contains a CTA:

.section {
  min-height: 100vh;    /* fallback for older browsers */
  min-height: 100dvh;   /* respects dynamic browser chrome */
}

Note: Firefox and some in-app browsers (Instagram, TikTok) have had inconsistent implementations of lvh and svh in older versions. Practitioners on r/webdev report testing across these browsers is essential before shipping.

Measuring Visibility and Impact

A mobile CTA hidden on some phones is fundamentally a measurement problem, not just a design problem. You need data to distinguish between “the CTA was never visible” (a visibility failure) and “the CTA was visible but nobody clicked it” (a persuasion failure). The fixes for each are completely different.

Use IntersectionObserver to track when the CTA enters the viewport:

const cta = document.querySelector('.primary-cta');
const obs = new IntersectionObserver(([entry]) => {
  if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
    // Fire analytics event: "CTA viewed"
  }
}, {
  threshold: [0, 0.5, 1],
  rootMargin: '0px 0px -80px 0px'  // subtract typical overlay height
});
obs.observe(cta);

The negative rootMargin at the bottom simulates a sticky overlay (chat widget, cookie banner) so the CTA only counts as “viewed” when it’s truly unobstructed.

Compare “CTA viewed” rates and “clicks from view” across device types and browsers. If iPhone users see the CTA 40% less often than Android users, you have a visibility bug. If they see it equally but click less, you have a messaging problem.

For teams that want to understand how AI-powered analysis compares to manual testing for catching these kinds of issues, the comparison of AI analysis versus traditional testing provides useful context.

Accessibility and Compliance Guardrails

Fixing a hidden CTA incorrectly can create accessibility violations. Keep these WCAG 2.2 requirements in mind.

Focus not obscured (2.4.12/2.4.13). Sticky bars and fixed banners must not fully cover focused elements. If a keyboard user tabs to a form field and your sticky CTA bar covers it, that’s a WCAG failure. Use scroll-padding-bottom on your scroll container to push focused elements above the bar.

Target size (2.5.8). Interactive elements need a minimum tap target of 24 by 24 CSS pixels, or adequate spacing between adjacent targets. Small CTA buttons become even harder to tap when the surrounding layout is compressed by overlays or text scaling.

Text inflation. iOS and Android can auto-increase text size based on user preferences. Prefer fluid layouts that accommodate this. If you use -webkit-text-size-adjust, do so carefully, because overriding user preferences is hostile to accessibility.

For a broader checklist of critical landing page elements including CTA sizing and placement, that guide covers the full picture.

QA Checklist Before You Ship

Run through this list on real devices before deploying any CTA-related changes. DevTools emulation is not sufficient for final verification.

  • [ ] iPhone with notch (any model with Face ID): Check safe-area padding, home indicator overlap.
  • [ ] Android flagship (Pixel or Samsung): Check gesture bar overlap, keyboard behavior.
  • [ ] Portrait and landscape on both platforms.
  • [ ] System text size set to largest on both iOS and Android.
  • [ ] Keyboard open on the last form field, verifying the CTA remains visible and tappable.
  • [ ] In-app browsers (Instagram, TikTok, Facebook) if your traffic comes from social.
  • [ ] PWA standalone mode if applicable (safe-area insets can behave differently).
  • [ ] Cookie banner and chat widget active, confirming neither blocks the CTA after dismissal.
  • [ ] Incognito/private mode to catch personalization-based CTA hiding.

For a structured approach to running through these checks, the UX audit tool provides a framework you can adapt to your workflow.

When to Use Sticky CTAs (and When Not To)

Sticky CTAs are the most common solution to a mobile CTA hidden on some phones, but they introduce their own tradeoffs. Practitioners on Reddit’s r/shopify_growth debate this actively, with some reporting conversion lifts and others finding that sticky bars feel cramped, cover product content, and annoy users on small screens.

The right approach:

  • Use sticky CTAs on long pages where the primary action would otherwise scroll out of view (product pages, long-form landing pages, multi-step forms).
  • Don’t use them on short pages where the CTA is already always visible.
  • Test both versions. Once your visibility bugs are fixed, use an A/B test planner to structure a proper experiment comparing sticky versus inline CTAs.
  • If you do go sticky, ensure the bar is thin enough not to obscure meaningful content. 60 pixels of height (plus safe-area padding) is usually the upper limit before users start feeling crowded.

Fix It Systematically

A mobile CTA hidden on some phones rarely has a single cause. Most production sites deal with a combination: the 100vh bug clips content for some users, a chat widget covers the button for others, and the keyboard hides it entirely during checkout. Fixing one without checking the others just shifts the problem.

The systematic approach is: diagnose with real devices, instrument visibility with IntersectionObserver, fix with the smallest cross-browser-safe CSS and JavaScript changes, and verify with your QA checklist. Then measure the impact on conversion rates to prove the fix worked.

If you want a fast way to catch mobile CTA visibility problems across your key pages, Conversion Score’s AI-powered audit flags above-the-fold and CTA issues without installing any scripts. For teams fixing these issues across multiple templates or client sites, the Pro plan offers unlimited audits, competitor analysis, and PDF reports to document improvements.

FAQ

Why does my CTA show on desktop but not on mobile?

The most common cause is a CSS rule using 100vh for section height, which miscalculates on mobile browsers where the address bar takes up space. Other causes include media queries that set display: none at mobile breakpoints, safe-area overlap on notched phones, or z-index conflicts that only manifest at smaller screen widths.

How do I fix a CTA hidden by the on-screen keyboard?

On Android with Chrome, add interactive-widget=resizes-content to your viewport meta tag. On iOS Safari, use the Visual Viewport API to detect the keyboard height and translate your CTA upward by that amount. The fix differs by platform because iOS and Android handle keyboard-layout interaction differently.

Does 100vh work correctly on mobile?

No. On most mobile browsers, 100vh equals the viewport height after the browser chrome (address bar, toolbar) is hidden. Since users see the page with chrome visible on load, 100vh sections are taller than the visible area. Use 100dvh (dynamic viewport height) with a 100vh fallback for older browsers.

Can cookie banners actually block CTA clicks?

Yes. This is a documented real-world failure mode. Cookie banner implementations sometimes leave invisible backdrop elements with active pointer-events even after the banner appears dismissed. Developers have reported this blocking checkout CTAs until customer complaints surfaced the issue.

What are safe-area insets and do I need them?

Safe-area insets are CSS environment variables (env(safe-area-inset-bottom), etc.) that tell you how much space is reserved for hardware features like the iPhone’s home indicator or a phone’s rounded corners. If your CTA is pinned to the bottom of the screen on any modern edge-to-edge phone, you need to add safe-area padding. This requires setting viewport-fit=cover in your viewport meta tag.

How can I tell if my CTA is actually visible to users?

Use the IntersectionObserver API to track when the CTA is at least 50% visible in the viewport. Compare “CTA viewed” rates across device types and browsers in your analytics. If one segment has significantly lower view rates, you likely have a device-specific visibility bug.

Should I use position fixed or sticky for mobile CTAs?

Prefer position: sticky for mobile CTAs. Fixed positioning on iOS has well-documented quirks during scrolling and when the keyboard is open, including the element jumping or becoming untappable. Sticky positioning avoids most of these issues while still keeping the CTA anchored at the bottom of the scrolling container.

Why does my CTA disappear only for new visitors?

This typically points to personalization or targeting rules in your CTA platform, not a CSS issue. Tools like HubSpot can hide CTAs for visitors who haven’t been identified via cookies. Test your page in incognito mode and review your CTA platform’s audience targeting settings before investigating layout bugs.

Read more guides on the CRO blog, run a free conversion audit on your own site, or see Pro plans for unlimited audits.