Skip to main content

What is non-mobile design?

App stores expect apps to look and feel like apps Reviewers can instantly tell when an app is just a website wrapped in a native container. The layout, navigation patterns, and interaction design all signal “website” instead of “app.” Common rejection messages:
  • “Your app appears to be a repackaged website”
  • “The app does not provide a native user experience”
  • “This would be better suited as a mobile website”
This rejection is about visual and interaction design, not functionality.

Why this happens

Web layouts don’t translate to mobile apps Desktop and responsive web design patterns look wrong on mobile apps. Reviewers see these patterns and immediately flag the submission. Common mistakes:
  • Sidebars or slide-out drawer menus
  • Top navigation bars with multiple links
  • Hamburger menus in the header
  • Desktop-style footers with link columns
  • Scrolling headers that hide on scroll
  • Browser-specific elements like cookie banners
These work fine on websites. They fail App Store review.

How to fix it

Understand the mobile app layout pattern

Native apps follow a consistent structure Every successful mobile app uses the same basic layout. Reviewers expect to see this pattern. What reviewers expect:
  • Fixed (but CSS realtive) top bar showing current page title (optional back button)
  • Scrollable content area in the middle
  • Fixed (but CSS realtive) bottom navigation bar with icons for main sections
  • No sidebars
  • No hamburger menus
  • No desktop-style navigation

Foundation architecture

Applications require a root frame element that establishes viewport boundaries
<head>
  <meta 
    name="viewport" 
    content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no"
  >
</head>

<body>
  <div class="app-root">
    <div class="safe-area-top"></div>
    
    <header class="app-header">
      <!-- Fixed header with page title -->
    </header>
    
    <main class="app-content">
      <!-- Scrollable content -->
    </main>
    
    <footer class="app-footer">
      <!-- Fixed bottom navigation -->
    </footer>
    
    <div class="safe-area-bottom"></div>
  </div>
</body>
CSS implementation:
/* Root frame - establishes viewport boundaries */
.app-root {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Safe area frames - handle device boundaries */
.safe-area-top {
  flex-shrink: 0;
  height: var(--safe-area-top, env(safe-area-inset-top, 0));
}

.safe-area-bottom {
  flex-shrink: 0;
  height: var(--safe-area-bottom, env(safe-area-inset-bottom, 0));
}

/* Header frame - fixed positioning */
.app-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  height: 56px;
  padding: 0 1rem;
  border-bottom: 1px solid #e5e7eb;
}

/* Content frame - scrollable container */
.app-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  
  /* Hide scrollbar for native appearance */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.app-content::-webkit-scrollbar {
  display: none;
}

/* Footer frame - fixed positioning */
.app-footer {
  flex-shrink: 0;
  border-top: 1px solid #e5e7eb;
}
Key requirements:
  • Use position: fixed for root frame (do not use height: 100vh)
  • Include dedicated safe area spacer elements
  • Header and footer use flex-shrink: 0 (non-scrolling)
  • Content area uses flex: 1 and overflow-y: auto (scrollable)
  • Apply scrollbar-width: none for native appearance
See: Safe Areas

Device boundaries

Safe area variables The Despia runtime automatically injects CSS variables for device-specific boundary insets (notches, status bars, home indicators).
.element {
  padding-top: var(--safe-area-top);
  padding-bottom: var(--safe-area-bottom);
}
PWA fallback implementation When deployed as a PWA, Despia-specific variables are unavailable. Implement fallback values using standard environment variables.
.element {
  /* Despia variable → standard env() → default value */
  padding-top: var(--safe-area-top, env(safe-area-inset-top, 0));
  padding-bottom: var(--safe-area-bottom, env(safe-area-inset-bottom, 0));
}

Header design

Keep it simple and consistent Mobile app headers are minimal. They show the current page and maybe a back button.
<header class="app-header">
  <button class="back-button" onclick="history.back()">
    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <path d="M15 18l-6-6 6-6"/>
    </svg>
  </button>
  <h1 class="page-title">Settings</h1>
  <div class="header-spacer"></div>
</header>
.app-header {
  display: flex;
  align-items: center;
  height: 56px;
  padding: 0 8px;
}

