Thumbnail Tester & Previewer

A thumbnail that looks great at 1280×720 in your editor has to survive at 120 pixels next to autoplay and ads. Upload your design — or pull a video's current thumbnail — and see it at the sizes viewers actually meet it, before you publish.

Preview your thumbnail

Everything stays in your browser. Load a second design into slot B for a side-by-side A/B comparison.

Design A

Design B optional A/B

Mockup text

Load an image above to see it in the 4 preview surfaces and the legibility strip.

What the tester actually does

When you choose a file, your browser decodes it locally to learn its pixel width and height, then displays it from an in-memory object URL. Nothing is resampled, analysed, or sent anywhere: the same bytes are drawn into each preview at a fixed display size. When you paste a link instead, the same parser and thumbnail-set engine that power the downloader turn it into an 11-character video ID and a list of image addresses, your browser fetches the largest one directly from YouTube, and the placeholder check runs before anything is shown. Either way, every loaded image is then rendered in 4 surfaces — Home grid card (desktop) at 320×180px, Suggested / sidebar row at 168×94px, Search result row at 246×138px, Mobile list row at 160×90px — and in a legibility strip at 120, 168, 246 pixels wide, with your title, channel name, meta line, and duration badge around it, because a thumbnail is never displayed in isolation.

Reading the result for the first time? The guide How to read the thumbnail tester owns the worked examples — the status line readout by readout, the near-miss export sizes, and the filename label rules with sample names — and the rest of the site's background reading is in the guides index. This page explains the mechanism those examples come from: what is fetched, what is decoded, what is computed, and where the tool stops.

The preview surfaces: typical, not a spec

The 4 slots are rendered at true display sizes — the CSS pixel sizes video platforms typically use for each surface. They move a few pixels with every redesign, so the engine labels them honest current typicals and this page repeats the label: representative, never exact. Each slot is a fixed box of exactly that width and height, and your image is drawn inside it at that size, so what you see is the detail that survives inside that pixel budget, not a resampled file. The table below adds the engine's own arithmetic. The simplified ratio comes from the same describeRatio function the tool uses on your upload, and the last column asks the aspect engine what exact 16:9 would need at each width. 2 of the 4 typicals cannot be exactly 16:9, because whole pixels cannot land on a fractional height — the engine reports the exact value and the rounding rather than hiding it.

Surface Typical size Ratio Exact 16:9 height at that width
Home grid card (desktop) 320×180px 16:9 (1.778) 180 — exact
Suggested / sidebar row 168×94px 84:47 (1.787) 94.5 — no whole pixel; nearest is 95
Search result row 246×138px 41:23 (1.783) 138.375 — no whole pixel; nearest is 138
Mobile list row 160×90px 16:9 (1.778) 90 — exact

The legibility strip

Below the mockups, the strip shows the same image at 120px, 168px, 246px wide — from the width of the smallest size YouTube stores (120×90) up to the width of the search result row typical (246×138); both ends are pinned to those engine constants when the page is built. The strip fixes only the width; the height follows from the image's own ratio, so a 16:9 image comes out 67.5px tall at 120px, 94.5px tall at 168px, 138.375px tall at 246px — fractional where the arithmetic is fractional, which the browser handles. Nothing is measured here. The strip exists so you can see, rather than guess, which parts of the image remain distinguishable between 120 and 246 pixels, and the grayscale toggle applies to it as well.

The URL box runs the same parser as the downloader, and the parser works in a fixed order rather than by pattern-matching the whole string. The input is trimmed, and an empty box is refused as empty-input. If what remains is exactly an 11-character video ID — letters, digits, hyphen, underscore — it is accepted as a bare ID with no URL machinery at all. Anything with whitespace inside is refused as not-a-youtube-url, because it is neither a link nor an ID. The text is then read as a web address — a missing https:// is supplied, so a copied youtube.com/… without its scheme still parses — and only http and https schemes survive: a javascript: address can carry a convincing hostname, and it is refused as not-a-youtube-url before the hostname is even looked at. The hostname must be one YouTube serves video pages from. A youtu.be share link takes the first path segment as its ID; a lookalike domain such as youtube.com.evil.example is refused as not-a-youtube-url, not treated as YouTube. On a genuine host the first path segment decides the rest: channel paths are refused as channel-url, a playlist page as playlist-url, a watch link that carries list= but no v= as playlist-url, and an embed/videoseries playlist embed as playlist-url; a watch link yields its v= value, and Shorts, embed, /live/, and legacy /v/ paths yield the segment after them. A YouTube path the parser does not recognise is unsupported-url, and every candidate ID, from whichever branch, is validated against the exact character set and length, so invalid-video-id is the answer for a too-short ID inside a link (a bare ID that is too short never reaches this step — it fails the ID pattern, is read as an address, and is refused as not-a-youtube-url, as the methodology table shows). Each of those codes was produced by running the parser when this page was built, and the 6 accepted forms — watch?v= with extra parameters, youtu.be with a tracking string, Shorts without a scheme, embed, /live/, a bare ID — were checked to resolve to one and the same ID. The complete rejection table — every rejection the engine can produce, with the message the status line prints word for word — is on the methodology page.

