What Is Scroll Depth Tracking and Why It Matters
Scroll depth tracking measures how far visitors actually read on a page. The definition, why it matters for content sites, and how to implement it with IntersectionObserver.
TL;DR
- 1.Scroll depth is the percentage of a page a visitor actually scrolled through, usually reported in 25%/50%/75%/100% buckets.
- 2.It is the closest thing analytics has to a "did people actually read this" metric, especially for long-form content.
- 3.Average scroll depth across content sites lands around 50–60% for blog posts; only 20–30% of readers reach the end.
- 4.IntersectionObserver is the modern, performant way to implement it — it replaces the legacy scroll-event approach that hammered the browser.
- 5.Scroll depth is most valuable when paired with bounce rate and time on page; alone it can be misleading.
- 6.Sleek, GA4, Plausible, and most modern analytics tools support scroll depth either out of the box or via a 10-line snippet.
The definition
Scroll depth is the proportion of a webpage that a visitor scrolled through during their session. It is typically expressed as a percentage of the total page height, and reported in buckets — most commonly 25%, 50%, 75%, and 100%.
The metric exists because pageviews and time on page do not tell you whether a visitor actually consumed your content. A reader who lands on a 4,000-word article and bounces after 5 seconds without scrolling is fundamentally different from one who scrolls to the end and stays for 8 minutes — but both look similar in basic analytics.
Scroll depth was popularized by Google Tag Manager's built-in scroll trigger around 2017, and is now one of the most-used custom metrics in content analytics.
How scroll depth is calculated
The math is straightforward. The browser knows the total height of the page (`document.documentElement.scrollHeight`) and how far the visitor has scrolled (`window.scrollY + window.innerHeight`). Scroll depth at any moment is:
The thresholds matter. If you only fire a "scrolled to bottom" event, you lose the gradient — you cannot tell whether readers are dropping off at the headline, the second paragraph, or the conclusion.
scroll_depth_% = ((scrollY + innerHeight) / scrollHeight) × 100
Most trackers fire events at thresholds:
- 25% reached
- 50% reached
- 75% reached
- 100% reachedWhy scroll depth matters for content sites
For blog and content sites, scroll depth is the single best signal of content quality that does not require user surveys. It tells you:
For ecommerce and SaaS marketing pages, scroll depth tells you whether visitors saw the content below the fold — features, social proof, FAQs, pricing tables. A pricing page where 80% of visitors never scroll to the comparison table is effectively a one-screen page.
- Where readers drop off — if 70% reach the 25% mark but only 30% reach 50%, your introduction is working and your middle is losing them.
- Which articles deserve a redesign — a long article where 50% of readers exit before scrolling past the hero is buried by something at the top.
- Whether your CTA is being seen — a CTA at 80% page depth is invisible if only 20% of readers reach it.
- Whether the headline is delivering on its promise — high entry, low scroll-through is a tell that the title overpromised.
Industry benchmarks
Scroll-depth benchmarks vary by content type and length. Aggregated data from Chartbeat, Hotjar, and Crazy Egg studies through 2024:
- Long-form blog posts (2,000+ words): 20–30% of readers reach the end
- Standard blog posts (800–1,500 words): 40–55% reach the end
- Landing pages (single screen): 80–90% see the full page
- Multi-section landing pages (3+ screens): 30–50% reach the bottom
- News articles: 25–35% finish (Chartbeat's widely-cited 2018–2024 data)
- Documentation and reference pages: 50–70% scroll because readers are searching, not reading linearly
- Average scroll depth on a typical blog post lands at 50–60%
Implementing scroll depth with IntersectionObserver
The legacy way to track scroll depth was to listen to the `scroll` event and check `scrollY` on every fire. This worked but was performance-hostile — the scroll event fires dozens of times per second, and pinning your tracking script to it caused jank on long pages.
The modern approach uses IntersectionObserver, which is built for this exact use case. You drop invisible "marker" elements at 25/50/75/100% of the page, and the browser tells you when each one becomes visible — without you polling the DOM.
Here is a minimal implementation:
This snippet costs roughly 1 KB, runs once on page load, and adds zero overhead to scrolling itself. It works in every browser shipped since 2017.
// Insert invisible markers at 25/50/75/100% of the page
const thresholds = [25, 50, 75, 100]
const fired = new Set()
function placeMarkers() {
const height = document.documentElement.scrollHeight
thresholds.forEach((pct) => {
const marker = document.createElement('div')
marker.style.position = 'absolute'
marker.style.top = (height * pct / 100) + 'px'
marker.style.height = '1px'
marker.dataset.depth = String(pct)
document.body.appendChild(marker)
})
}
placeMarkers()
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const depth = entry.target.dataset.depth
if (!fired.has(depth)) {
fired.add(depth)
// Fire your analytics event here
sleek?.track('scroll_depth', { depth: Number(depth) })
}
}
})
})
document.querySelectorAll('[data-depth]').forEach((el) => observer.observe(el))How to track scroll depth in popular tools
- Google Analytics 4: Enhanced Measurement includes scroll tracking by default but only fires at the 90% threshold. For 25/50/75/100% buckets, you set up custom GTM triggers.
- Plausible: Scroll depth is supported via custom events. You fire `scroll_depth` events from a snippet like the one above, and the dashboard aggregates them.
- Sleek Analytics: Scroll depth is built in for content-tracked sites — enable it in site settings and the dashboard shows scroll-depth distribution per page alongside your standard metrics.
- Hotjar / Microsoft Clarity: These show scroll-depth heatmaps as their core product, with pixel-level granularity. They are complementary to event-based tracking, not a replacement.
- Custom server-side: Some teams pipe scroll events to their own warehouse for joining with conversion data. The implementation is the same snippet pattern.
Common mistakes
- Tracking scroll depth on every page indiscriminately. Long-form articles benefit; a contact form does not.
- Using the scroll event instead of IntersectionObserver, which causes performance regressions on long pages and mobile devices.
- Firing events at every pixel of scroll. Use thresholds (25/50/75/100% or by section) — anything more granular is noise.
- Comparing scroll depth across pages of different lengths without normalizing. A 50% scroll on a 4,000-word article is more reading than a 100% scroll on a 400-word post.
- Treating low scroll depth as a failure. For documentation and reference content, low scroll depth is normal — readers find what they need and leave.
- Ignoring mobile vs desktop. Mobile users scroll faster but read less; the same page often shows higher scroll depth and lower time-per-section on mobile.
When scroll depth is misleading
Scroll depth measures whether someone scrolled past a section, not whether they read it. A reader who flicks to the bottom of a long page in 2 seconds will register as 100% scroll — and contribute zero engagement. This is why scroll depth alone is not a reliable engagement metric.
The honest read is scroll depth combined with time-to-reach-depth. If readers reach 75% in 30 seconds on a 2,000-word article, they are scanning, not reading. If they reach 75% in 4 minutes, they are reading. Most analytics tools do not surface this combination by default — you have to look at scroll depth and average time on page side by side and reconcile.
Tools like Hotjar and Microsoft Clarity solve this with session recordings: they show you the actual scrolling behavior, including pauses and re-reads. The trade-off is that they are expensive at scale and they do not aggregate as cleanly as event-based tracking.
The takeaway
Scroll depth is one of the most underused metrics in content analytics. For any team that publishes long-form content — blogs, documentation, landing pages with significant below-the-fold content — it answers questions that pageviews and bounce rate cannot.
Implement it with IntersectionObserver, fire at 25/50/75/100% buckets, and read it alongside time on page and conversion rate. Use it to find the articles that lose readers in the middle, to validate that your CTAs are actually being seen, and to prioritize which content deserves a redesign.
For teams who want it built in without writing the snippet, modern analytics tools like Sleek include scroll depth on the page-level report — turn it on in settings and the data starts appearing immediately.
Frequently asked questions
What is a good scroll depth for a blog post?
For long-form blog posts (2,000+ words), 20–30% of readers reaching the end is normal. For shorter posts (800–1,500 words), 40–55% is typical. Average scroll depth across a blog post tends to land at 50–60%. Aim higher than your category baseline rather than chasing a universal number.
How do I track scroll depth in Google Analytics 4?
GA4's Enhanced Measurement fires a scroll event at the 90% threshold by default. For 25/50/75/100% buckets, set up custom triggers in Google Tag Manager — create scroll triggers at each threshold and forward them to GA4 as custom events. Most teams find the GTM setup takes about 30 minutes.
What is the difference between scroll depth and time on page?
Scroll depth measures how far a visitor scrolled; time on page measures how long they stayed. Either alone can mislead — a visitor who flicks to the bottom in 2 seconds shows 100% scroll depth and near-zero time. Read them together: high scroll depth + high time on page is the engagement signal.
Why use IntersectionObserver instead of the scroll event?
The scroll event fires dozens of times per second during normal scrolling, and any work you do in its handler runs on every fire — causing jank on long pages and mobile devices. IntersectionObserver lets the browser notify you only when a specific element enters the viewport, which is roughly 100x more efficient for scroll-depth tracking.
Does scroll depth affect SEO?
Not directly. Google does not use scroll depth as a ranking signal. Indirectly, scroll depth correlates with engagement metrics that Google does measure (dwell time, return visits), so improving scroll depth often improves the same things SEO cares about.
Can I track scroll depth without Google Tag Manager?
Yes. A 20-line IntersectionObserver snippet handles it without any tag manager. Privacy-friendly tools like Plausible and Sleek Analytics support scroll-depth events directly via their tracking API — you fire `scroll_depth` events and the dashboard aggregates them.
Is scroll depth misleading?
It can be. Scroll depth measures whether someone scrolled past a point, not whether they read it. A scanner who flicks to the bottom in 2 seconds registers 100% scroll depth without engagement. The honest read is scroll depth combined with time on page — together they tell you whether the visitor actually consumed the content.
Track your own growth loop
Sleek Analytics gives you visitors, sources, pages, devices, and real-time behavior with one lightweight script. No cookies, no GDPR banners.
Related reading
What Is Bounce Rate? Definition, Benchmarks, and How to Improve It
Bounce rate explained: the formula, industry benchmarks (41–55% across most categories), why GA4 redefined it, and the practical levers that move it down.
GlossaryWhat Is a Good Conversion Rate in 2026? (Industry Benchmarks)
A good conversion rate depends on your industry: SaaS 1–3%, ecommerce 2.5–3%, B2B lead gen 2–5%. Real benchmarks, the formula, and the levers that actually move it.
ComparisonsSleek vs Plausible (2026): Which Privacy-First Analytics Tool Wins?
Sleek Analytics vs Plausible in 2026: pricing, features, real-time capabilities, AI chat, revenue tracking, and migration paths. Honest comparison from a competitor.