L'overlay du menu bloque les clics sur Firefox - le cas La Rosée

Le

Par Thomas Simonet

Marque : La Rosée Cosmétiques

Cette analyse est indépendante et ne résulte d'aucune collaboration avec la marque mentionnée. Elle repose uniquement sur une observation externe réalisée le . Je n'ai accès ni au code et ni aux données. Le problème peut être ponctuel ou propre à ma configuration.

Si le bug est critique, l'équipe a été contactée avant publication.

La criticité de ce problème est prioritaire (À fixer dans l'heure) et a été reporté le

Contexte

L'utilisateur arrive sur la homepage et navigue sur une page catégorie et ne parvient pas à cliquer sur les boutons pour visualiser un produit qui l'intéresse.

L'utilisateur quitte le site et ne reviendra probablement jamais.

Reproduction du problème

La vidéo a été enregistrée le 14/09/2026 avec cap.so.

J'utilise le navigateur Firefox 155.0.1.

Le bug ne touche ni Google Chrome ni les autres navigateurs sous le moteur de rendu Blink.

Impact potentiel

Il est possible que les utilisateurs de Firefox ne puissent pas utiliser correctement le site.

À la rédaction de cet article, Firefox est utilisé par 7,35 % des utilisateurs en France (Source StatCounter).

La cause

[data-state=closed]:is(._nav-menu-viewport_1uy2l_90,._search-content_1uy2l_91)+._overlay_1uy2l_102 {
    animation: .2s linear forwards _fade-out_1uy2l_1;
}

:is(._nav-menu-viewport_1uy2l_90,._search-content_1uy2l_91)+._overlay_1uy2l_102 {
    inset-inline: 0;
    content: "";
    background-color: #000;
    height: 100vmax;
    -webkit-backdrop-filter: blur(5px);
    backdrop-filter: blur(5px);
    position: absolute;
    top: 100%;
}

@keyframes _fade-out_1uy2l_1 {
    0% {
        opacity: 1;
        display: block;
    }

    100% {
        opacity: 0;
        display: none;
    }    
}

L'overlay est ajouté au DOM à l'ouverture du menu, mais est caché par l'animation "_fade-out_1uy2l_1" qui applique un "display: none;" et une "opacity: 0;" après l'exécution de l'animation (voir animation-fill-mode et la valeur forwards).

Firefox ne prend pas en compte le "display: none" dans l'animation :

document.querySelector('._overlay_1uy2l_102').checkVisibility() // True sur Firefox
document.querySelector('._overlay_1uy2l_102').checkVisibility() // False sur Google Chrome

Mais pourquoi ? Firefox ne supporte pas encore les animations sur la propriété "display". Voir le tableau de compatibilité sur caniuse

Le fix

Dans ce cas précis, le fix le plus simple et rapide à déployer consiste à ajouter une propriété css :

:is(._nav-menu-viewport_1uy2l_90,._search-content_1uy2l_91)+._overlay_1uy2l_102 {
    /* Plus les autres propriétés */ 
    pointer-events: none;
}

Un autre fix cross-browser plus robuste consiste à utiliser les propriétés "transition-behavior: allow-discrete" et "@starting-style".

Comment éviter ce type de problème

  • Mettre en place des tests E2E (avec Playwright par exemple) ;
  • Créer des tableaux de bord segmentés par navigateur. (dans ce cas précis, le taux de conversion sur Firefox doit être inférieur aux autres) ;
  • Analyser les sessions replay des abandons (via Datadog par exemple) ;
  • Faire auditer son site e-commerce par Panier Percé.

Reproduire le bug en local

Fichier HTML

<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        *,
        *:before,
        *:after {
            box-sizing: border-box;
        }

        body {
            min-height: 100vh;
            background: #fff;
        }

        header {
            position: sticky;
            top: 0;
        }

        nav {
            width: 100%;
            height: 50px;
        }

        #overlay {
            inset-inline: 0;
            content: "";
            background-color: #000;
            height: 50vh;
            -webkit-backdrop-filter: blur(5px);
            backdrop-filter: blur(5px);
            position: absolute;
            top: 100%;
            animation: .2s linear forwards fade-out;
            pointer-events: auto;
        }

        @keyframes fade-out {
            0% {
                opacity: 1;
                display: block;
            }

            100% {
                opacity: 0;
                display: none;
            }    
        }
    </style>