From a valid ID the engine derives one address per stored size, and the tester walks them largest-first: maxresdefault → sddefault → hqdefault. It stops at hqdefault, which exists for effectively every public video, so the 2 smallest sizes are never requested. The downloader needs a verdict for every size, because each one gets its own button or a "not available for this video" label; the tester needs one image, so it stops at the first size that passes. Whichever frame you end up with, the crop report treats it like any other upload — and the fallbacks are stored in 4:3 frames, so if the largest size is missing for that video the status line will say the image is not 16:9 and quantify the crop.

Order Size key Frame Ratio Cover crop in a 16:9 slot Address
1 maxresdefault 1280×720 16:9 none https://img.youtube.com/vi/jNQXAC9IVRw/maxresdefault.jpg
2 sddefault 640×480 4:3 25% of height hidden https://img.youtube.com/vi/jNQXAC9IVRw/sddefault.jpg
3 hqdefault 480×360 4:3 25% of height hidden https://img.youtube.com/vi/jNQXAC9IVRw/hqdefault.jpg

That the fetch works at all is not a given. A page can only read image bytes from another domain when that domain's server explicitly allows it (CORS), and YouTube's image server sends Access-Control-Allow-Origin: * on thumbnail responses — verified empirically, as the methodology page records. That header is what lets your browser fetch the image, decode it, and run the check below; without it the tester could display the image but never measure it. The request goes from your browser straight to YouTube's image server, the same request it would make while you browse YouTube, and this site's servers never see the link.

A missing size does not fail cleanly on YouTube's side: the answer is HTTP 404 with a gray 120×90 placeholder as its body, which a plain <img> renders without complaint. The tester reads the two signals the methodology page describes, in order. A response whose status is not OK is skipped outright — nothing is decoded, and the ladder moves to the next size. An OK response is decoded in your browser to learn its real pixel width and height, and those dimensions are handed, with the status flag set, to the same pure classifier the downloader uses. Asking for maxresdefault and decoding 1280×720 is classified available, and the ladder stops there; asking for maxresdefault and decoding 120×90 is classified missing, and any answer other than available sends the ladder on to the next size. The width test is relative to the size requested rather than an absolute threshold, because default really is 120×90: the classifier calls a 120-pixel decode at that size available. That size is never in the tester's ladder, so the distinction matters to the downloader rather than here — as do the classifier's inputs the tester never supplies: a failed status (classified missing) and bytes that will not decode (classified undecodable), which the downloader needs in order to label every size. The tester skips a non-OK response before classifying, and a body that will not decode drops it into the fallback path described under Where the tool stops. The classifier's full matrix is on the methodology page; the guide walks through the three verdicts a status line usually shows.

How the crop report is computed

The status line under each slot reports the image's pixel size, its simplified ratio, and what a 16:9 "cover" fit hides. The 16:9 test is exact integer arithmetic — width × 9 must equal height × 16 — and the crop is geometry, not opinion: an image wider than 16:9 is scaled to the slot's height and loses width at the sides; a taller one is scaled to the slot's width and loses height at the top and bottom. The percentage is the share of that axis outside the slot, rounded to one decimal. Every figure below comes from the engine for the listed input.

Upload Pixels Ratio Fits 16:9 Hidden in a 16:9 slot
Full-HD export 1920×1080 16:9 (1.778) yes nothing
Resolution guidance (size guide) 3840×2160 16:9 (1.778) yes nothing
maxresdefault frame 1280×720 16:9 (1.778) yes nothing
sddefault frame 640×480 4:3 (1.333) no 25% of height
hqdefault frame 480×360 4:3 (1.333) no 25% of height
Square 1080×1080 1:1 (1.000) no 43.8% of height
Vertical 1080×1920 9:16 (0.563) no 68.4% of height
Ultra-wide 2560×1080 64:27 (2.370) no 25% of width
Wide share card 1200×630 40:21 (1.905) no 6.7% of width

The 16:9 target is not the tester's own choice. Google's help documentation recommends that shape — the size guide cites it to Google's "Add video thumbnails" article, checked on July 25, 2026 — which is why the slots and the crop report are built around that one ratio. The resolution-guidance row in the table takes its input from the size guide too, read from that page as it builds, so the figure is the one it cites to the same article on the same date rather than a claim of this page's own. The engine does not round an image into 16:9 that is not: the test has no tolerance, so an export one pixel off its exact height is reported as not 16:9 with the small crop that miss costs, and the guide walks through that near-miss case with the numbers. If you want the report to say "fits", pick a width the aspect calculator marks as exact. For a square upload the whole line reads: Loaded: my design — 1080×1080 (1:1); not 16:9 — about 43.8% of its height is hidden in 16:9 slots.

Filenames and labels

An upload is labelled by its filename so that A/B rows stay readable: the extension is stripped, hyphens and underscores become spaces, runs of whitespace collapse, and anything longer than 40 characters is cut with an ellipsis. A name that is only an extension falls back to a generic label. The filename never leaves your browser and is not part of any measurement — it is display text, derived by the same pure function the tool calls, and the guide runs sample filenames through it.

