Complete JavaScript Course Module 10: Intermediate: The Browser Object Model (BOM)

JavaScript Window Object and Screen: The Browser Object Model Explained

  • Beginner
  • Lesson 10.1
  • 6 min read
  • 41 of 76 in the course

In short

The JavaScript window object is the browser tab your code runs in. In this lesson you will learn what the Browser Object Model (BOM) is, how to read the window and screen size, react to resizing, scroll the page and check media queries. What is the BOM and how is it different from the DOM?

The JavaScript window object is the browser tab your code runs in. In this lesson you will learn what the Browser Object Model (BOM) is, how to read the window and screen size, react to resizing, scroll the page and check media queries.

What is the BOM and how is it different from the DOM?

The BOM (Browser Object Model) is the set of objects the browser gives you to talk to the browser itself, not to the page content. The DOM (Document Object Model), which you met in the DOM module, is about the page: headings, buttons, paragraphs.

A simple comparison: if a web page is a letter, the DOM is the text on the paper, and the BOM is the envelope, the post office and the desk the letter sits on. The BOM tells you how big the window is, what the current address (URL) is, what language the user speaks, and lets you go back in history.

The main BOM objects are:

ObjectWhat it gives you
windowThe browser tab itself: size, scrolling, timers, popups
window.screenInformation about the user's physical screen
window.locationThe current URL, and ways to change it
window.historyThe back and forward history of the tab
window.navigatorInformation about the browser and device
documentThe page itself (this is the DOM)

Notice that document lives inside window too. The DOM is actually one part of the bigger window object.

Note: There is no official "BOM standard". The name is just a handy label for these browser objects. Today they are all described in the HTML Living Standard and other web standards, and they work the same way in all modern browsers.

Why is window called the global object?

In a browser, window is the global object. That means everything that is available "everywhere" in your script is really a property of window. You have been using it all along without writing its name.

console.log(window.document === document);
// Output: true

window.console.log("Hello from window.console");
// Output: Hello from window.console

console.log(typeof window.setTimeout);
// Output: function

var oldStyle = "I am on window";
let modern = "I am not on window";
console.log(window.oldStyle);
// Output: I am on window
console.log(window.modern);
// Output: undefined

Here document, console, setTimeout and alert are all properties of window, so you can write them with or without window. in front. The last part shows an important detail: old-style var variables at the top level become properties of window, but let and const do not. This is one more reason to use let and const: they do not clutter the global object.

Common mistake: Naming your own top-level variable name, status or top with var. These already exist on window (for example window.name is always a string), so your value can behave strangely. Use const and more specific names like userName.

How to get the window size with innerWidth and innerHeight

window.innerWidth and window.innerHeight give you the size of the viewport, the visible area of the page inside the browser, in CSS pixels. outerWidth and outerHeight include the browser's toolbars and borders, and you rarely need them.

To react when the user resizes the window (or turns their phone), listen for the resize event on window:

<!DOCTYPE html>
<html lang="en">
<body>
  <p id="size">Resize the window...</p>

  <script>
    const sizeText = document.querySelector("#size");

    const showSize = () => {
      const width = window.innerWidth;
      const height = window.innerHeight;
      const layout = width < 600 ? "phone layout" : "desktop layout";
      sizeText.textContent = `${width} x ${height} px (${layout})`;
    };

    showSize();                                   // show it once at the start
    window.addEventListener("resize", showSize);  // and again on every resize
  </script>
</body>
</html>

When you open this page, you see something like "1280 x 720 px (desktop layout)". Drag the window narrower and the text updates live. We call showSize() once immediately, because the resize event only fires when the size changes, not when the page loads.

Tip: The resize event can fire dozens of times per second while dragging. Keep the handler small. In the Performance lesson you will learn to "debounce" it so heavy work runs only once the user stops resizing.

How to scroll with JavaScript: scrollTo, scrollBy and scrollY