</head>
<body>
    <header>
        <nav id="nav">
            <button id="open_menu">Menu</button>
        </nav>
    </header>
    <main>
        <article>
            <button id="add_to_cart" type="submit">Ajouter au panier</button>
        </article>
    </main>

    <script>
    const menuBtn = document.getElementById("open_menu")
    let overlay_created = false

    menuBtn.addEventListener("click", () => {
        if (!overlay_created) {
            overlay = document.createElement("div")
            overlay.id = "overlay"
            document.getElementById("nav").appendChild(overlay)         
            overlay_created = true   
        }
    })
    </script>
</body>
</html>

Ce fichier permet de recréer la structure de base pour reproduire le bug. L'overlay est inséré dans le DOM après un clic sur le bouton #open_menu avec quelques lignes de JavaScript comme sur le site.

Le test playwright

from playwright.sync_api import sync_playwright, expect

# test
URL = "http://localhost:8000/"
MENU_SELECTOR = "[id*='open_menu']"
ADD_TO_CART_SELECTOR = "[id*='add_to_cart']"
OVERLAY_SELECTOR = "[id*='overlay']"

def run(playwright):
    browser = playwright.firefox.launch(headless=False) # Firefox version 155.0
    page = browser.new_context(
        viewport={"width": 2560, "height": 1440},
        device_scale_factor=1.25
    ).new_page()

    try:
        page.goto(URL, wait_until="domcontentloaded") #1

        menu = page.locator(MENU_SELECTOR).first #2
        menu.wait_for(state="visible", timeout=5000)
        menu.click()

        expect(page.locator(OVERLAY_SELECTOR)).to_be_attached() #3

        add = page.locator(ADD_TO_CART_SELECTOR).first #4
        add.wait_for(state="visible", timeout=5000)
        add.click()

        print("✅ Test réussi")
        return True

    except Exception as e:
        print(f"❌ Test échoué : {e}")
        return False

    finally:
        browser.close()

if __name__ == "__main__":
    with sync_playwright() as playwright:
        run(playwright)

Les étapes :

  1. Charge http://localhost:8000/
  2. Clic sur le bouton "menu"
  3. Vérifie que l'overlay a bien été ajouté
  4. Clic sur le bouton "ajouter au panier"

Lancer le test

python -m http.server 8000
uv run test.py

Résultat du test

❌ Test échoué : Locator.click: Timeout 30000ms exceeded.
Call log:
  - waiting for locator("[id*='add_to_cart']").first
    - locator resolved to <button href="#" id="add_to_cart">Ajouter au panier</button>
  - attempting click action
    2 × waiting for element to be visible, enabled and stable
      - element is visible, enabled and stable
      - scrolling into view if needed
      - done scrolling
      - <div id="overlay"></div> from <header>…</header> subtree intercepts pointer events

Playwright détecte bien le bug : overlay from header subtree intercepts pointer events

Et pour confirmer, voici le même test avec Chromium :

browser = playwright.chromium.launch(headless=False) # ✅ Test réussi

A propos de l'auteur.


Je suis Thomas Simonet, développeur web et chef de projet e-commerce depuis plus de 10 ans. Chez Bergère de France, j'ai piloté pendant 5 ans une boutique Magento 2 à 21 M€ de CA annuel, et j'ai fait passer leur boutique Amazon de 0 à 550 k€.

En savoir plus
Photo de Thomas Simonet, fondateur de Panier Percé

Audit e-commerce complet en 5 jours.

Je passe ta boutique en revue : sécurité, performance, SEO, UX, CRO, marketing. 200+ points de contrôle au total.

En 5 jours, j'analyse chaque levier et je te rédige des recommandations claires, priorisées par criticité et facilité de mise en oeuvre dans une feuille de route claire et précise.