Skip to main content

Backgrounds, Borders & Shadows

Backgrounds, rounded corners, and shadows add visual depth and polish to your designs. This chapter covers every background technique, border rounding, and shadow effect CSS offers.

background-color

The simplest background -- a solid colour:

.card {
background-color: #f5f5f5;
}

Already covered in chapter 4. All colour formats (hex, rgb, hsl, named) work here.

background-image

Load an image as the background:

.hero {
background-image: url("hero.jpg");
}

The image tiles (repeats) by default to fill the element. You almost always need additional properties to control this.

background-size

Controls how the image is scaled:

ValueBehaviour
coverScales to fill the element completely, may crop
containScales to fit inside the element, may leave gaps
100% autoCustom width and height values
.hero {
background-image: url("hero.jpg");
background-size: cover;
}

cover is the most common value. It ensures no gaps and is the equivalent of object-fit: cover for <img> elements.

background-position

Controls where the image is anchored:

.hero {
background-image: url("hero.jpg");
background-size: cover;
background-position: center;
}

Values: center, top, bottom, left, right, or exact values like 50% 30% or 20px 100px.

background-repeat

Controls tiling behaviour:

ValueBehaviour
repeatTile both directions (default)
repeat-xTile horizontally only
repeat-yTile vertically only
no-repeatShow the image once
.hero {
background-image: url("hero.jpg");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}

background-attachment

Controls whether the background scrolls with the page:

ValueBehaviour
scrollBackground scrolls with the element
fixedBackground stays fixed (parallax effect)
localBackground scrolls with the element content
.hero {
background-image: url("hero.jpg");
background-size: cover;
background-attachment: fixed;
}

Note: background-attachment: fixed creates a parallax-like effect but performs poorly on mobile devices. Use it sparingly.

The background shorthand

Combine all background properties in one declaration:

.hero {
background: url("hero.jpg") center / cover no-repeat;
}

The order: image position / size repeat attachment color. The / separates position from size.

Gradients

Gradients are generated images -- you use them with background-image (or the background shorthand), not background-color.

Linear gradients

Create a smooth transition between colours along a line:

.gradient {
background: linear-gradient(to right, #667eea, #764ba2);
}

Directions:

ValueDirection
to rightLeft to right
to bottomTop to bottom
to bottom rightDiagonal
135degAt 135 degrees

Multiple colour stops:

.rainbow {
background: linear-gradient(
to right,
#ff6b6b,
#ffd93d,
#6bcb77,
#4d96ff,
#9b59b6
);
}

Control where each colour starts:

.gradient {
background: linear-gradient(to right, #667eea 0%, #764ba2 50%, #f093fb 100%);
}

Hard colour stops

For sharp transitions instead of smooth blending, place two colours at the same position:

.flag {
background: linear-gradient(
to bottom,
#000 33%,
#dd0000 33%,
#dd0000 66%,
#ffce00 66%
);
}

Radial gradients

Create a circular or elliptical gradient:

.spotlight {
background: radial-gradient(circle, #fff, #333);
}

Control shape, size, and position:

.glow {
background: radial-gradient(circle at 30% 50%, #667eea, transparent 60%);
}

Conic gradients

Rotate colours around a centre point:

.color-wheel {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
}

Multiple backgrounds

An element can have multiple backgrounds, separated by commas. They stack on top of each other -- the first one is on top:

.layered {
background:
linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.7)),
url("hero.jpg") center / cover no-repeat;
}

This is a common pattern: a dark gradient overlay on top of an image, making white text readable on any photo.

border-radius

Rounds the corners of an element:

.card {
border-radius: 8px;
}

A single value rounds all four corners equally.

Individual corners

.card {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}

Shorthand (clockwise from top-left):

.card {
border-radius: 8px 8px 0 0;
}

Circles and pills

.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
}

.pill {
padding: 6px 16px;
border-radius: 9999px;
}

50% on a square element creates a circle. A very large value like 9999px creates a pill shape on rectangular elements.

box-shadow

Adds a shadow behind an element:

.card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

The syntax: offset-x offset-y blur-radius spread-radius colour.

ParameterWhat it does
offset-xHorizontal offset (positive = right)
offset-yVertical offset (positive = down)
blur-radiusHow blurry the shadow is (larger = softer)
spread-radiusExpands or shrinks the shadow (optional)
colourShadow colour (usually semi-transparent)

Common shadow presets

/* Subtle elevation */
.shadow-sm {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

/* Medium elevation */
.shadow-md {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

/* Large elevation */
.shadow-lg {
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}

/* Elevated on hover */
.card:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.2);
}

Multiple shadows

Stack multiple shadows for more realistic depth:

.card {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 4px 8px rgba(0, 0, 0, 0.06);
}

Inset shadows

Add the inset keyword for an inner shadow:

.input-field {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
}

text-shadow

Adds a shadow behind text:

h1 {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

Syntax: offset-x offset-y blur-radius colour.

.neon {
color: #fff;
text-shadow:
0 0 10px #fff,
0 0 20px #ff00de,
0 0 40px #ff00de;
}

outline

Outlines are drawn outside the border and do not affect layout:

button:focus {
outline: 2px solid #4a90d9;
outline-offset: 2px;
}

Unlike borders, outlines do not affect the element's size or position. They are primarily used for focus indicators (accessibility).

Note: Never remove focus outlines (outline: none) without providing an alternative focus style. Focus indicators are essential for keyboard navigation.

Practical example

A polished card component combining everything:

.card {
max-width: 360px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
background-color: white;
transition: box-shadow 0.2s ease;
}

.card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.card-image {
width: 100%;
height: 200px;
background: linear-gradient(to bottom, transparent 60%, rgba(0, 0, 0, 0.4)),
url("photo.jpg") center / cover no-repeat;
}

.card-body {
padding: 20px;
}

.card-body h3 {
margin: 0 0 8px;
font-size: 1.25rem;
}

.card-body p {
margin: 0;
color: #666;
}

What you learned

  • background-image with background-size: cover fills elements with images
  • Linear, radial, and conic gradients create smooth colour transitions
  • Multiple backgrounds stack on top of each other
  • border-radius rounds corners; 50% makes circles; large values make pills
  • box-shadow adds depth; stack multiple shadows for realism; use inset for inner shadows
  • text-shadow adds depth behind text
  • Outlines are for focus indicators and do not affect layout

Next step

Static styles are powerful, but movement brings interfaces to life. The next chapter covers transitions and animations -- how to smoothly change CSS values over time.