Skip to content

Mobile-First Footer — Complete Guide

DodaTech Updated 2026-06-28 10 min read

In this tutorial, you will learn about Mobile. We cover key concepts, practical examples, and best practices to help you master this topic.

Mobile-first footers use compact layouts, sticky bottom bars, collapsible sections, safe-area insets, and essential-only links for small screen navigation.

What You'll Learn

  • Compact footer layout
  • Sticky bottom navigation bar
  • Collapsible footer sections (accordion)
  • Safe area insets for notched devices
  • Essential link prioritization
  • Social links and branding
  • Accessibility for footer navigation

Why It Matters

  • Desktop-style footers overwhelm mobile users
  • Long footers push content above the fold
  • Small links are hard to tap
  • Missing safe area insets hide content behind notches

Real-World Use

  • An e-commerce footer with compact accordion sections
  • A news site with sticky bottom nav bar
  • A SaaS site footer with essential links only
  • A blog footer with social proof and newsletter signup
flowchart LR
  A[Mobile-First Footer] --> B[Compact Layout]
  A --> C[Sticky Bar]
  A --> D[Accordion]
  A --> E[Safe Areas]
  B --> F[Prioritized links]
  C --> G[Bottom navigation]
  D --> H[Collapsible sections]
  E --> I[env(safe-area-inset)]

Mobile footers should be compact, prioritizing the most important links and collapsing secondary content.

<footer class="mobile-footer">
    <div class="footer-brand">
        <div class="footer-logo">DodaTech</div>
        <p class="footer-tagline">Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.</p>
    </div>

    <div class="footer-links">
        <div class="footer-column">
            <h4 class="footer-heading">Product</h4>
            <ul class="footer-list">
                <li><a href="#">Features</a></li>
                <li><a href="#">Pricing</a></li>
                <li><a href="#">Changelog</a></li>
            </ul>
        </div>

        <div class="footer-column">
            <h4 class="footer-heading">Resources</h4>
            <ul class="footer-list">
                <li><a href="#">Documentation</a></li>
                <li><a href="#">Tutorials</a></li>
                <li><a href="#">API Reference</a></li>
            </ul>
        </div>

        <div class="footer-column">
            <h4 class="footer-heading">Company</h4>
            <ul class="footer-list">
                <li><a href="#">About</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </div>
    </div>

    <div class="footer-social">
        <a href="#" aria-label="GitHub">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
        </a>
        <a href="#" aria-label="Twitter">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>
        </a>
        <a href="#" aria-label="LinkedIn">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
        </a>
    </div>

    <div class="footer-bottom">
        <p>&copy; 2026 DodaTech. All rights reserved.</p>
        <div class="footer-legal">
            <a href="#">Privacy Policy</a>
            <a href="#">Terms of Service</a>
        </div>
    </div>
</footer>

<style>
.mobile-footer {
    background: #1f2937;
    color: #d1d5db;
    padding: 2rem 1rem 1rem;
    font-size: 0.875rem;
}

.footer-brand {
    margin-bottom: 1.5rem;
}

.footer-logo {
    font-size: 1.25rem;
    font-weight: 700;
    color: #fff;
    margin-bottom: 0.5rem;
}

.footer-tagline {
    font-size: 0.8125rem;
    color: #9ca3af;
    line-height: 1.5;
    max-width: 300px;
}

