Mobiles (WordPress-)Menü: Ohne JS mit Popover-API und Anchor Positioning

Verfasst von

in

,

Seit Anfang 2026 ist Anchor Positioning in allen großen Browsern verfügbar. In Kombination mit der Popover API lässt sich damit unter anderem ein barrierefreies mobiles Menü extrem easy und komplett ohne JavaScript bauen.

In Oxygen habe ich dafür das PHP-Code-Element genutzt. Zuerst erstellen wir den Button, der das Menü aufruft. Über das Attribut popovertarget verweisen wir auf die ID unseres Menü-Containers. Der Container selbst erhält das Attribut popover, damit der Browser ihn als solchen erkennt:

<button id="menu-button" popovertarget="mobile-menu"> 
    🍔 Menü 
</button>
<nav id="mobile-menu" popover>
    <?php wp_nav_menu( array( 'menu' => 'header' ) ); ?>
</nav>

(Hinweis: ‚menu‘ => ‚header‘ verweist auf mein WordPress-Menü mit dem Namen „header“.)

Ab hier funktioniert die Logik bereits! Damit das Menü aber exakt unter dem Button erscheint, nutzen wir das neue CSS Anchor Positioning. Zuerst definieren wir den Button als Anker und binden das Menü anschließend mit position-anchor daran. Über position-area legen wir fest, dass es unter dem Button erscheinen soll:

#menu-button {
    anchor-name: --menu-button;
}

#mobile-menu {
    position: absolute;
    position-anchor: --menu-button;
    position-area: bottom;
}

Zum Schluss noch ein bisschen Styling:

#menu-button {
    anchor-name: --menu-button;
    cursor: pointer;
    width: 13rem;
    padding: 0.5rem 2rem;
    background: #F9F9F9;
    border: 1px solid #2c3e50;
    font-family: var(--bde-heading-font-family);
    font-size: 1.2rem;
    font-weight: 700;
    color: #2c3e50;
}

#mobile-menu {
    position: absolute;
    position-anchor: --menu-button;
    position-area: bottom;
    width: 13rem;
    padding: 0;
    background: #F9F9F9;
    border: none;
    font-family: var(--bde-heading-font-family);
    font-size: 1.2rem;
    font-weight: 700;
    color: #2c3e50;
    ul {
        padding: 0 2rem;
        list-style: none; 
    }
    li {
        margin: 1rem 0;
    }
    a {
        text-decoration: none;
        color: #000;
        &:hover {
            text-decoration: underline;
        }
    }
}

Und das war es auch schon! Ein performantes, natives Menü ohne eine einzige Zeile JavaScript.