.back-button {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: #2563eb;
}

.page-title {
  flex: 1;
  font-size: 17px;
  font-weight: 600;
  text-align: center;
}

.header-spacer {
  width: 44px;
}
What to avoid in headers:
  • Multiple navigation links
  • Dropdown menus
  • Search bars that span the full width
  • Logo images
  • Hamburger menu icons

Bottom navigation

This is the primary navigation pattern for mobile apps Bottom navigation is the standard. Users expect it. Reviewers expect it.
<footer class="app-footer">
  <nav class="bottom-nav">
    <button class="nav-item active">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
        <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
      </svg>
      <span>Home</span>
    </button>
    <button class="nav-item">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
      </svg>
      <span>Search</span>
    </button>
    <button class="nav-item">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M12 5v14M5 12h14"/>
      </svg>
      <span>Create</span>
    </button>
    <button class="nav-item">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
        <path d="M13.73 21a2 2 0 0 1-3.46 0"/>
      </svg>
      <span>Alerts</span>
    </button>
    <button class="nav-item">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
        <circle cx="12" cy="7" r="4"/>
      </svg>
      <span>Profile</span>
    </button>
  </nav>
</footer>
.bottom-nav {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 56px;
  background: #ffffff;
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 64px;
  padding: 8px 0;
  color: #6b7280;
  background: none;
  border: none;
  cursor: pointer;
}

.nav-item.active {
  color: #2563eb;
}

.nav-item span {
  font-size: 10px;
  font-weight: 500;
}
Bottom navigation guidelines:
  • Keep to 3-5 items maximum
  • Highlight current tab with color or fill change
  • Labels are optional but improve usability
  • Use consistent icon style (all outline or all filled)
  • Icons should be 24x24px
  • Tap targets should be at least 44x44px

What to remove

These elements signal “website” to reviewers Delete or replace these patterns: Sidebars Sidebars don’t exist in native mobile apps. Move navigation to the bottom bar or into separate screens. Hamburger menus The three-line menu icon is a web pattern. Replace with bottom navigation for primary actions. Use a settings screen for secondary options. Top navigation bars with links Website-style navigation like “Home | About | Contact | Login” doesn’t belong. Use bottom navigation instead. Desktop footers Multi-column footers with links, social icons, and legal text are for websites. Remove entirely or move essential links to a settings screen. Cookie banners These are web-specific. Remove them from the native app using user agent detection. Browser chrome elements Address bars, back/forward buttons, refresh icons. These should never appear in your app.

Common layout mistakes

Side-by-side comparison
Website patternMobile app pattern
Hamburger menuBottom navigation
Top nav linksTab bar at bottom
Sidebar drawerSeparate screens
Desktop footerSettings screen
Scrolling headerFixed header
Full-width searchSearch icon in nav

Testing your layout

Before submitting, verify these points:
  1. Is the header fixed at the top?
  2. Is the navigation at the bottom?
  3. Does only the content area scroll?
  4. Are safe areas handled for notches?
  5. Is the scrollbar hidden?
  6. Are there any sidebars visible?
  7. Are there any hamburger menus?
  8. Does the layout feel like Instagram, Twitter, or other native apps?

Quick checklist

Layout structure:
  1. Root frame uses position: fixed
  2. Viewport meta tag includes viewport-fit=cover
  3. Safe area spacers are present
  4. Header is fixed with flex-shrink: 0
  5. Content area uses flex: 1 and overflow-y: auto
  6. Footer is fixed with flex-shrink: 0
Navigation:
  1. Bottom navigation with 3-5 items
  2. No sidebars
  3. No hamburger menus
  4. No top navigation links
Polish:
  1. Scrollbar is hidden
  2. Icons are consistent (outline or filled)
  3. Active state is visible on current tab
  4. Tap targets are at least 44x44px

Still stuck?

If you keep getting rejected for design issues:
  1. Open Instagram, Twitter, or Spotify on your phone. Compare their layout to yours.
  2. Screenshot your app and ask: “Does this look like a website or an app?”
  3. Contact support: support@despia.com with:
    • Screenshots of your current layout
    • Your rejection notice
    • Description of navigation patterns you’re using