---
title: How to Fix AdMob Banner Overlap in a Capacitor App
description: Stop a Capacitor AdMob banner from covering your tab bar or content with resize mode or a CSS variable driven by the bannerSizeChanged event.
date:
  created: 2026-10-07
  updated: 2026-10-07
authors:
  - robingenz
categories:
  - Capacitor
  - Guides
  - Ionic Framework
  - SDKs
links:
  - Capacitor AdMob: sdks/capacitor/admob.md
faq: true
---

# How to Fix AdMob Banner Overlap in a Capacitor App

An AdMob banner hides your tab bar or the last item of a list because it is a native view drawn on top of the web view, and the web view has no idea how tall it is. When a Capacitor AdMob banner overlaps content, the [Capacitor AdMob plugin](../../sdks/capacitor/admob.md) gives you two fixes: let it shrink the web view with `mode: 'resize'`, or keep the default overlay and reserve space in CSS from the `bannerSizeChanged` event. This guide covers both, with the Ionic CSS for tab bars, content and floating action buttons, and what changes if you come from `@capacitor-community/admob`. The plugin is part of [Capawesome Insiders](../../insiders/index.md), a paid subscription.

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Ship a fix in one command with Capawesome Cloud Live Updates, no store review" src="https://capawesome.io/assets/banners/cloud-ship-a-fix-in-one-command.png" />
  </a>
</div>

**Key takeaways:**

- An AdMob banner is a native view above the Capacitor web view, so HTML and CSS never move out of its way on their own.
- `mode: 'resize'` in the Capacitor AdMob plugin shrinks the web view so a top or bottom banner never covers web content, with no CSS changes.
- In the default `overlay` mode, the `bannerSizeChanged` event reports the banner height in CSS pixels, ready to write into a CSS custom property.
- Ionic's `ion-tab-bar` already pads itself for the bottom safe area, so its margin should equal the banner height without adding `env(safe-area-inset-bottom)`.
- `@capacitor-community/admob` reports banner sizes in dp and points and offers a `margin` option; the Capacitor AdMob plugin uses CSS pixels and has no margin.

## Why the banner overlaps

The banner overlaps your content because the Google Mobile Ads SDK renders it as a native view that sits on top of the Capacitor web view. Your HTML is laid out as if the banner did not exist. In an Ionic app that usually means the `ion-tab-bar` disappears under a bottom banner, a floating action button ends up behind it, or the last row of a list can never be scrolled into view.

