HTML onscroll Attribute

Beginner
⏱️ 6 min read
📚 Updated: Jun 2026
🎯 3 Examples
Events & Handlers

Introduction

The onscroll attribute is an inline event handler for the scroll event. It runs JavaScript when the user scrolls inside a scrollable element — vertically or horizontally. Use it on containers with overflow: auto or overflow: scroll to react to scroll position, update labels, lazy-load content, or build effects like sticky headers. Read element.scrollTop or window.scrollY inside your handler. For whole-page scroll, prefer window.addEventListener("scroll", …). Throttle heavy work because scroll fires very often. For “when this section enters the viewport,” consider IntersectionObserver instead.

What You’ll Learn

01

Event handler

Inline JS.

02

scroll

Position change.

03

Overflow box

Scrollable div.

04

scrollTop

Pixels scrolled.

05

Throttle

Performance.

06

addEventListener

Preferred way.

Purpose of onscroll Attribute

The primary purpose of onscroll is to execute JavaScript when scroll position changes inside an element — so you can respond to user scroll actions and create dynamic experiences such as parallax effects, progress indicators, infinite lists, or lazy-loaded images.

The scroll event fires on the element whose content moved. For a scrollable <div>, put onscroll on that div. For the entire page, attach the handler to window in JavaScript rather than relying on <body onscroll> alone.

💡
Scrollable container required

onscroll only fires when an element actually scrolls. A plain <div> with no overflow will never trigger it — add overflow: auto and content taller than the box.

📝 Syntax

Set onscroll on a scrollable element or assign element.onscroll in JavaScript:

onscroll.html
<div id="panel" style="height:200px;overflow:auto" onscroll="handleScroll()"></div>

<script>
  panel.onscroll = handleScroll;
  window.addEventListener("scroll", handleScroll, { passive: true });
</script>

Syntax Rules

  • Value is JavaScript executed when the scroll event fires.
  • Works on elements with scrollable overflow (auto, scroll, overlay).
  • Also assignable as element.onscroll in script.
  • Fires repeatedly while scrolling — throttle or debounce heavy logic.
  • Read element.scrollTop / scrollLeft for container position; window.scrollY for page scroll.
  • Modern alternative: addEventListener("scroll", handler, { passive: true }).
  • For viewport visibility checks, consider IntersectionObserver.

💎 Values

The onscroll attribute accepts a string of JavaScript code:

  • onscroll="handleScroll()" — Call a named function.
  • onscroll="updateProgress()" — Update a scroll progress bar.
  • JavaScript: element.onscroll = () => { … } — property assignment.
onscroll-handler.html
var timer;
function handleScroll() {
  clearTimeout(timer);
  timer = setTimeout(function () {
    status.textContent =
      "Scrolled " + Math.round(window.scrollY) + " px from top";
  }, 50);
}

window.addEventListener("scroll", handleScroll, { passive: true });

⚡ Quick Reference

Property / APIWhen it runsNotes
scrollScroll position changesonscroll
element.scrollTopRead anytimeVertical px inside container
window.scrollYRead anytimePage scroll from top
element.scrollHeightRead anytimeTotal scrollable height
IntersectionObserverElement enters viewportLazy load, reveal on scroll

Applicable Elements

TargetSupported?Notes
<div>, <section> with overflowYesPrimary inline use — scrollable containers
<textarea>, <iframe>YesNative scrollable elements
windowYes (JS)Page scroll via addEventListener
<body>PartialPrefer window for document scroll
Non-scrollable elementsNoNo overflow — no scroll event

onscroll vs onwheel vs IntersectionObserver

APIWhat it watchesTypical use
onscrollScroll position changeProgress bars, parallax, scroll labels
onwheelMouse wheel / trackpad inputCustom zoom, horizontal carousels
IntersectionObserverElement visibility in viewportLazy loading, animate on reveal
CSS position: stickySticky positioningSticky headers without JS

Examples Gallery

Scrollable div with inline handler, dynamic assignment, and a throttled page-scroll progress label.

👀 Live Preview

Scroll this page — your distance from the top updates below:

Scroll position: 0 px from top

Example — onscroll on a scrollable div

Detect scrolling inside a box with overflow: auto:

div-onscroll.html
<div id="panel"
     style="height:150px;overflow:auto;border:1px solid #ccc"
     onscroll="showScroll()">
  <div style="height:500px">
    <p>Scroll inside this box.</p>
  </div>
</div>
<p id="out"></p>

