Responsive Website Tester

A layout looks fine on your monitor and breaks on somebody's phone. Load the page in a frame you control the width of, drag the handle through the widths real traffic arrives at, and read off which breakpoints turn on where the design gives up.

360 × 800shown at 100 percent
PortraitDevice pixels 1080 × 2400 at 3x
about:blank

Live at 360px

Breakpoints that have already fired at this width. Anything greyed out is waiting for a wider frame.

Tailwind

    Bootstrap 5

      Query that matches here

      @media (min-width: 360px) { }

      Nothing above the base styles is active yet, so what you see is the mobile layout every visitor gets before a single breakpoint applies.

      What a frame proves, and what a frame quietly fakes

      The width of an iframe is the viewport width for everything inside it. Media queries read it, vw units resolve against it, container queries measure their containers inside it, and a grid collapses at exactly the width your stylesheet says. For layout work, the preview above is honest.

      Four things stay desktop no matter how narrow the frame gets, and each one has burned somebody shipping on a Friday:

      • Pointer type. Your mouse is still a mouse, so @media (hover: hover) and (pointer: fine) keep matching. A dropdown built on hover looks perfect here and becomes unreachable on a touchscreen.
      • Device pixel ratio. The frame renders at your monitor's ratio. A phone at 3x will pull the 3x image from your srcset and it will weigh three times what you saw.
      • User agent. Server side device sniffing sees your desktop browser, so any markup branching on the UA string sends you the desktop variant.
      • Browser engine. Everything here runs your engine. Safari on iOS has its own rules for 100vh, sticky headers under the address bar, and date inputs, none of which reproduce in a Chrome or Firefox frame.

      Use this for the pass where you find the width the layout breaks at. Use a real handset, or a device lab, for the pass where you find out whether the thing is usable.

      Why the frame stays blank on most big sites

      Point the tool at a bank, a search engine or a social network and you get an empty rectangle. The site refused embedding, and the refusal arrives in one of two response headers.

      X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' https://toolexe.com

      X-Frame-Options is the older switch with three states: DENY blocks every embed, SAMEORIGIN allows only pages from the same origin, and the long dead ALLOW-FROM is ignored by current browsers. CSP frame-ancestors replaced it, takes a list of origins, and wins whenever both headers are present.

      No browser extension or proxy trick around this belongs in a page like this one, because the header exists to stop clickjacking: an attacker stacking an invisible frame of your logged in bank under a fake button. The workable path is the other direction. On a staging host you own, permit the origin you preview from:

      # nginx, staging only add_header Content-Security-Policy "frame-ancestors 'self' https://toolexe.com" always;

      Then remove the line before that config reaches production. A staging site with loose framing rules and a copy of production data is its own problem.

      Round numbers are device trivia, not breakpoints

      The preset row above exists because people look for it, not because 393 pixels deserves a media query. Device widths churn every release cycle, and a stylesheet pinned to last year's iPhone is a stylesheet you rewrite next year.

      Drag the slider slowly instead and watch the frame. The moment a headline wraps to three lines, a nav crushes into itself, or a table starts a horizontal scrollbar, you have found a breakpoint the content asked for. Round the number outward a little and write it down:

      @media (min-width: 47.5rem) {.card-grid { grid-template-columns: repeat(2, 1fr); }}

      Writing the query in rem rather than px means the breakpoint moves when a visitor raises their default font size, which is what a reader at 24px base text actually needs. Sizing in px pins the layout to a text size somebody has already told the browser they do not want.

      Two widths are worth a look even so. Around 320 pixels is the narrowest screen still in circulation, and a layout with a fixed 340 pixel element overflows there. Past roughly 1600 pixels, a text column with no max-width stretches to a line length nobody finishes reading.

      CSS pixels, device pixels, and the number in the readout

      The readout above prints both. A phone advertising a 1080 by 2400 screen reports a viewport of 360 by 800 to CSS, because its device pixel ratio is 3 and every CSS pixel covers a 3 by 3 block of hardware.

      HardwarePhysical pixelsRatioCSS viewport
      Common Android1080 × 24003x360 × 800
      iPhone 151179 × 25563x393 × 852
      iPad, portrait1536 × 20482x768 × 1024
      1080p laptop1920 × 10801x1920 × 1080

      Media queries only ever see the right hand column, so build against those numbers. The ratio matters in one place: images. Ship a 360 pixel wide slot with a 360 pixel image and it looks soft on every phone made in the last decade. Let the browser pick:

      <img src="hero-360.jpg" srcset="hero-360.jpg 360w, hero-720.jpg 720w, hero-1080.jpg 1080w" sizes="(min-width: 47.5rem) 50vw, 100vw" width="360" height="240" alt="…">

      The width and height attributes are not decoration. They give the browser an aspect ratio to reserve space with, which is the difference between a page that settles and a page that shoves the paragraph you started reading down the screen.

      The one tag that makes all of this apply

      Without a viewport meta tag, mobile browsers pretend to be around 980 pixels wide, render the desktop layout, then shrink the whole thing to fit. Your media queries never fire, and the site looks like a scaled down screenshot.

      <meta name="viewport" content="width=device-width, initial-scale=1">

      Nothing else belongs in that line. Adding maximum-scale=1 or user-scalable=no stops a reader zooming in on small text, which fails WCAG 1.4.4 and is a common finding in accessibility audits. If the layout only holds together because zoom is disabled, the layout is the bug.

      The frame above sidesteps this entirely, since an iframe width is already the viewport width. A page with no viewport tag previews fine here and still breaks on a phone, so check the <head> as well as the preview.

      Container queries changed where the breakpoint belongs

      A media query asks how wide the window is. A card in a narrow sidebar has the same problem as a card on a phone, and the window width tells you nothing about the sidebar.

      .sidebar, .main { container-type: inline-size; } @container (min-width: 30rem) {.card { display: grid; grid-template-columns: 8rem 1fr; }}

      The card now switches on its own width, so one component behaves correctly in a sidebar, a modal and a full width section without a stack of viewport rules describing every context. Support landed across Chrome, Safari and Firefox in 2023, which puts it in reach for most projects now.

      Media queries keep the jobs container queries never took over: page level structure, print styles, prefers-reduced-motion, prefers-color-scheme, and the pointer and hover checks worth remembering while you drag the slider above with a mouse.

      Where this page stops being enough

      A short list, so the preview does not get trusted past the point it earns:

      • Any site sending a framing header shows nothing here. That covers a large share of the web.
      • Pages behind a login stay behind it. The frame carries no session, so you preview the signed out view.
      • Scripts inside the frame read their own dimensions correctly, but a script measuring window.screen or navigator.userAgent reads your desktop.
      • Touch gestures, momentum scrolling, the iOS address bar collapsing on scroll, and on screen keyboards pushing fixed footers around have no equivalent in a frame.
      • Performance numbers mean nothing here. You are on a desktop CPU over your own connection, which is the opposite of the mid range phone on patchy mobile data your slowest traffic arrives on.

      Responsive testing questions

      Why does the preview stay blank for the site I want to check?

      The site sent X-Frame-Options or a Content-Security-Policy frame-ancestors rule refusing to be embedded. Browsers enforce that header and no setting on this page overrides it. Run curl -sI against the URL to confirm which header came back, then preview a staging build where you control the response.

      Is the frame width the same as a real phone viewport?

      For layout, yes. Media queries, vw units and container queries inside the frame all resolve against the width you set, so a breakpoint firing here fires on a phone at that width. Pointer type, device pixel ratio, user agent and browser engine stay desktop.

      Which widths should I test first?

      Start at 320 to catch fixed width elements overflowing on the narrowest screens still in use, then 360 and 393 for the bulk of phone traffic, 768 for tablets in portrait, and 1366 for the most common laptop. After that, drag the slider and stop wherever the layout itself looks wrong.

      Should breakpoints be written in px or rem?

      rem, in most cases. A rem breakpoint scales with the reader's default font size, so somebody browsing at 24px base text gets the simpler layout sooner, when they need it. A px breakpoint ignores that preference and holds the desktop layout on a screen full of oversized text.

      Does this replace the responsive mode in browser dev tools?

      No. Dev tools spoof the user agent, throttle the network, emulate touch and let you inspect the DOM of the page you are testing. This page is faster for the specific job of dragging one width against a live URL and seeing which framework breakpoints are already active.

      Can I preview a page running on localhost?

      Only if your browser reaches it and the dev server permits framing. Vite and similar servers usually do. The request comes from your browser rather than any Toolexe server, so a local address resolves the same way pasting it in the address bar would.

      Is the URL I paste stored anywhere?

      No. The URL sets the src of an iframe in your own browser and lands in the query string so the link is shareable. Nothing is sent to a Toolexe server, logged or queued for a screenshot.

      Why does the rendered page look smaller than the width I picked?

      A 1920 pixel frame will not fit on most screens, so Fit to space scales the whole frame down while keeping the viewport width the page sees unchanged. Breakpoints still fire at the real number. Switch the zoom control to 100 percent and scroll if you need to read the text.