Command Palette

Search for a command to run...

Hectal
PHASE 5Beginner ~20 min· topic 8 of 8

Topic 5.8

Backgrounds and Gradients

In one line

Every box can paint a background colour plus any number of image layers, which you size, position and repeat; gradients are images the browser draws for you, in straight lines, circles or around a point.

Think of it like this

Decorating a wall. First you paint it one colour (background-color). Then you can hang posters on top (background-image), choose how big each poster is (background-size), where it hangs (background-position), and whether you tile the same poster across the whole wall like wallpaper (background-repeat). You can hang several posters, one on top of another.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

background-color
One colour that fills the box, painted under every background image.
background-image
One or more images painted on top of the background colour.
background-size
How big each background image is drawn. cover fills the box; contain fits inside it.
background-position
Where the background image sits inside the box.
background-repeat
Whether the image tiles across the box, and in which directions.
Gradient
An image the browser draws by blending colours, in a line, a circle or around a point.
Colour stop
A colour plus the position where it's reached in a gradient, like red 30%.
Layer
One of several stacked backgrounds. The first one listed is drawn on top.

Step by step

01Paint a colour

Start with a fallback colour. Everything else sits on top of it.

style.csswhole filecss
.hero {
  background-color: #1e1b4b;
  color: white;
}

02Add an image and size it

A photo that always fills the hero, cropped as needed, centred so the middle of the picture stays visible on every screen.