window.scrollY tells you how many pixels the page is scrolled down from the top (and scrollX from the left). To move the page yourself, use:

  • window.scrollTo(x, y) or window.scrollTo({ top, left, behavior }) scrolls to an exact position.
  • window.scrollBy(x, y) or window.scrollBy({ top, behavior }) scrolls by an amount from where you are now.

Here is a classic "Back to top" button that appears only after you scroll down:

<!DOCTYPE html>
<html lang="en">
<body style="height: 3000px; font-family: sans-serif;">
  <h1>A very long article</h1>
  <button id="toTop" hidden style="position: fixed; bottom: 20px; right: 20px;">Back to top</button>

  <script>
    const toTopButton = document.querySelector("#toTop");

    window.addEventListener("scroll", () => {
      // show the button after 400px of scrolling
      toTopButton.hidden = window.scrollY < 400;
    });

    toTopButton.addEventListener("click", () => {
      window.scrollTo({ top: 0, behavior: "smooth" });
    });
  </script>
</body>
</html>

Scroll down and a button appears in the bottom-right corner. Click it and the page glides back to the top. behavior: "smooth" gives the smooth animation; leave it out (or use "instant") to jump straight there. Try window.scrollBy({ top: 300, behavior: "smooth" }) in the console to move down one "step".

How to use window.screen and devicePixelRatio

window.screen describes the user's physical monitor, not the browser window:

  • screen.width and screen.height are the full screen size.
  • screen.availWidth and screen.availHeight are the space left after the taskbar or dock.
  • window.devicePixelRatio tells you how many real device pixels make one CSS pixel. A normal monitor gives 1; most phones and "Retina" screens give 2 or 3.
console.log(`Screen: ${screen.width} x ${screen.height}`);
console.log(`Available: ${screen.availWidth} x ${screen.availHeight}`);
console.log(`Window: ${window.innerWidth} x ${window.innerHeight}`);
console.log(`Pixel ratio: ${window.devicePixelRatio}`);
// Output (example on a laptop):
// Screen: 1440 x 900
// Available: 1440 x 875
// Window: 1280 x 720
// Pixel ratio: 2

A pixel ratio of 2 means the screen is sharp, so you might load a bigger image for it. For normal layout decisions, though, use the window size, not the screen size: the user's window is often smaller than their screen.

How to check a CSS media query in JavaScript with matchMedia

window.matchMedia() lets JavaScript ask the same questions as CSS media queries. It returns an object with a matches property (true or false) and a change event you can listen to.

const smallScreen = window.matchMedia("(max-width: 600px)");
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");

console.log("Small screen?", smallScreen.matches);
console.log("Dark mode?", prefersDark.matches);
// Output (example): Small screen? false
// Output (example): Dark mode? true

smallScreen.addEventListener("change", (event) => {
  console.log(event.matches ? "Switched to small layout" : "Switched to large layout");
});

The change event fires only when the answer flips, for example when the window crosses 600px. That makes matchMedia much lighter than checking innerWidth on every resize. It also keeps your JavaScript breakpoints in sync with your CSS ones. You can read more on MDN's matchMedia page.

Practice exercise

Build a small "reading progress" page. Make the body very tall (for example height: 4000px). Add a paragraph fixed at the top that shows "You have read 35% of this page". Update it on every scroll event. Then add a second line that says "Phone" or "Desktop" using matchMedia("(max-width: 600px)") and its change event.

Hint: the total scrollable distance is document.documentElement.scrollHeight - window.innerHeight. Divide window.scrollY by that number, multiply by 100 and use Math.round().

Key takeaways

  • The BOM is the set of browser objects (window, screen, location, history, navigator); the DOM (document) is the page content inside it.
  • window is the global object: alert, setTimeout and document are all its properties.
  • innerWidth and innerHeight give the viewport size; listen to resize to react to changes.
  • Use scrollY to read the scroll position and scrollTo / scrollBy with behavior: "smooth" to move it.
  • matchMedia checks CSS media queries from JavaScript and fires change only when the result flips.