.footer-links {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

.footer-heading {
    font-size: 0.8125rem;
    font-weight: 600;
    color: #fff;
    margin: 0 0 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.footer-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-list li {
    margin-bottom: 0.5rem;
}

.footer-list a {
    color: #9ca3af;
    text-decoration: none;
    font-size: 0.875rem;
    padding: 0.25rem 0;
    display: inline-block;
    min-height: 44px;
    line-height: 44px;
}

.footer-list a:active {
    color: #fff;
}

.footer-social {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.footer-social a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: #9ca3af;
    border-radius: 8px;
    transition: color 0.2s, background 0.2s;
}

.footer-social a:active {
    color: #fff;
    background: #374151;
}

.footer-bottom {
    border-top: 1px solid #374151;
    padding-top: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: #6b7280;
}

.footer-legal {
    display: flex;
    gap: 1rem;
}

.footer-legal a {
    color: #6b7280;
    text-decoration: none;
}

.footer-legal a:active {
    color: #9ca3af;
}

@media (min-width: 768px) {
    .mobile-footer {
        padding: 3rem 2rem 1.5rem;
    }

    .footer-links {
        grid-template-columns: repeat(3, 1fr);
    }

    .footer-bottom {
        flex-direction: row;
        justify-content: space-between;
    }
}
</style>

Expected output: A compact footer with 2-column link grid on mobile and 3-column on desktop. All links have 44px tap targets. Social icons are adequately sized and spaced. Legal links are compact at the bottom.

Sticky Bottom Navigation Bar

Many mobile apps use a persistent bottom navigation bar instead of a traditional footer.

Code Example: Bottom Navigation Bar

<nav class="bottom-nav" aria-label="Main navigation">
    <a href="#" class="nav-item active" aria-current="page">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
        </svg>
        <span>Home</span>
    </a>
    <a href="#" class="nav-item">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4zM16 10a4 4 0 01-8 0"/>
        </svg>
        <span>Shop</span>
    </a>
    <a href="#" class="nav-item">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
        </svg>
        <span>Wishlist</span>
        <span class="nav-badge">3</span>
    </a>
    <a href="#" class="nav-item">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
        </svg>
        <span>Profile</span>
    </a>
</nav>

<style>
.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    background: #fff;
    border-top: 1px solid #e5e7eb;
    z-index: 100;
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 0.5rem 0;
    color: #9ca3af;
    text-decoration: none;
    font-size: 0.6875rem;
    font-weight: 500;
    min-height: 56px;
    position: relative;
    transition: color 0.2s;
    -webkit-tap-highlight-color: transparent;
}

.nav-item:active {
    color: #3b82f6;
}

.nav-item.active {
    color: #3b82f6;
}

.nav-item svg {
    display: block;
}

.nav-badge {
    position: absolute;
    top: 4px;
    right: 50%;
    margin-right: -20px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    font-size: 0.625rem;
    font-weight: 700;
    color: #fff;
    background: #ef4444;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
}
</style>

Expected output: A fixed bottom navigation bar with four tabs. The active tab is highlighted in blue. The Wishlist tab shows a badge count. The bar has safe-area-inset-bottom padding for notched devices.

Collapsible accordion sections keep the footer compact while preserving all links.

<footer class="accordion-footer">
    <div class="accordion-section">
        <button class="accordion-trigger" aria-expanded="false">
            Product
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M6 9l6 6 6-6"/>
            </svg>
        </button>
        <div class="accordion-content" hidden>
            <ul class="accordion-list">
                <li><a href="#">Features</a></li>
                <li><a href="#">Pricing</a></li>
                <li><a href="#">Integrations</a></li>
                <li><a href="#">Changelog</a></li>
            </ul>
        </div>
    </div>

    <div class="accordion-section">
        <button class="accordion-trigger" aria-expanded="false">
            Resources
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M6 9l6 6 6-6"/>
            </svg>
        </button>
        <div class="accordion-content" hidden>
            <ul class="accordion-list">
                <li><a href="#">Documentation</a></li>
                <li><a href="#">Tutorials</a></li>
                <li><a href="#">API Reference</a></li>
                <li><a href="#">Community</a></li>
            </ul>
        </div>
    </div>

    <div class="accordion-section">
        <button class="accordion-trigger" aria-expanded="false">
            Company
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M6 9l6 6 6-6"/>
            </svg>
        </button>
        <div class="accordion-content" hidden>
            <ul class="accordion-list">
                <li><a href="#">About</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">Careers</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </div>
    </div>
</footer>

<script>
document.querySelectorAll('.accordion-trigger').forEach(trigger => {
    trigger.addEventListener('click', function() {
        const expanded = this.getAttribute('aria-expanded') === 'true';
        this.setAttribute('aria-expanded', !expanded);
        const content = this.nextElementSibling;
        content.hidden = expanded;
    });
});
</script>

<style>
.accordion-footer {
    background: #1f2937;
    padding: 0 1rem;
    max-width: 480px;
}

.accordion-section {
    border-bottom: 1px solid #374151;
}

.accordion-trigger {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 0;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #fff;
    background: transparent;
    border: none;
    cursor: pointer;
    min-height: 48px;
    -webkit-tap-highlight-color: transparent;
}

.accordion-trigger svg {
    transition: transform 0.2s ease;
}

.accordion-trigger[aria-expanded="true"] svg {
    transform: rotate(180deg);
}

.accordion-content {
    padding-bottom: 0.75rem;
}

.accordion-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.accordion-list li {
    margin-bottom: 0.375rem;
}

.accordion-list a {
    color: #9ca3af;
    text-decoration: none;
    font-size: 0.875rem;
    padding: 0.5rem 0;
    display: block;
    min-height: 44px;
    line-height: 44px;
}

.accordion-list a:active {
    color: #fff;
}
</style>

Expected output: The footer shows collapsible sections. Tapping a header reveals the links below with a rotating chevron animation. Only one section needs to be open at a time. All links have 44px minimum tap targets.

Common Mistakes

  1. Desktop-style 4-column footer on mobile — Links become tiny and unreadable. Stack columns vertically or use 2-column grid.
  2. No safe area inset padding — On notched devices, the footer content hides behind the home indicator.
  3. Footer too long — A footer that takes half the screen pushes the main content above the fold. Use accordion sections.
  4. Tiny tap targets on links — Footer links smaller than 44px are hard to tap after scrolling.
  5. No sticky bottom nav — Users must scroll back to the top to navigate, causing unnecessary friction.
  6. Footer before the content — The footer should be at the bottom, not above the fold pushing content down.
  7. No dark background — Footers with light background on mobile create visual noise. Dark backgrounds separate the footer from content.

Practice Questions

  1. What CSS function provides safe area padding for notched devices? env(safe-area-inset-bottom) adds padding for the home indicator area on iPhones and similar devices.
  2. Why should mobile footers use accordion sections? Accordion sections keep the footer compact while preserving access to all links. Users expand only what they need.
  3. What is the purpose of a sticky bottom navigation bar? It provides persistent access to primary navigation without scrolling, reducing friction for one-handed use.
  4. How many links should a mobile footer show by default? 6-8 essential links. Secondary links go in accordion sections available on tap.
  5. What aria attribute indicates an accordion section is open? aria-expanded="true" on the trigger button. The content panel uses hidden attribute when collapsed.

Challenge

Build a complete footer system for an e-commerce site. Include: (1) a sticky bottom navigation bar with 5 tabs (Home, Search, Categories, Cart with badge, Profile), (2) a compact footer below with brand, tagline, and 4 accordion sections (Shop, Customer Service, About, Legal), (3) social media links with 44x44px icons, (4) a newsletter signup form with email input and submit button, (5) safe area insets on both the bottom nav and footer, (6) a back-to-top button that appears when scrolling down, (7) proper heading hierarchy for accessibility.

FAQ

Should I use a sticky bottom nav or a traditional footer?

Use a sticky bottom nav for app-like experiences where primary navigation is needed on every page (shop, social, dashboard). Use a traditional footer for content sites (blogs, documentation, landing pages).

How do I handle the bottom nav on desktop?

On desktop (768px+), move the navigation to a sidebar or top nav. The bottom nav pattern is mobile-specific and looks out of place on wide screens.

What is safe-area-inset-bottom and how do I use it?

It is a CSS environment variable that returns the height of the home indicator area on notched devices. Use it as padding-bottom on fixed bottom elements: padding-bottom: env(safe-area-inset-bottom, 0px).

How many accordion sections should a mobile footer have?

3-5 sections. More than 5 makes the footer too tall when all sections are expanded. Prioritize the most important link categories.

Should the footer have a different background color?

Yes. A dark background (dark gray or black) visually separates the footer from the content and creates a clear end-of-page indicator. Use high-contrast text colors for readability.

Mini Project

Build a footer for a SaaS product landing page. Include: (1) sticky bottom nav with Home, Features, Pricing, Docs, and Account tabs (active state, badges, safe area padding), (2) an expandable footer with brand section, 3 accordion groups (Product, Resources, Company), social icons (GitHub, Twitter, LinkedIn), (3) a newsletter signup form with email validation, (4) a back-to-top button (FAB style) that appears after scrolling 300px, (5) legal links row with privacy policy and terms, (6) copyright line with the DodaTech brand context, (7) responsive adaptation showing a top nav on desktop instead of bottom nav.

What's Next

Continue with Lesson 14: Mobile-First Header to design headers optimized for mobile navigation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro