Free placeholder image generator
Placeholder images without the placeholder host
Free, and there is no account to make: name a width and a height up to 4096 px a side and the box is drawn right here, ready as a PNG file, as an inline data: URI of about 450 bytes, or as SVG source you can paste straight into a component. The label carries the real pixel dimensions and its color is checked against the background at the 3:1 WCAG threshold, so it stays readable on a dark box as well as a grey one. Nothing is fetched from a placeholder service, which is why the mockup still renders behind a corporate proxy, on a plane, and after the URL you would have linked to has stopped resolving.
- 100% free
- No signup
- Up to 4096 px
- PNG, SVG, data: URI
- 20 px blur-up
Press Ctrl+V anywhere on the page to drop in a hex code or a size like 1200x630 — no need to click the field first.
1200 × 630 px · 1.905:1 · label set at 176 px
Label against background: 16.96:1 — clears the 3:1 WCAG threshold for text at 176 px.
Inline data: URI · 480 B
The colors and the dimensions stay legible in the URI, so you can edit them by hand in the markup later.
SVG source · 298 B
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630"> <rect width="1200" height="630" fill="#e5e7eb"/> <text x="600" y="376.6" font-family="system-ui, sans-serif" font-size="176" font-weight="600" text-anchor="middle" fill="#000000">1200 × 630</text> </svg>
The PNG URI is built on demand: encoding a 1200 × 630 canvas on every keystroke would stall the fields.
Blur-up placeholder from the real photo
When the final image already exists, a grey box is the wrong placeholder. Drop the photo in and it is scaled to 20 px wide and encoded twice, so you can see what each form costs as a string: a few hundred bytes either way, small enough to sit in the HTML and be painted before the real file has finished one round trip.
Drop the photograph that will eventually load into this slot.
No photo loaded. This panel is the one placeholder a remote service cannot give you: it has never seen your image.
How to make a placeholder image
Three steps: size the box, color it so the label reads, take it in the form your markup wants.
Set the box
Type a width and a height, or take one of the seven presets — 1200 × 630 for an Open Graph card, 728 × 90 for a leaderboard slot, 150 × 150 for an avatar. Pasting 1200x630 anywhere on the page fills both fields at once, and Swap flips a landscape box to portrait without retyping either number. Anything over 4096 px on a side is refused by name rather than silently clamped, so you never wonder why the export came back smaller than you asked.
Color it so the label survives
Set the background and leave the label color on automatic to get whichever of black or white reads better against it. The readout under the preview gives the exact WCAG ratio and turns orange below 3:1, which is the threshold that applies here because the dimension label is set at 176 px on a 1200 × 630 box. Swap the label for your own text, turn it off for a flat swatch, or add the corner-to-corner cross when the box has to be unmistakable in a screenshot.
Take the form your markup wants
Download PNG puts a file in your repo, Copy data: URI gives a component with no asset pipeline something to render, and Copy SVG source hands you markup you can keep editing. The two encodings sit side by side with their byte counts — 414 against 480 on the default box — because which is smaller depends on how much of the SVG is spaces and quotes. If what you actually need is a preview of the real photograph rather than a grey rectangle, drop it into the blur-up panel underneath.
Technical specifications
| Box size | 1 × 1 up to 4096 × 4096 px, within a total budget of 8,000,000 px; presets for 1200 × 630, 1920 × 1080, 800 × 600, 400 × 400, 300 × 250, 728 × 90 and 150 × 150 |
|---|---|
| Outputs | PNG file, SVG file, SVG data: URI in percent-encoded and base64 form, and a base64 PNG data: URI built on request |
| Size of the default box | The 1200 × 630 grey box with its dimensions on it is 291 bytes of SVG — 414 bytes as a base64 data: URI, 480 percent-encoded; both counts update as you type |
| Label | The pixel dimensions by default, or 64 characters of your own; auto-sized to 28% of the shorter side, shrunk to keep a 7% margin each side, capped at 240 px and floored at 8 px |
| Contrast check | WCAG 2.1 relative luminance between label and background, flagged below 3:1 — the large-text threshold, which the dimension label clears on any box over 86 px tall |
| Transparency | The background takes an alpha channel: the PNG keeps 8 bits of it, the SVG writes fill-opacity, and the contrast reading switches to the color composited over white |
| Blur-up panel | 12 MB input ceiling; output 12, 20 or 32 px wide, encoded twice — WebP at quality 0.5 and JPEG at 0.4, around 300 and 950 bytes respectively at 20 px — with a warning past 1,024 |
| Label typeface | system-ui with a sans-serif fallback: the PNG bakes the glyphs, the SVG resolves the stack on the reader's machine, and neither version fetches a webfont |
Frequently asked questions
Should I inline the data: URI or ship the PNG file?
Inline it whenever the encoded string is under about a kilobyte, which every flat placeholder here is. The 1200 × 630 box is 291 bytes of SVG markup — 414 as base64, 480 percent-encoded — so inlining removes an HTTP request whose headers alone would outweigh the image. The PNG of the same box is a different calculation: base64 adds a third to the file, the string cannot be cached separately from the HTML it lives in, and it is re-downloaded with every page that repeats it. Take the file when something outside a browser has to read it — a README, a Figma frame, an email template that strips data URIs.
Why does my SVG data URI show up as a broken image?
Nine times in ten the xmlns attribute is missing. An inline svg element in the DOM inherits its namespace from the HTML around it, so hand-written markup looks correct on the page and then fails the moment it becomes an image: an SVG loaded through img or background-image is parsed as a standalone XML document, and XML without a namespace is not SVG. The second cause is an unencoded hash — a color written as #e5e7eb inside a CSS url() ends the URI and starts a fragment identifier, leaving the browser a truncated document. Both encodings copied from this page are complete on both counts.
Why does the label look different on my colleague's screen?
Because the SVG names a font stack rather than carrying the glyphs. system-ui resolves to San Francisco on macOS, Segoe UI on Windows and Roboto on most Android builds, and their widths differ enough that a label fitting exactly on one machine is clipped on another — and an SVG loaded as an image has no way to fetch a webfont to settle the argument. The PNG has no such problem, because the glyphs are already pixels by the time the file exists. Export the PNG when the placeholder is headed for a screenshot, a slide or a PDF.
Is this a drop-in replacement for a placeholder service?
No, and the place where a service still wins is worth stating plainly: its output is a URL, so changing 400x300 to 800x600 is two keystrokes in your markup, while here you come back and regenerate the file. What you get in exchange is that the box is no longer a third-party GET fired from every render of the mockup — it cannot be blocked by a proxy that allow-lists domains, it does not send a Referer header naming your staging host, it works with the network off, and it cannot begin returning 404 the day the service is retired. The percent-encoded data URI recovers some of the convenience, since the width, the height and the hex codes stay readable inside the string and can be edited in place.
What is the blur-up panel for, and why 20 px?
It is for the case where the final image already exists and a grey rectangle would be a downgrade: a 20 px-wide copy of the real photograph, inlined in the HTML and blurred up in the slot while the full file arrives — the technique Medium shipped in 2015 that image components have copied ever since. 20 px is the width where the shapes are still recognizable and the string is still cheap, roughly 300 bytes as WebP against roughly 950 as JPEG. That gap is worth understanding rather than guessing at: a JPEG this small is mostly its quantization and Huffman tables, about 600 bytes of fixed header that do not shrink with the picture, so dropping JPEG quality from 0.5 to 0.3 saves around 40 bytes while changing the format saves nearly 700. Below 12 px too little is left to recognize; above 32 px the string passes a kilobyte and costs more than the perceived speed it buys. The averaged color shown beside the preview is the older and cheaper version of the same idea: one hex value behind the slot and no data URI at all.
Can the placeholder be transparent?
Yes — give the background an alpha channel and the PNG keeps it as 8-bit alpha. rgba(15, 23, 42, 0.08) produces the faint tinted block a skeleton screen wants, and the SVG writes it as a fill plus fill-opacity rather than an rgba() fill, so renderers that predate CSS Color 4 still read it correctly. The contrast figure switches to the color composited over white as soon as you do this, because a WCAG ratio is only defined between two opaque colors and a translucent grey over an unknown page is not one.
Why does the label say 1200 × 630 when the image renders at 400 px?
Because the label states the intrinsic size of the file, not the size of the slot it landed in — and that gap is the most useful thing a placeholder can tell you. A box drawn at 1200 × 630 that displays 400 px wide means the layout is downscaling by three, so a real photograph in that slot would be shipping nine times the pixels it needs. Comparing the label against the rendered box is the quickest way to catch a mis-sized image slot while it is still cheap to fix.
About placeholder images
The placeholder has been a hosted service for most of the web's life: placehold.it arrived in 2010, via.placeholder.com and dummyimage.com followed, and the interface they settled on puts the dimensions in the URL path. It is a good interface, and nothing on this page beats it for editing — you change two numbers in the markup and the picture changes with them. What it also is, though, is a third-party GET issued from every render of the mockup. That request carries a Referer header naming your staging host, it fails behind a proxy that allow-lists domains, it fails on a laptop with no network, and it is one DNS change away from turning a design review into a page of broken-image icons. Placeholders have a habit of surviving into production, which quietly promotes a convenience into a dependency nobody reviewed.
For a rectangle with a caption on it, SVG is the right file, and the difference is not marginal: the 1200 × 630 box above is 291 bytes of markup against roughly 5 KB for the same thing as a PNG, and it stays sharp at any zoom because there is nothing in it but a rect and a text node. Two details decide whether it survives becoming a data: URI. The root element has to carry xmlns="http://www.w3.org/2000/svg" — an inline SVG element inherits that namespace from the HTML around it and an image does not — and every # has to be encoded, or a stylesheet reads the color as a fragment identifier and truncates the document. Which encoding comes out smaller is a genuine coin-toss rather than a rule: base64 costs a flat third of the file, while percent-encoding costs three bytes for each space, quote and angle bracket, and markup this terse is nearly half those characters. Both counts are on screen so the choice is measured instead of guessed. Hand-written SVG placeholders with more in them than a rect are worth running through the SVG optimizer first, since the editor metadata is often larger than the drawing.
The one placeholder a remote service structurally cannot produce is the one that looks like your image, because the service has never seen it. That is what the blur-up panel is for: a 20 px-wide copy of the real photograph — near 300 bytes as WebP, three times that as JPEG, because a JPEG that small is mostly the header tables it is obliged to carry — inlined in the HTML and blurred up in the slot while the full file arrives. Where the empty slot is a person rather than a scene, initials on a colored disc read better than any grey rectangle, and that is the avatar generator; where it is an application icon waiting for a real mark, the sizes a browser actually requests come from the favicon generator and the single Windows file from the ICO converter. When a placeholder finally graduates into a real asset, the direction of travel matters: rasterizing this box to a PNG at any scale is a resize, while tracing a bitmap into paths is a different operation entirely, and no amount of resizing turns one into the other.
Where the box is drawn
Every number on this page is worked out by JavaScript running in the tab you are reading it in. Nothing you type, paste or open is uploaded, logged or kept, which is also why the tools carry on working after you disconnect from the network.
The blur-up panel decodes your photograph into a canvas in this tab and reads it back at 20 px wide; the object URL is revoked the moment the image has decoded, and the only thing that outlives the click is the data: URI on your clipboard. Because no placeholder host is contacted, the mockup you are building never announces itself to one in a Referer header either.