style.csswhole filecss
.hero {
  background-color: #1e1b4b;
  background-image: url("mountains.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

03Layer a gradient for readable text

White text on a busy photo is hard to read. Put a dark, semi-transparent gradient on top of the photo: it's listed first.

style.csswhole filecss
.hero {
  background:
    linear-gradient(rgb(0 0 0 / 0.6), rgb(0 0 0 / 0.1)),
    url("mountains.jpg") center / cover no-repeat,
    #1e1b4b;
}
Layer a gradient for readable textdiagram
Rendering diagram…

04Draw with gradient stops

Repeating the same position for two colours makes a hard line. This makes 10px stripes with no image file at all.

style.csswhole filecss
.stripes {
  background: repeating-linear-gradient(
    45deg,
    #fde68a 0 10px,
    #fef3c7 10px 20px
  );
}

05Make a pie chart with conic-gradient

Each slice starts where the last ended. 0 as a start means "right after the previous stop".

style.csswhole filecss
.pie {
  width: 160px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#6366f1 0 40%, #ec4899 0 70%, #f59e0b 0);
}

Try it yourself

  1. 1

    Swap the layer order

    In the first example, move the gradient line above the url(...) line. Predict what happens to the mountain icon (it's now underneath the gradient, hidden).

  2. 2

    Tile the icon

    Change no-repeat to space in the first example. Predict how the icons are arranged, then run.

  3. 3

    Add a slice

    In the conic pie, change it to four slices: #6366f1 0 25%, #ec4899 0 50%, #f59e0b 0 75%, #10b981 0.

Code & diagrams

Layers, size, position and repeat New tab

Three layers: the icon, the gradient, and a last layer with no image, only the colour. Each comma-separated value belongs to one layer, in order; `48px` alone means 48px wide with an `auto` height.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

repeat: no-repeat, repeat, repeat
size: 48px auto, auto, auto
colour layer: rgb(79, 70, 229)
Linear, radial, conic and repeating gradients New tab

No image files at all: every pattern is drawn by the browser from the gradient functions.

Preview

Press Run to see the page.

Console

Nothing logged yet.
cover vs contain New tab

The square image in a wide box: `cover` scales it to 200px wide and crops it; `contain` scales it to 120px tall and leaves space at the sides.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

The shorthand that erases your colour

Write background-color: navy; and, later in the same rule, background: url("stars.png");.

terminal
$ the page shows
── what you'll see ──
If stars.png fails to load or has transparent areas, the box is transparent, not navy

Break #2

Colour in the wrong layer

Write background: navy, linear-gradient(red, blue);.

terminal
$ DevTools → Styles
── what you'll see ──
The declaration is crossed out as invalid and no background is applied

Myth vs fact

Myth

Gradients are slow because they're images.

Fact

They need no download and scale to any size without blurring. Very large or animated gradients cost some paint time, but a static gradient is usually cheaper than an image file.

Myth

The first background listed is at the bottom.

Fact

It's the opposite: the first is on top, like the first card in a stack you look down on. The colour is always the bottom layer.

Myth

Background images are fine for any picture.

Fact

Screen readers ignore them and they can't have alt text. Use <img> for pictures that carry meaning and keep backgrounds for decoration.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Gradients interpolate colours in sRGB by default, which can give muddy greys between complementary colours. Modern browsers support choosing a colour space: linear-gradient(in oklch, blue, yellow) gives brighter, more even blends.

  • ▸

    background-attachment: fixed (parallax-style) forces a repaint on every scroll in many browsers and is ignored on iOS Safari. Prefer a fixed-position pseudo-element or scroll-driven animations for the effect.

  • ▸

    image-set("hero.avif" type("image/avif"), "hero.jpg" type("image/jpeg")) lets the browser choose a format or resolution for a background image, like srcset does for <img>.

  • ▸

    Gradient borders with rounded corners: border: 3px solid transparent; background: linear-gradient(white, white) padding-box, linear-gradient(135deg, #6366f1, #ec4899) border-box; paints the white layer only inside the padding and the gradient under the border.

Remember this

  1. 1

    background-color fills the box with one colour. It's always the bottom layer, under every image. background-image adds one or more images on top: url("photo.jpg") loads a file, and gradient functions (below) make one. Images that fail to load show the colour underneath, so always set a colour too, especially behind text, so it stays readable.

  2. 2

    background-repeat decides whether an image tiles: repeat (default, both directions), repeat-x, repeat-y, no-repeat, plus space (tiles with even gaps, never cut) and round (tiles stretched so a whole number fit). background-position places it: keywords like center or right bottom, lengths or percentages (25% 75%), or offsets from an edge (right 16px bottom 16px). A percentage position lines up that point of the image with the same point of the box, so 100% 100% puts the image's bottom-right corner in the box's bottom-right corner.

  3. 3

    background-size sets how big each image is: a length (40px 40px), a percentage of the box, cover (scale to cover the whole box, cropping what doesn't fit) or contain (scale to fit entirely inside, maybe leaving empty space). cover is the usual choice for hero photos, contain for logos. By default the image is positioned relative to the padding box (background-origin: padding-box) and painted under the border too (background-clip: border-box); change these to paint only the content area, or to clip the background to the text with background-clip: text.

  4. 4

    A gradient is an image of colours blending into each other, drawn by the browser at any size with no download. linear-gradient(to right, #6366f1, #ec4899) blends along a straight line (direction as to right or an angle like 135deg). radial-gradient(circle at top left, gold, transparent 60%) spreads out from a point as a circle or ellipse. conic-gradient(red 0 25%, gold 0 50%, …) sweeps around a centre like clock hands, perfect for pie charts. Each colour can have a stop position; two colours at the same position make a hard edge instead of a blend, which is how you draw stripes. repeating-linear-gradient and friends repeat the pattern.

  5. 5

    Multiple backgrounds are separated by commas, and the first one listed is on top. Each layer can have its own size, position and repeat (also comma-separated, in the same order). The colour can only go in the last layer. The background shorthand combines everything: background: url("icon.svg") right 12px center / 20px no-repeat, linear-gradient(#fff, #f1f5f9); (the size comes after the position, separated by a /). Note that the shorthand resets every background property you don't mention, which can quietly undo an earlier background-color.

  6. 6

    Decorative images belong in CSS backgrounds; meaningful images (a product photo, a chart someone needs to read) belong in HTML <img> with alt text, because screen readers ignore CSS backgrounds. Large background photos should be compressed and sized for the screen (with image-set() for different resolutions), since background images can't use loading="lazy" the way <img> can.

Explain it without notes

01

How do multiple backgrounds stack, and where does the background colour go?

02

What's the difference between background-size: cover and contain?

03

Name the three gradient types and a good use for each.

04

Why might background: url(...) undo a background-color you set earlier?

05

When should an image be an <img> instead of a CSS background?

Practice

01

Make a 300×100 .bar with a left-to-right gradient from #22c55e to #0ea5e9 and a fallback colour #22c55e. Log its computed background-image.

02

Make a progress pie that is 70% filled using conic-gradient, 120px wide and round. Log its computed border-radius.

Trade-offs

  • ↔

    CSS gradients cost no download and scale perfectly, but complex illustrations are easier to maintain as SVG files.

  • ↔

    Background images are easy to layer and position, but they're invisible to assistive technology and can't be lazy-loaded natively; <img> with object-fit gives similar cropping with better semantics.

Done when you can

  • I can set background colour, image, size, position and repeat.

  • I can choose between cover and contain.

  • I can write linear, radial and conic gradients with colour stops and hard edges.

  • I can stack several backgrounds and know which is on top.

  • I can use the background shorthand without losing the colour.

  • I know when to use <img> instead of a CSS background.