CSSBeginner

CSS Backgrounds, Gradients, Borders, Rounded Corners and Shadows

Decorate boxes with background colors, gradients and images, borders, border-radius and box-shadow, and build a polished profile card step by step.

All CSS lessons

What you will learn

Now that you can size and space boxes, it is time to make them look good. In this lesson you will learn how to paint the background of a box (with a colour, a gradient or an image), how to draw and round borders, and how to add depth with shadows. At the end you will combine everything into a real profile card, the kind of component you see on every modern website.

The HTML we will style

The practice page has three things to decorate. Find each class in the code:

<h1 class="page-title">Style Lab</h1>

<!-- A banner with a gradient background -->
<div class="hero">
  <h2 class="hero-title">Welcome to my site</h2>
</div>

<!-- A box with a tiled background pattern -->
<div class="pattern">Tiled pattern</div>

<!-- A profile card: border, rounded corners and shadow -->
<div class="card">
  <div class="avatar">A</div>
  <h2 class="card-title">Aisha Khan</h2>
  <p class="card-text">Front-end learner. Loves CSS.</p>
  <button class="btn">Follow</button>
</div>
Selector Matches this element Decorated with
body the whole page a light grey background
.hero the banner <div> a gradient background
.hero-title the <h2> inside the banner (text only)
.pattern the <div> with “Tiled pattern” a repeating background
.card the outer <div> of the profile card border, rounded corners, shadow
.avatar the round <div> with the letter A a circle made with border-radius
.card-title, .card-text the <h2> and <p> inside the card text colours
.btn the <button> a pill-shaped button

Backgrounds

You already know background-color. There is a whole family of background- properties, and they all paint behind the content of the element (across the content and the padding, and beneath the border).

background-color

/* the <body>: styles the whole page */
body {
  background-color: #f3f4f6;
}

background-image: gradients

A gradient is a smooth blend between colours, drawn by the browser. It counts as an image, so it goes in background-image. No image file is needed.

/* the <div class="hero"> */
.hero {
  background-image: linear-gradient(to right, royalblue, purple);
  color: white;
  padding: 40px 20px;
  text-align: center;
}

linear-gradient(direction, color, color, ...):

  • The direction can be a keyword (to right, to bottom, to bottom right) or an angle (45deg, 180deg). If you skip it, the default is to bottom.
  • After the direction come two or more colours, blended in order.
  • You can add stops (positions) to control where colours change:
.hero {
  background-image: linear-gradient(to right, gold 0%, tomato 50%, purple 100%);
}

Two colour stops at the same position give a hard edge instead of a blend:

.hero {
  background-image: linear-gradient(to right, gold 50%, tomato 50%);
}

There is also radial-gradient(), which blends outward from a centre point:

.hero {
  background-image: radial-gradient(circle, gold, tomato);
}

background-image: pictures

To use a picture, write url() with the path to the image file:

.hero {
  background-color: #333;
  background-image: url("images/banner.jpg");
}
  • The path in url() is relative to the CSS file, not to the HTML file.
  • Always set a background-color too. It shows while the image loads and if the image fails.
  • Use a background image for decoration. If the picture carries meaning (a product photo, a diagram), use an HTML <img> with alt text instead.

In the editor: you have no image files, so practise with gradients. The rules for repeat, position and size below work the same for both.

background-repeat

By default a background image repeats (tiles) to fill the box.

  • repeat tiles in both directions (the default)
  • no-repeat shows it once
  • repeat-x and repeat-y tile in one direction only

background-size

  • cover scales the image to fill the whole box, cropping the edges if needed. Great for banners.
  • contain scales the image to fit entirely inside the box, which may leave empty space.
  • A length, like 40px 40px, sets an exact size.

background-position

Where the image sits in the box: keywords like center, top, bottom left, or lengths and percentages.

A good trick for practising without image files is to make a tiny gradient tile and repeat it:

/* the <div class="pattern"> */
.pattern {
  background-image: linear-gradient(45deg, gold 50%, tomato 50%);
  background-size: 40px 40px;
  background-repeat: repeat;
  padding: 40px;
  color: black;
  font-weight: bold;
  margin: 20px 0;
}

The gradient is a 40px by 40px tile, split diagonally between gold and tomato, and the browser repeats it to fill the box. Change the background-size to 20px 20px to see the pattern get finer.

A dark overlay on a photo

You can list more than one background, separated by commas. The first one is on top. That makes the classic “darkened photo behind white text” easy:

.hero {
  background-image:
    linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
    url("images/banner.jpg");
  background-size: cover;
  background-position: center;
  color: white;
}

The background shorthand

You can combine the properties into one line:

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

Here center / cover means “position / size”. The shorthand resets any background property you do not mention, so be careful when mixing it with individual properties: write the shorthand first, and the individual ones after it.

Borders

You met the border shorthand in the box model lesson: width, style and colour.

.card {
  border: 1px solid #dddddd;
}

Border styles

These are alternatives, so in the editor try one line at a time on the .card:

.card { border: 3px solid black; }      /* a solid line */
.card { border: 3px dashed black; }     /* dashes */
.card { border: 3px dotted black; }     /* dots */
.card { border: 6px double black; }     /* two lines (needs at least 3px) */
.card { border: none; }                 /* no border at all */

One side at a time

.card-title {
  border-bottom: 2px solid royalblue;
}

The four sides are border-top, border-right, border-bottom and border-left. A single underline like this is very common under headings.

border-radius: rounded corners

