TL;DR

This is what we’ll be creating:

This effect is achieved using only one CSS class. The properties needed look like this:

body {
  background-image: radial-gradient(#212121 20%, transparent 20%),
      radial-gradient(#fafafa 20%, transparent 20%);
  background-color: #e53935;
  background-position: 0 0, 50px 50px;
  background-size: 100px 100px;
}

The rest of this post breaks down the CSS and explains how it works. Or you can play with the code in the CodePen example:

See the Pen CSS Polka dot background by Claire (@claireparker) on CodePen.

Step 1 - make a circle

Let’s begin by displaying a single circle.

We use a radial-gradient as a background-image to create a circle pattern. Supply the gradient with two colors that each have identical color-stop values. The color-stops create the sharp border between the two colors, instead of a faded gradient effect. A color-stop can be a percentage between 0% and 100%, where 0 is the centre of the gradient and 100% is the edge.

Give the container element equal height and width to make the circle display nicely. If the element isn’t a square then the circle will appear warped.

body {
    background-image: radial-gradient(#212121 20%, #e53935 20%);
    height: 100px;
    width: 100px;
}

Result:

Note: I’m using the body tag because it’s the simplest tag to demonstrate the effect in a new webpage. This may not be suitable for your use-case, so replace body as necessary with another CSS selector - just don’t forget to give it a height and width.

Step 2 - make the circle repeat

Position the circle image in the top left of the background with the background-position: 0 0 property. The two values represent the x and y coordinates in pixels. We can omit the px value, because in CSS, 0 pixels (or ems, or %, etc) is the same as saying 0.

Give the image a set size of 100px by 100px with the background-size property.

Set the height and width of the body container larger than the background-size so that we can see the repeating effect of our image.

body {
  background-image: radial-gradient(#212121 20%, #e53935 20%);
  background-position: 0 0;
  background-size: 100px 100px;
  height: 200px;
  width: 100%;
}

Result:

Why is the image repeating? We haven’t set anything explicitly in the CSS to do this.

There’s another background-related property called background-repeat, which has an initial value of repeat. This is applied by the browser automatically without us having to do it. This makes the background-image repeat along both the x and y axes. If we were to change this to no-repeat, then we would only see one circle again. Since the containing element is now larger than the 100px by 100px background-image, we can see the circle repeat.

Step 3 - add a diagonal row

We add a second radial gradient to the background-image property by separating them with commas. I’ve given the second gradient a different colour for the circle to make it stand out.

We change the second color of each gradient to transparent, and set the background-color of the element explicitly. This is in order to see the new row of dots - otherwise it would be hidden behind the first one.

Now we have two gradients, we can give them each different background-position values, again separated by commas. By giving the new row values that are half of the background size (50px), we create the diagonal spacing effect.

body {
  background-image: radial-gradient(#212121 20%, transparent 20%),
     radial-gradient(#fafafa 20%, transparent 20%);
  background-color: #e53935;
  background-position: 0 0, 50px 50px;
  background-size: 100px 100px;
  height: 200px;
  width: 100%;
}

Final result:

And there you have it, a polka dot effect created in CSS. You could change the size of the circles, the colors, or even add another row at a different position to create more complex effects.

A note on background and shorthand

The background CSS property is shorthand for multiple background- prefixed properties. You mayb have used other CSS shorthands, such as font, margin or border. In this example, I’ve used individual properties such as background-image and background-color instead of the shorthand. This is because:

  • it’s easier to see what’s happening in the individual properties instead of trying to work out what each value means in background
  • when using shorthand, it’s easy to accidentally overwrite other properties and cause bugs, since you don’t explicitly declare properties (for this reason I always use background-color instead of background)
  • when setting multiple backgrounds it’s easier and not always possible to do so with the shorthand

Sometimes a shorthand can be useful, like margin: 10px 30px 20px 5px, but with less-common ones like font and background, I recommend using individual properties so that you can be sure of what’s happening in your code.