CSS Background Image Generator
Add your image, click the part that must stay in view, and see how it crops on desktop, tablet and phone. Add a darkening overlay for text, a placeholder colour and retina or AVIF/WebP versions, then copy the CSS.
Click the part that must stay in view
1600×900px image. This becomes background-position: 72% 30%.
How it crops
Shows 100% of the width, 67% of the height
Shows 77% of the width, 100% of the height
Shows 34% of the width, 100% of the height
.hero {
background-color: #64748B;
background-image: linear-gradient(to top, rgb(2 6 23 / 60%), rgb(2 6 23 / 0%) 70%),
url("/images/hero.jpg");
background-size: 100% 100%, cover;
background-position: 0 0, 72% 30%;
background-repeat: no-repeat, no-repeat;
}cover, contain and auto
| Value | What it does | Use it for |
|---|---|---|
| cover | Scales until both sides are filled; the overflow is cropped | Hero banners, full-bleed photos |
| contain | Scales until the whole image fits; leaves empty bands | Logos, diagrams, product shots |
| auto | The image's own pixel size | Tiles and textures |
| 400px auto | Fixed width, height in proportion | Patterns at a set scale |
With cover the browser picks the larger of the two scale factors. Take the 1600×900 sample in a 390×640 phone box: across it needs 390 ÷ 1600 = 0.244, down it needs 640 ÷ 900 = 0.711. It uses 0.711, so the image is drawn 1,138×640 and only 34% of its width fits on screen. The same image in the 1280×480 desktop hero uses 1280 ÷ 1600 = 0.8 and shows the full width but 67% of the height. One image, two very different crops, which is what the three previews above show.
Keeping the subject in frame
background-position percentages do not move the image by that amount. They line up a point on the image with the same point on the box: 72% 30% puts the spot 72% across and 30% down the image exactly 72% across and 30% down the box. The offset works out as:
offset = (box size − drawn image size) × percentageIn the phone example the image is 748px wider than the box, so 72% shifts it 748 × 0.72 = 539px left. The useful consequence: if the percentages are the subject's own position in the image, the subject stays inside the box at every screen size. That is why this tool asks you to click the subject rather than choose "left" or "center". Keywords are shortcuts for the same thing: left is 0%, center 50%, right 100%.
Overlays and layer order
background-image takes a comma-separated list and paints the first item on top. The overlay is listed first so it covers the photo; a linear-gradient() with the same colour at both ends is the usual way to write a flat tint, because CSS has no plain "colour layer" except background-color, which is always at the bottom.
Every other background property can take one value per layer, in the same order. That is why the export writes background-size: 100% 100%, cover: the overlay always fills the box while the photo is cropped, and with a pixel size or tiling the overlay still covers everything. A single value is simply reused for every layer.
The background: shorthand packs a layer into one line: image, position, then / and size, then repeat and attachment, with the colour allowed only in the last layer. One detail trips people up: a single box keyword there sets both background-origin and background-clip. To clip at the padding while keeping the default origin, the shorthand needs two boxes, padding-box padding-box, which is what the generator writes. Longhands avoid the question, and a later shorthand anywhere in your CSS resets every longhand, so pick one style per element.
For text, a bottom fade usually beats an even tint: it darkens only where a caption sits and leaves the rest of the photo bright. Check the text against the darkest and lightest parts of the photo under it, not against the overlay colour alone.
Fixed backgrounds and parallax
background-attachment: fixed pins the image to the window, so content scrolls over it. It is the classic one-line parallax, with two catches. Safari on iPhone and iPad ignores it and scrolls the image normally, and with fixed the image is sized against the whole window rather than the element, so cover crops much more than the preview suggests on a short banner. local is the rarer option: it scrolls the background along with the element's own scrolling content.
When an image should not be a background
Screen readers do not announce background images, there is no alt text, and they disappear in Windows high-contrast mode and in most "print without backgrounds" settings. That is fine for decoration: textures, a mood photo behind a heading. If the picture carries information (a product, a person, a chart), use <img alt="…"> and style it with object-fit instead.
When the image does not show
| Symptom | Cause | Fix |
|---|---|---|
| Nothing at all | The element has no height; backgrounds never create any | Give it a height, min-height or aspect-ratio |
| 404 in the Network tab | Relative paths resolve from the CSS file, not the page | Use a root path such as /images/hero.jpg |
| Image tiles | repeat is the default | background-repeat: no-repeat |
| Subject cut off on phones | cover crops the sides on tall boxes | Set the position to the subject's percentages |
| Settings lost | A later background: shorthand resets every longhand | Use longhands, or put the shorthand first |
Frequently asked questions
How do I make a background image cover the whole page?
Put it on body with background-size: cover and background-attachment: fixed (desktop), or on a full-height wrapper with min-height: 100vh. On phones, a wrapper element works more reliably than fixed.
Can I set the opacity of a background image only?
Not directly. Either lay a semi-transparent overlay of the page colour on top (as this tool does with Even tint), or put the image on a ::before pseudo-element and give that pseudo-element opacity.
Should I write url() with quotes?
Quotes are optional unless the path contains spaces, brackets or quotes. The generator always adds them, and escapes any quotes inside the path.
What is the difference between background-image and background?
background is a shorthand that sets image, size, position, repeat, attachment, origin, clip and colour together, and resets any you leave out. The generator writes longhands so each can be changed on its own later.
How big should a hero background image be?
Wide enough for the largest box it fills times the screen density: a 1280px hero needs 1280px for 1× screens and 2560px for 2×. Serve smaller files to phones with image-set() or media queries, and compress AVIF or WebP versions.
Why does my image look blurry?
cover or a large box is scaling it up past its own size. Check the drawn size in the previews above; if it is bigger than the image, use a larger source or a 2× version.
Sources
- W3C: CSS Backgrounds and Borders Module Level 3: layers, background-size, background-position percentages and attachment
- MDN: background-size: cover, contain and per-layer values
- MDN: background-position: how percentages align the image and the box
- MDN: image-set(): resolution and type() options, browser support
- MDN: background-attachment: fixed and local; iOS Safari behaviour in the compatibility data
- web.dev: Optimize Largest Contentful Paint: why CSS background images are discovered late
- W3C WAI: Decorative images: when an image can be decoration
Related Tools
Build and preview common CSS Grid layout patterns.
Build linear and radial gradients with custom color stops.
Remove, replace, and export image metadata.
Generate and inspect solid background-color declarations.
Generate uniform or side-specific CSS border declarations.
Generate uniform, corner, and elliptical border-radius CSS.