border-radius rounds the corners of a box. It works even without a visible border, because it also clips the background.

/* the <div class="card"> */
.card {
  border-radius: 16px;
}

More things you can do:

  • Different corners: with four values, the order is top-left, top-right, bottom-right, bottom-left (clockwise, like padding).
.card {
  border-radius: 20px 20px 0 0;   /* rounded on top, square at the bottom */
}
  • A circle: give an element the same width and height, then a radius of 50%:
/* the <div class="avatar"> */
.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background-color: royalblue;
  color: white;
  text-align: center;
  line-height: 80px;   /* quick trick to centre the letter vertically */
  font-size: 36px;
  margin: 0 auto 12px;
}
  • A pill shape: a very large radius, such as 999px, rounds the ends of a wide box completely. It is perfect for buttons:
/* the <button class="btn"> */
.btn {
  padding: 10px 24px;
  border: none;
  border-radius: 999px;
  background-color: seagreen;
  color: white;
}

Outline is different: outline looks like a border, but it takes up no space and does not follow box-sizing. Browsers use it for the focus ring when you tab to a button or link. Never remove it (outline: none) unless you replace it with a clear focus style, because keyboard users need it.

box-shadow: adding depth

A shadow makes a box look like it floats above the page.

/* the <div class="card"> */
.card {
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

The values, in order:

box-shadow: 0   8px   20px   rgba(0,0,0,0.12);
            |   |     |      |
            |   |     |      +-- colour
            |   |     +--------- blur: how soft the edge is
            |   +--------------- vertical offset (positive = down)
            +------------------- horizontal offset (positive = right)

There is an optional fourth length (spread) after the blur, which makes the shadow bigger or smaller. Notes:

  • Use a semi-transparent black (rgba(0, 0, 0, 0.1) to 0.2). Solid dark shadows look heavy and old-fashioned.
  • Words like inset at the start put the shadow inside the box.
  • You can layer several shadows by separating them with commas.
  • A shadow takes no space and does not push other elements away.
  • text-shadow works the same way, but for text: text-shadow: 2px 2px 4px gray;
.btn {
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

.card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 10px 30px rgba(0, 0, 0, 0.1);
}

Putting it together: the profile card

Here is the finished stylesheet for the practice page. Compare each rule with the mapping table above.

/* the page */
body {
  background-color: #f3f4f6;
  font-family: Arial, Helvetica, sans-serif;
}

/* the gradient banner */
.hero {
  background-image: linear-gradient(to right, royalblue, purple);
  color: white;
  padding: 40px 20px;
  text-align: center;
  border-radius: 12px;
}

/* the tiled box */
.pattern {
  background-image: linear-gradient(45deg, gold 50%, tomato 50%);
  background-size: 40px 40px;
  padding: 40px;
  margin: 20px 0;
  font-weight: bold;
}

/* the profile card */
.card {
  width: 280px;
  padding: 24px;
  text-align: center;
  background-color: white;
  border: 1px solid #dddddd;
  border-radius: 16px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

.avatar {
  width: 80px;
  height: 80px;
  margin: 0 auto 12px;
  border-radius: 50%;
  background-color: royalblue;
  color: white;
  font-size: 36px;
  line-height: 80px;
}

.card-title {
  margin: 0 0 4px;
  padding-bottom: 8px;
  border-bottom: 2px solid royalblue;
}

.card-text {
  color: gray;
}

.btn {
  padding: 10px 24px;
  border: none;
  border-radius: 999px;
  background-color: seagreen;
  color: white;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

Common mistakes

  • Putting a gradient in background-color. Gradients are images, so use background-image (or the background shorthand).
  • Forgetting the border style. border: 2px red shows nothing. It needs solid.
  • A circle that is an oval. border-radius: 50% only makes a circle if width and height are equal.
  • A wrong url() path. It is relative to the CSS file, so a file in css/ needs ../images/banner.jpg.
  • Skipping the fallback background-color behind a background image.
  • Overusing shadows and gradients. One soft shadow looks professional. Five hard ones look messy.
  • Using the background shorthand after individual properties. It resets them.
  • Removing outline on focus without giving keyboard users a replacement.
  • Poor contrast between text and a gradient or image behind it. Add an overlay if needed.

Practice

  1. Click Practice in Editor. Change the .hero gradient to to bottom, then to 135deg, then give it three colours.
  2. Change the .pattern tile size to 20px 20px, and change the two colours. What happens to the pattern?
  3. Build the .card step by step: first a white background and padding, then a 1px border, then border-radius: 16px, and finally the box-shadow. Look at each change on its own.
  4. Turn .avatar into a circle. Then make it a rounded square instead by changing only the radius.
  5. Make the .btn a pill. Then make a second button that has a 2px solid border and a transparent background.
  6. Give the card a top-only rounded corner with four border-radius values.
  7. Add a background image of your own on your computer using url(), together with background-size: cover and a dark overlay gradient.

Recap

  • background-color, background-image, background-repeat, background-size and background-position control what is painted behind a box.
  • A gradient (linear-gradient, radial-gradient) is an image made by CSS, so it goes in background-image.
  • For photos use url() (relative to the CSS file), background-size: cover and a fallback background-color.
  • The first background in a comma-separated list is on top, which makes dark overlays easy.
  • border needs width, style and colour. border-radius rounds corners: 50% on a square makes a circle, and 999px makes a pill.
  • box-shadow: x y blur colour adds depth. Keep shadows soft, using semi-transparent colours.
  • You have finished CSS Getting Started.