Developers have reported this for years against the community plugin. Issue [#2 "Ad overlapping tabs"](https://github.com/capacitor-community/admob/issues/2){:target="_blank"} from July 2020 describes a bottom banner covering Ionic tabs. Issue [#208 "Adding banner above the tabs"](https://github.com/capacitor-community/admob/issues/208){:target="_blank"} asks the same question in November 2022. Edge-to-edge layouts made it worse, as [#390 "Banner Ad Overlaps App's Navigation Bar and Margin Property Ignored on Android 15 & 16"](https://github.com/capacitor-community/admob/issues/390){:target="_blank"} from November 2025 shows.

A fixed `padding-bottom: 50px` does not fix it either, because the default adaptive banner has no fixed height. Google's [iOS banner guide](https://developers.google.com/admob/ios/banner){:target="_blank"} (last updated October 2, 2026) puts it like this:

> Anchored adaptive banners are always on-screen, anchored to the top or bottom of the screen with a maximum height of 20% of the screen size with a 150px max height

Google's Android guide describes the same 50 to 150 dp range for large anchored adaptive banners. The Capacitor AdMob plugin uses `BannerSize.AdaptiveBanner` as its default size and leaves the height to the SDK, so the only reliable number is the one the SDK reports after it picks a size. The [announcement post](./announcing-the-capacitor-admob-plugin.md) lists the three placement modes side by side; this guide goes through what each one means for your layout.

All banner calls below assume that consent is gathered and the SDK is initialized, which the [AdMob GDPR consent guide](./how-to-handle-admob-gdpr-consent-in-a-capacitor-app.md) covers. To install the Capacitor AdMob plugin, please refer to the [Installation](../../sdks/capacitor/admob.md/#installation) section in the plugin documentation.

## Resize the web view

Resize mode is the fix that needs no CSS at all. When you pass `mode: 'resize'` to [`showBanner(...)`](../../sdks/capacitor/admob.md#showbanner), the plugin shrinks the web view so that, in the README's words, "the banner ad never overlaps your web content". Your app keeps laying itself out in a full-height page; the page is a little shorter.

The mode works for a top banner as well as a bottom one. Here the banner sits above an Ionic header, and the identifier that `showBanner(...)` resolves with is kept for later calls:

```typescript
import { Admob, BannerSize } from '@capawesome-team/capacitor-admob';

let topBannerId: string | undefined;

const showTopBanner = async () => {
  const { id } = await Admob.showBanner({
    adUnitId: 'ca-app-pub-3940256099942544/6300978111',
    size: BannerSize.AdaptiveBanner,
    position: 'top',
    mode: 'resize',
  });
  topBannerId = id;
};
```

The ad unit above is Google's Android test banner; on iOS, use `ca-app-pub-3940256099942544/2934735716` during development. The stored `topBannerId` is what the hide, resume and remove methods take later.

Resize mode covers most apps with one anchored banner. It stops being the right tool in three cases. A banner placed inside scrolling content needs a frame instead, and the [`ShowBannerOptions`](../../sdks/capacitor/admob.md#showbanneroptions) reference states that `position` is ignored once a frame is set. Layouts that should continue behind the banner, such as a full-screen map or game canvas, need the overlay. And a shrinking web view changes the viewport height your CSS and your `resize` listeners see, which some layouts react to with a visible jump.

## Pad in overlay mode

Overlay mode is the default, and it leaves the web view at full size. The README describes the banner as "displayed on top of the web view, anchored to the top or bottom edge (safe-area aware)", so it stays clear of the home indicator and the gesture bar. Your CSS is responsible for keeping content out from under it.

The plugin tells you how much space to reserve through the [`bannerSizeChanged`](../../sdks/capacitor/admob.md#addlistenerbannersizechanged-) event. Its payload carries the banner `id` plus `width` and `height` in CSS pixels, so the value goes straight into a CSS custom property without any unit conversion. Register the listener once and before you call `showBanner(...)`, otherwise the first size event can arrive before anything is listening. The sample keeps the handle so that a second call to `showBottomBanner()` does not add a second handler.

```typescript
import type { PluginListenerHandle } from '@capacitor/core';
import { Admob, BannerSize } from '@capawesome-team/capacitor-admob';

const BANNER_ID = 'bottom-banner';
let bannerHeight = 0;
let sizeListener: PluginListenerHandle | undefined;

const setBannerInset = (height: number) => {
  document.documentElement.style.setProperty('--admob-banner-height', `${height}px`);
};

const addBannerSizeListener = async () => {
  if (sizeListener) {
    return;
  }
  sizeListener = await Admob.addListener('bannerSizeChanged', ({ id, height }) => {
    if (id !== BANNER_ID) {
      return;
    }
    bannerHeight = height;
    setBannerInset(height);
  });
};

const showBottomBanner = async () => {
  await addBannerSizeListener();
  await Admob.showBanner({
    id: BANNER_ID,
    adUnitId: 'ca-app-pub-3940256099942544/6300978111',
    size: BannerSize.AdaptiveBanner,
    position: 'bottom',
    mode: 'overlay',
  });
};
```

Passing your own `id` instead of using the generated one solves an ordering problem. The listener exists before `showBanner(...)` resolves, so it cannot compare against a returned identifier yet, but it can compare against a constant. The check also keeps a second banner, for example an inline one, from overwriting the bottom inset with its own height.

The property lives on `document.documentElement`, which is the `:root` element in CSS. Any component can read it with `var(--admob-banner-height, 0px)`, and the `0px` fallback keeps the layout correct on the web and before the first event, when the property is not set yet.

## Ionic layout specifics

In an Ionic app, the element that receives the banner height depends on what sits at the bottom of the page. With tabs, move the `ion-tab-bar` up by the banner height:

```css
ion-tab-bar {
  margin-bottom: var(--admob-banner-height, 0px);
}
```

Do not add `env(safe-area-inset-bottom)` or `--ion-safe-area-bottom` to that margin. Ionic's tab bar and footer already pad themselves for the bottom inset, and the overlay banner already sits above the inset, so adding it again gives you a tab bar that grows by the height of the gesture bar. The same applies to `ion-footer`. The [Ionic section of our edge-to-edge guide](./capacitor-edge-to-edge-and-safe-areas-guide.md#ionic-framework-specifics) explains which components handle the inset themselves.

Pages without a tab bar or a footer need the space inside `ion-content`. Its `--padding-bottom` property extends the scrollable area so the last item can scroll above the banner. A bottom `ion-fab` is positioned against `ion-content` itself rather than its scroll padding, so it needs its own margin:

```css
ion-content {
  --padding-bottom: var(--admob-banner-height, 0px);
}

ion-fab[vertical="bottom"] {
  margin-bottom: var(--admob-banner-height, 0px);
}
```

Scope these rules to the pages that show the banner, for example with a class on the page component, if other pages run without ads. On a tabbed page you do not need the content and FAB rules at all, because the raised tab bar already shortens the area above it. Whether the content padding is enough on a device with gesture navigation depends on how the reported height treats the bottom inset, which the FAQ below covers.

## Hide, resume, remove

The CSS variable has to follow the banner's visibility, because hiding a banner does not reset the space you reserved for it. [`hideBanner(...)`](../../sdks/capacitor/admob.md#hidebanner) keeps the ad loaded but invisible, and [`resumeBanner(...)`](../../sdks/capacitor/admob.md#resumebanner) shows it again. With `BANNER_ID`, `bannerHeight` and `setBannerInset` from the previous section, one function handles both directions:

```typescript
import { Admob } from '@capawesome-team/capacitor-admob';

const setBannerVisible = async (visible: boolean) => {
  if (visible) {
    await Admob.resumeBanner({ id: BANNER_ID });
    setBannerInset(bannerHeight);
  } else {
    await Admob.hideBanner({ id: BANNER_ID });
    setBannerInset(0);
  }
};
```

The function restores the last known height on resume instead of waiting for a new event, since the README does not say that resuming fires `bannerSizeChanged`. When a user buys your ad-free tier, call [`removeBanner(...)`](../../sdks/capacitor/admob.md#removebanner) to destroy the banner, set the inset to `0`, and call `remove()` on `sizeListener` before clearing it.

Collapsible banners need no extra code. With `collapsible: true`, the banner opens into a larger ad and collapses back, and the README names this as the example case for `bannerSizeChanged`. The listener above writes each new height to the CSS variable, so the tab bar or content padding follows the banner in both directions.

## Inline placement

An inline banner sits between your content instead of at a screen edge, and the plugin places it at a frame you measure in CSS pixels. Pass the rectangle of an anchor element from `getBoundingClientRect()` as `frame` together with `BannerSize.InlineAdaptiveBanner`, whose height is capped by the frame height. Because the banner is still a native view, it does not scroll with the page, so call [`setBannerFrame(...)`](../../sdks/capacitor/admob.md#setbannerframe) whenever the anchor moves, on scroll as well as on resize. The anchor element reserves the space in your layout, which makes this the one mode where overlap is a matter of sizing the anchor correctly. The announcement post shows the measuring code.

## Community plugin migration

`@capacitor-community/admob` is a maintained, MIT-licensed plugin, and its banner documentation gives the same advice as this guide: the banner is "drawn on the native screen above the WebView", and you pad your content from its `bannerAdSizeChanged` event. Before comparing, note the price difference. The community plugin is free, while the Capacitor AdMob plugin is available only to Capawesome Insiders, and its README still marks it as experimental.

| | `@capacitor-community/admob` | Capacitor AdMob plugin |
| --- | --- | --- |
| Avoiding overlap | Pad content from the size event, or offset with `margin` | `mode: 'resize'`, or pad content from the size event |
| Offset option | `margin` in dp (Android) or points (iOS) | None |
| Position values | `TOP_CENTER`, `CENTER`, `BOTTOM_CENTER` | `'top'`, `'bottom'`, or a `frame` |
| Size event | `bannerAdSizeChanged` with `{ width, height }` | `bannerSizeChanged` with `{ id, width, height }` |
| Units | dp (Android) and points (iOS) | CSS pixels |
| Banners at once | One | Several, each with its own `id` |
| Android SDK | Legacy Google Mobile Ads SDK 25.4.x | Next-Gen Google Mobile Ads SDK |
| License | MIT | Capawesome Insiders (paid) |

The unit difference is smaller in practice than the table suggests. Android defines one dp as roughly one pixel on a 160 dpi screen and scales it by [screen density](https://developer.android.com/training/multiscreen/screendensities){:target="_blank"}, and the WebView sets [`devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio){:target="_blank"} to that same density factor, so one CSS pixel covers about one dp. On iOS, one CSS pixel in WKWebView equals one point at the default zoom. That is why the community documentation can write the reported height straight into `paddingBottom` as pixels. The Capacitor AdMob plugin documents CSS pixels in its API, so your code does not rely on that mapping.

The `margin` workaround does not carry over. Community answers often set `margin` to the tab bar height so a `BOTTOM_CENTER` banner sits above the tabs, but that value is a fixed number of dp that ignores edge-to-edge insets, as issue #390 shows. Replace it with `mode: 'resize'` or with the `ion-tab-bar` rule from the Ionic section.

The SDK row matters for the long term. Google's [deprecation schedule](https://developers.google.com/admob/android/deprecation){:target="_blank"} gives the legacy Android SDK versions 24 and 25 a deprecation date of June 30, 2027, after which ads still serve but without technical support, and a sunset date of June 30, 2028, after which ads are "at risk of not serving". The Capacitor AdMob plugin runs on the Next-Gen SDK on Android.

## FAQ

### Why does my AdMob banner cover the bottom of my Ionic app?

Because the banner is a native view drawn on top of the Capacitor web view, and the web view does not know it is there, so your tab bar, footer or last list item stays underneath. Fix it by showing the banner with `mode: 'resize'` in the [Capacitor AdMob plugin](../../sdks/capacitor/admob.md), or by reserving the banner height in CSS from the `bannerSizeChanged` event.

### Should I use resize or overlay mode?

Use `mode: 'resize'` when you have one banner at the top or bottom and want no CSS changes. Use `overlay` when content should continue behind the banner, when the viewport height must stay constant, or when you already have a fixed footer that can absorb the banner height.

### Does the reported banner height include the safe-area inset?

The README does not specify it. It describes the overlay banner as safe-area aware and the `height` of `bannerSizeChanged` as the banner height in CSS pixels, but not whether the gesture bar or home indicator is part of that value. On the community plugin, issue [#304](https://github.com/capacitor-community/admob/issues/304){:target="_blank"} reports that the height did include the bottom inset. Test on a device with gesture navigation: log the event, then check that the last list item ends exactly at the top edge of the banner.

### What happens when a collapsible banner expands?

The plugin fires `bannerSizeChanged` with the new size when a collapsible banner expands or collapses. If your listener writes the height to a CSS variable, the tab bar or content padding follows the banner automatically.

### Is the Capacitor AdMob plugin free?

No. The Capacitor AdMob plugin is part of the [Capawesome Insiders](../../insiders/index.md) subscription. `@capacitor-community/admob` is a free, MIT-licensed alternative.

## Related posts

- [Announcing the Capacitor AdMob Plugin](./announcing-the-capacitor-admob-plugin.md)
- [How to Handle AdMob GDPR Consent (UMP) in a Capacitor App](./how-to-handle-admob-gdpr-consent-in-a-capacitor-app.md)
- [Capacitor Edge-to-Edge & Safe Areas: The Complete Guide](./capacitor-edge-to-edge-and-safe-areas-guide.md)

## Try Capawesome Cloud

Adding the Capacitor AdMob plugin to an app requires a new native build, while switching the banner mode or adjusting the CSS later is web code that a live update can ship without a store review. Capawesome Cloud handles both, and [How to Sign & Build Capacitor Apps in the Cloud](./how-to-sign-and-build-your-capacitor-app-in-the-cloud.md) walks through the native build side.

[Try Capawesome Cloud Free](https://capawesome.io){ .md-button .md-button--primary }

## Conclusion

Start with `mode: 'resize'` for a single top or bottom banner. Switch to overlay plus `bannerSizeChanged` when content has to continue behind the banner or the viewport height must stay constant, and to a `frame` when the banner belongs inside your content. Before you ship either, test on one device with gesture navigation and one with a notch, since the inset is where most remaining overlap comes from; the [Capacitor edge-to-edge and safe areas guide](./capacitor-edge-to-edge-and-safe-areas-guide.md) covers the CSS for that.

If you have any questions, join us on the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"}. To stay updated on the latest news, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"}.
