Wenn du eine Matomo-Heatmap geöffnet hast und deine Sidebar abgeschnitten war, die untere Hälfte eines Modals gefehlt hat oder Klick-Marker über Inhalt schweben, der dort gar nicht hinzugehören scheint — die Klicks selbst sind in Ordnung. Matomo hat sie an den richtigen Koordinaten aufgezeichnet. Was kaputt ist, ist der Screenshot darunter. Irgendein Wrapper auf der Seite hat overflow: hidden, overflow: auto oder overflow: scroll gesetzt, und Matomos Renderer behandelt alles, was über die sichtbare Kante dieses Wrappers hinausgeht, als wäre es schlicht nicht vorhanden. Die Heatmap zeigt dir deshalb nur einen Ausschnitt der Seite, statt der Seite, die deine Besucher tatsächlich gesehen haben.
Die schnellste Lösung ist eine kostenlose Chrome-Erweiterung, die wir pflegen: der Matomo Heatmap Helper. Er neutralisiert Overflow-Container direkt vor jeder Erfassung, lässt den Renderer das vollständige Dokument sehen und stellt die ursprünglichen Styles danach wieder her. Der Rest dieses Posts erklärt, wie du dasselbe ohne Erweiterung hinkriegst — plus ein paar dauerhafte Fixes, die sich zu shippen lohnen.
Wie du es ohne die Erweiterung behebst
Es gibt ein Console-Snippet, das das Problem kurz vor jeder Erfassung überbrückt, und ein paar dauerhafte Fixes, die du mit der Seite ausliefern kannst. Nimm das, was zu deinen Rahmenbedingungen passt.
Alle overflow-eingeschränkten Elemente auf der Seite auflisten
Bevor du irgendetwas änderst, finde erst heraus, welche Wrapper abschneiden. Öffne die Seite in Chrome, drück F12 für DevTools, wechsle zur Console und füge Folgendes ein:
// Listet alle Elemente auf, die gerade Inhalt abschneiden
Array.from(document.querySelectorAll('*')).filter(el => {
const s = getComputedStyle(el);
return ['hidden','auto','scroll'].includes(s.overflow)
|| ['hidden','auto','scroll'].includes(s.overflowY);
});Das gibt dir die genaue Liste der Knoten, die Matomos Renderer als Boxen fester Größe behandeln wird. Die üblichen Verdächtigen sind Sidebars, Modals, Custom-Scroll-Wrapper um <main> und alte Clearfix-Wrapper mit overflow: hidden aus Layoutgründen, die seit Jahren keine Rolle mehr spielen.
Der schnelle Fix: Overflow-Einschränkungen per Console entfernen
Das ist das Snippet, das wir direkt vor dem Auslösen von Matomos Heatmap-Erfassung in die Browser-Console einfügen. Es geht durch jedes Element, das gerade abschneidet, und setzt dessen overflow und overflow-y auf visible. Wenn Matomo das DOM serialisiert, versteckt sich nichts mehr hinter einer sichtbaren Kante.
// Direkt vor der Erfassung in die Browser-Console einfügen.
// Setzt jeden Overflow-Container auf der Seite auf 'visible'.
document.querySelectorAll('*').forEach(el => {
const s = getComputedStyle(el);
if (['hidden','auto','scroll'].includes(s.overflow) ||
['hidden','auto','scroll'].includes(s.overflowY)) {
el.style.overflow = 'visible';
el.style.overflowY = 'visible';
}
});Die Seite sieht einen Moment lang seltsam aus. Sidebars dehnen sich auf ihre volle Inhaltshöhe aus, Modals strecken sich über den Viewport-Rand hinaus, und alles, was von einem Container fester Höhe abhing, hat plötzlich keinen mehr. Das ist in Ordnung. Du erfasst die Heatmap, du browst nicht die Seite. Wenn du fertig bist, einfach neu laden.
Das ist der schnelle Weg. Er funktioniert für einmalige Erfassungen und Review-Zyklen, bei denen du jetzt einen sauberen Screenshot brauchst und nicht auf eine Code-Änderung warten willst. Für alles, was du regelmäßig neu erfassen wirst, ship einen der dauerhaften Fixes weiter unten.
Dauerhafter CSS-Fix, auf Erfassungsmodus beschränkt
Die sauberste Lösung, wenn du das Stylesheet kontrollierst, ist ein heatmap-only Override, der jeden Overflow-Container abschaltet, sobald Matomos Tracker geladen ist. Ein CSS-Block, eine JS-Zeile — fertig.
/* Selektoren auf die Wrapper deiner Seite anpassen */
html.heatmap-mode .sidebar,
html.heatmap-mode main,
html.heatmap-mode .modal-shell {
overflow: visible !important;
overflow-y: visible !important;
height: auto !important;
max-height: none !important;
}// Zur Seite hinzufügen. Schaltet die Klasse an, sobald Matomos Tracker auf der Seite ist.
if (window._paq) document.documentElement.classList.add('heatmap-mode');Der Override greift jetzt nur auf Seiten, auf denen Matomo ohnehin lädt — für eine Heatmap-Review kein Problem und für den Rest deines Traffics unsichtbar. Wenn du es enger scopen willst, gate es auf einen Query-Parameter (?heatmap=1) oder ein separates Stylesheet, das nur auf der Staging-Kopie eingebunden wird, auf die du Matomo zeigst.
Den verschachtelten Scroll-Container ganz loswerden
Wenn deine Seite overflow: auto auf <main> oder einem anderen Wrapper aus Scrollytelling-Gründen hat, ist der architektonische Fix, ihn wegzuschmeißen und das Dokument scrollen zu lassen. Matomos Renderer kann Document-Scroll nachbilden, einen verschachtelten Scroll-Zustand kann er nicht. Außerdem bekommst du eine bessere mobile UX (iOS Safari hat seine eigenen Meinungen zu verschachtelten Scroll-Containern), und die Accessibility verbessert sich, weil Tastatur-Scroll und Screen-Reader-Navigation so funktionieren, wie Nutzer es erwarten.
Das ist eine größere Änderung als der CSS-Override, aber sie ist die, die verhindert, dass das Problem wiederkommt, wenn jemand einen neuen Abschnitt zum Layout hinzufügt.
Clearfix overflow: hidden durch display: flow-root ersetzen
Alte Clearfix-Wrapper mit overflow: hidden waren ein Workaround, um gefloatete Kindelemente zu containen. display: flow-root macht dasselbe, ohne dabei etwas abzuschneiden, und ist seit 2018 sicher in jedem Browser einsetzbar, der noch eine Rolle spielt.
/* Selektor auf deinen Clearfix-Wrapper anpassen */
.row-with-floats {
display: flow-root;
}Gleiches Containment-Verhalten, kein Abschneiden, und kein Kampf mehr mit dem Screenshot. Der schnelle Weg, Kandidaten zu finden: CSS nach overflow: hidden durchsuchen und bei jedem prüfen, ob es wirklich etwas abschneiden soll. Meistens nicht.
Ein Hinweis zum Trade-off
Egal welchen dauerhaften Fix du wählst: scope den Override (eine Klasse, ein Query-Parameter, ein heatmap-only Stylesheet), statt die Live-Styles für alle zu verändern. Deine Besucher sehen das Layout, das du für sie gestaltet hast — und das Modal, das innerhalb seiner eigenen Box scrollen soll, soll das für sie weiter tun. Der Override muss nur für den Renderer existieren, den Matomo auf die Seite richtet.
Warum Matomo deine Overflow-Container nicht rendern kann
Matomos Screenshot-Erfassung läuft in zwei Schritten ab. Zuerst serialisiert der Tracker dein Live-DOM in HTML und schickt es weg. Dann rendert dein Matomo-Server dieses HTML in einem festen Viewport, um den Screenshot zu erzeugen, den du in der Heatmap-Ansicht siehst. Keine Browser-Session, kein Scroll-Zustand von deinem Besucher, keine JS-gesteuerten Layout-Anpassungen. Nur eine HTML-Datei, die kalt von einer anderen IP gerendert wird.
Der Renderer kann Document-Scroll nachbilden — deshalb werden lange Seiten sauber erfasst. Was er nicht nachbilden kann, ist der innere Scroll-Zustand eines verschachtelten overflow: auto-Containers, weil der im Browser des Besuchers lebt und nie ins serialisierte DOM einfliest. Wenn der Renderer auf einen overflow: hidden-Wrapper trifft, macht er das, was jeder Browser macht: er schneidet ab. Das Ergebnis ist ein Screenshot, der wie der sichtbare Ausschnitt der Seite zu einem bestimmten Moment aussieht — alles andere ist weg.
Die Klick-Koordinaten machen es schlimmer. Matomo zeichnet Klicks relativ zum Dokument auf, nicht relativ zur inneren Scroll-Position des Containers, in dem der Nutzer scrollte. Ein Klick auf das dritte Element in einer scrollbaren Sidebar wird an der y-Koordinate gespeichert, die es zum Klickzeitpunkt hatte. Wenn der Renderer die Sidebar bei Scroll-Top null screenshottet, gehört diese y-Koordinate jetzt zum ersten Element. Der Marker wird dort eingetragen. Der Klick sieht aus, als wäre er auf dem falschen Link gelandet.
Was tatsächlich schiefläuft
Ein paar Muster, auf die wir immer wieder stoßen:
- Sidebars und Modals mit eigenen Scrollbars. Der Wrapper hat eine feste Höhe und
overflow: auto, die innere Liste ist größer, und nur der Teil, der bei der Erfassung sichtbar war, schafft es in den Screenshot. - Scrollytelling-Seiten mit
overflow: autoauf<main>oder einem ähnlichen Wrapper. Der Body scrollt nicht, das innere Element schon — und die Heatmap erfasst einen Viewport voll Inhalt. - Legacy-Clearfix-Wrapper mit
overflow: hidden, die eigentlich gar nichts abschneiden sollen. Sie sollten Floats containen. Sie schneiden trotzdem ab und lassen Inhalt aus dem Screenshot fallen. - Custom-Dropdown-Menüs oder Akkordeons, die durch Abschneiden mit
overflow: hiddenplus einer Höhen-Transition animieren. Den geschlossenen Zustand sieht Matomo. - CSS
maskoderclip-pathauf einem Container. Andere Property, gleicher Effekt auf den Screenshot. Der Fix ist derselbe: in Capture-Mode ausschalten.
Wenn deine Heatmap Inhalt vermisst oder die Klick-Marker nicht mit den erwarteten Elementen übereinstimmen, triffst du mindestens eines davon. Oft mehrere auf derselben Seite.
Das ist auch dieselbe Problemfamilie, die Schriftarten, Bilder und Sticky-Header im selben Screenshot kaputtmacht. Wir haben einen längeren Post über kaputte Matomo-Heatmap-Screenshots, der den Rest durchgeht, und separate Posts darüber, warum Schriftarten nicht laden und warum Bilder nicht laden, da diese Probleme fast genauso häufig auftauchen.
Was wir tatsächlich tun würden
Wenn du das Stylesheet kontrollierst, ship den heatmap-only Override. Ein CSS-Block, auf eine Klasse beschränkt, die du anschaltest, wenn Matomos Tracker geladen ist. Das ist das kleinste Diff, das das Problem dauerhaft löst, und es ändert nichts an dem, was Besucher sehen.
Wenn das Layout einen verschachtelten Scroll-Container hat, der dich auch sonst schon genervt hat, nimm den architektonischen Fix und lass das Dokument scrollen. Du sparst dir das Problem bei jeder künftigen Heatmap-Erfassung, und deine mobilen Nutzer werden es dir danken.
Wenn weder das eine noch das andere erreichbar ist — kein Stylesheet-Zugriff, Third-Party-Widgets, die du nicht restylen kannst, ein CMS, das kein Custom-CSS durchlässt — ist der Matomo Heatmap Helper das, was wir auf Client-Sites einsetzen, wo wir den Stack nicht anfassen können. Er geht dieselben Overflow-Container durch, die das Snippet findet, neutralisiert sie für die Erfassung und stellt sie danach wieder her — die Seite ist für den nächsten Besucher intakt. Kostenlos, Open Source, Code auf GitHub.
Martez ist das größere Projekt, aus dem die Erweiterung entstanden ist. Es verbindet Matomo mit Meta Ads und Google Ads, sodass ROAS, CLV und Attribution neben deinen Web-Analytics liegen statt in einer separaten Tabelle. Momentan in der Private Beta. Trag dich auf die Warteliste ein, wenn das für dich relevant ist.
Meistens ist das eine Stylesheet-Änderung entfernt. Lohnt sich, es einmal zu erledigen.