A thumbnail pulled from a link is labelled with its video ID and the size key that was actually served, so an A/B row tells you whether you are looking at maxresdefault or a fallback frame.

What is measured, and what is not

Measured: the decoded pixel width and height, the simplified ratio and its decimal, whether the image is exactly 16:9, and the axis and percentage a cover fit hides. Rendered but not measured: the image at each typical size, the strip, and the mockup text you typed. Not measured at all: any contrast score, any detection of text or faces, and anything about what happens after you publish — the tester makes no prediction, ranks nothing, and would be dishonest if it claimed to. The grayscale toggle is a display filter, not an analysis. The duration badge in the mockups is a rendered element placed by the stylesheet, not the overlay-zone arithmetic; if you want the zone geometry, the safe-area checker computes it from the same convention-not-spec module. For the home grid card (desktop) size of 320×180, that engine places the typical zones at: Duration badge (typical) 70×25px at (250, 155); Hover controls (typical) 51×54px at (269, 0); Watched-progress bar (typical) 320×9px at (0, 171). Those rects model a convention at typical proportions — YouTube publishes no overlay specification — which is why every label carries the word typical.

Where the tool stops

Sizes are CSS pixels; what you see is your browser's own scaling of the image at that size, not a downsampled copy you could export. If no size in the ladder passes the check, the status line reports that no thumbnail could be fetched for that video. A file that will not decode as an image, or that is over the tester's size cap, is refused with a message rather than shown broken. If the fetch itself is blocked in your environment, the tester degrades to a direct image address — the previews still render, but the placeholder check cannot run and the reported size is the nominal one for that variant, not a decoded measurement. And the title, channel, and meta line are yours to type: they change what surrounds the image and nothing else.

A/B without self-deception

When you compare two designs, keep everything else identical — same title, same metadata, same surfaces. That is exactly what slot B does: both images are rendered at the same sizes, next to the same text, in the same order, so the only variable is the thumbnail itself. The tester does not score the pair or predict anything about them. What it gives you is the comparison at the sizes that matter, with the shrinking already done, so that the decision is made against the real display size rather than the editor's zoom level.

Why the mockups are generic on purpose

These previews are evocative of "a video platform" — neutral grays, no logo, no cloned iconography — because YouTube's interface and branding belong to YouTube. The pixel sizes, text truncation, and badge placement are what you need to evaluate a thumbnail, and none of that requires imitating anyone's trade dress. ThumbnailPro is not affiliated with YouTube or Google.

Frequently asked questions

Why do the mockups look like a video platform but not exactly like YouTube?

Deliberately. YouTube’s interface, logo, and exact iconography are YouTube’s property, so the previews use neutral, generic video-platform layouts at the same display sizes instead. What matters for judging a thumbnail — the pixel dimensions, the surrounding text, the duration badge covering a corner — is all there; the branding is not.

Are the preview sizes real?

They are honest current typicals: 320×180, 168×94, 246×138, 160×90 pixels for the grid, sidebar, search, and mobile surfaces. Platforms shuffle these by a few pixels with every redesign, so treat them as representative display sizes, not a specification.

What does the grayscale toggle actually do?

It applies a grayscale filter to every thumbnail image in the mockups, both A/B slots, and the legibility strip — and nothing else. No score is computed. Whatever still separates one region of your image from another with the color removed is a difference in lightness; whatever disappears was carried by hue alone. That is the entire check, and you read it by eye.

Why does my uploaded image get cropped in the previews?

The preview slots are 16:9, like the surfaces they stand in for. An image of another shape is fitted the way a “cover” fit does — scaled until it fills the slot, with the overflow on one axis hidden — and the status line names the axis and the percentage. A 4:3 frame such as 640×480 loses 25% of its height; a square one loses 43.8%. Export at exactly 16:9 — the shape Google’s help documentation recommends, verified July 25, 2026 on the size guide — at 1280×720 or larger, and nothing is hidden.

Is my image uploaded to a server?

No. The file is read by JavaScript in your tab, displayed from a local object URL, and discarded when you close the page. Nothing you upload leaves your device.

Can I compare two designs?

Yes — load a second image into slot B and every mockup renders both designs side by side with the same title and metadata, so the only variable is the thumbnail itself. The tester does not score or rank the two; it puts them at identical sizes next to identical text and leaves the judgement to you.

Which image do I get when I paste a video link?

The largest one YouTube actually serves for that video. The tester requests maxresdefault → sddefault → hqdefault in that order and keeps the first that passes the placeholder check; the ladder stops at hqdefault, which exists for effectively every public video, so the 2 smallest stored sizes (default at 120×90 and mqdefault at 320×180) are never requested. If only hqdefault exists you get a 480×360 image, which is 4:3 — and the crop report will say so.

What happens if my browser cannot fetch the image?

If the request itself fails — an extension or proxy interfering with it, for example — the tester falls back to showing the image straight from YouTube’s address in a plain image element. The previews still render, but on that path the tool cannot decode the bytes, so the status line reports the size YouTube lists for that variant rather than a measured one, and the placeholder check cannot run.

Images are processed locally and never transmitted. The preview sizes and crop math come from the same tested module documented on the methodology page.