2026, Jan 05 05:00

Make Leafmap Truly Full-Page in Streamlit: eliminate top/bottom gaps with app.html and 100vh iframe

Make a Leafmap fill the Streamlit page without top or bottom gaps: use app.html and set the iframe to height 100vh and display block for edge-to-edge results.

How to make a leafmap fill the entire Streamlit page without mysterious top or bottom gaps? If you tried bumping the height and ended up with a Y offset or stubborn margins, you’re running into the way Streamlit renders HTML and iframes around embedded maps. Below is a concise walkthrough of why it happens and how to fix it cleanly, with a code sample you can drop into your app.

Reproducing the issue

The following example sets a wide layout and injects CSS via markdown, yet the map still leaves space above and below. Increasing the map’s height only introduces scroll/offset behavior, not a true full-bleed view.

import streamlit as app
import leafmap.foliumap as geo
app.set_page_config(
    page_title=None,
    page_icon=None,
    layout="wide",
    initial_sidebar_state="auto",
)
app.markdown(
    """
    <style>
        header {visibility: hidden;}
        footer {visibility: hidden;}
        .block-container {
            padding: 0 !important;
            margin: 0 !important;
            max-width: 100% !important;
            width: 100% !important;
        }
        .main {
            padding: 0 !important;
            margin: 0 !important;
        }
        .css-1aumxhk {
            margin-top: 0 !important;
        }
    </style>
    """,
    unsafe_allow_html=True,
)
viewer = geo.Map(center=[-0.1807, -78.4678], zoom=7)
viewer.to_streamlit(height=830)

What’s really going on

The top margin comes from using app.markdown() to inject HTML. Streamlit wraps that content in its own container, which adds spacing above the map. Switching the injection method removes that container and the extra gap. The bottom gap is not solved by setting a fixed pixel height for the map; the embedded map is inside an iframe, and that iframe needs to be told to consume the full viewport height to avoid leftover space. There’s also a small residual gap typical for inline elements; the iframe should be rendered as a block-level element to eliminate it.

One more practical note: app.html() (introduced in Streamlit 1.33.0) handles raw HTML injection without the additional markdown wrapper, which directly addresses the top margin.

The fix

Use app.html() instead of app.markdown() to inject the style block, and target the iframe with height: 100vh and display: block. Remove the explicit height on the map so the iframe can take over full-page sizing.

import streamlit as app
import leafmap.foliumap as geo
print('Streamlit version:', app.__version__)
app.set_page_config(
    page_title=None,
    page_icon=None,
    layout="wide",
    initial_sidebar_state="auto",
)
app.html(
    """
    <style>
        header {visibility: hidden;}
        footer {visibility: hidden;}
        .block-container {
            padding: 0 !important;
            margin: 0 !important;
            max-width: 100% !important;
            width: 100% !important;
        }
        .main {
            padding: 0 !important;
            margin: 0 !important;
        }
        .css-1aumxhk {
            margin-top: 0 !important;
        }
        iframe {
            height: 100vh;
            display: block;
        }
    </style>
    """
)
fullmap = geo.Map(center=[-0.1807, -78.4678], zoom=7)
fullmap.to_streamlit()

Why this matters

Map-first interfaces—dashboards, kiosks, monitoring screens—often require a full-bleed view without scrollbars or accidental padding. Relying on fixed pixel heights or ad‑hoc tweaks leads to offsets and layout drift across devices. Treating the map as a full-viewport iframe consistently yields a stable, edge-to-edge canvas.

Notes and practical observations

If you must stick with markdown for any reason, placing the CSS injection after the map can also remove the top margin. Inspecting the rendered page in DevTools helps pinpoint spacing by revealing which container introduces the gap; for example, elements with gap: 1rem can be set to gap: 0 if necessary. However, the most straightforward approach is to avoid the markdown wrapper altogether and style the iframe directly.

Takeaways

To make a leafmap occupy all available space in Streamlit without margins, inject CSS using app.html(), give the underlying iframe height: 100vh, and render it as a block-level element. Skip hardcoded pixel heights on the map itself to prevent scroll and offsets. If you’re following older tutorials, note that app.html() is available starting from Streamlit 1.33.0, and using it sidesteps the extra container that causes the top margin.