<script>
  function showScroll() {
    var panel = document.getElementById("panel");
    document.getElementById("out").textContent =
      "Scrolled " + panel.scrollTop + " px";
  }
</script>
Try It Yourself

How It Works

When the user scrolls inside the div, the browser fires scroll on that element. The inline attribute calls showScroll(), which reads scrollTop — pixels scrolled from the top of the container.

Dynamic Values with JavaScript

Assign the handler on an element at runtime:

dynamic-onscroll.html
<script>
  document.getElementById("dynamicElement").onscroll = function () {
    log.textContent = "Scrolling inside the box!";
  };
</script>
Try It Yourself

How It Works

Assigning element.onscroll is equivalent to the inline attribute for that element. Use this when you attach the handler after the DOM loads or based on user interaction.

Example — Throttled page scroll label

Track how far the user has scrolled down the page without running heavy code on every pixel:

throttled-scroll.html
var timer;
window.addEventListener("scroll", function () {
  clearTimeout(timer);
  timer = setTimeout(function () {
    var y = window.scrollY;
    var max = document.documentElement.scrollHeight - window.innerHeight;
    var pct = max > 0 ? Math.round((y / max) * 100) : 0;
    status.textContent = "Page scroll: " + pct + "% (" + Math.round(y) + " px)";
  }, 50);
}, { passive: true });
Try It Yourself

How It Works

Scroll can fire dozens of times per second. A 50ms throttle batches updates so your UI stays smooth on mobile devices.

♿ Accessibility

  • Respect reduced motion — Check prefers-reduced-motion before parallax or scroll-driven animations.
  • Do not hijack scroll — Avoid blocking normal page scroll unless the user expects it (e.g. a modal).
  • Keyboard scroll — Scroll events also fire from Page Up/Down and arrow keys; test keyboard-only navigation.
  • Focus management — Lazy-loaded content should not move focus unexpectedly when it appears.
  • Sticky headers — Ensure fixed/sticky nav does not cover focused elements or skip links.

🧠 How onscroll Works

1

User scrolls content

Wheel, touch, or keys.

Input
2

scroll fires

onscroll runs.

Event
3

Read position

scrollTop / scrollY.

State
=

Update UI

Progress, lazy load, effects.

Browser Support

The scroll event and onscroll handler are supported in all modern browsers, including Internet Explorer 9+.

UI Events · Fully supported

Universal onscroll support

All major browsers fire scroll when scrollable content moves.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 9+ supported
Full support
Opera Fully supported
Full support
onscroll attribute 99% supported

Bottom line: Reliable for scroll handling in all modern browsers — throttle handlers for smooth performance.

💡 Best Practices

✅ Do

  • Throttle or debounce scroll handlers on long pages
  • Use { passive: true } with addEventListener for page scroll
  • Ensure the element has scrollable overflow before using onscroll
  • Use IntersectionObserver for lazy loading images
  • Respect prefers-reduced-motion for scroll animations

❌ Don’t

  • Run heavy DOM work on every scroll event
  • Put onscroll on elements that cannot scroll
  • Block or override normal page scroll without good reason
  • Rely on console.log alone in tutorials — show visible feedback
  • Confuse onwheel (input) with onscroll (position change)

Conclusion

The onscroll attribute runs JavaScript when scroll position changes inside a scrollable element — useful for progress bars, lazy loading, parallax effects, and dynamic UI updates tied to scroll.

Throttle your handlers, use addEventListener with { passive: true } for page scroll, and reach for IntersectionObserver when you only need to know if an element is visible in the viewport.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about onscroll

Bookmark these before wiring scroll logic.

5
Core concepts
📈 02

Throttle

Performance.

Pattern
🔎 03

scrollTop

Read px.

API
👁 04

Observer

Lazy load.

Prefer
05

Not onwheel

Position vs input.

Gotcha

❓ Frequently Asked Questions

It runs JavaScript when the scroll event fires — when scroll position changes inside a scrollable element or on the page.
Only if the div can scroll — give it a fixed height and overflow: auto with content taller than the box. Otherwise the event never fires.
Scroll fires very frequently while the user moves. Throttling batches updates — avoiding jank and wasted CPU, especially on mobile.
onwheel responds to wheel/trackpad input. onscroll fires when scroll position actually changes — including keyboard and scrollbar drag.
addEventListener("scroll", handler, { passive: true }) is preferred in production — easier to throttle and attach multiple listeners.
Yes in all modern browsers; Internet Explorer 9+.

Build scroll-aware pages

Practice the onscroll attribute with scrollable containers and throttled page scroll in the Try It editor.

Try scrollable div example →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful