How to Create a Chessboard Pattern in CSS

In this article, you will learn how to create a Chessboard pattern in pure CSS. We will only use HTML and CSS, even for the Chess pieces.

We will show you three different approaches to creating a chessboard. Each method has its pluses and minuses, but they all offer something valuable to learn.

If you want to take a peek at the end result, scroll to the bottom.

I strongly recommend you open Codepen and follow along with this tutorial.

Let’s go.

Setting up the Chessboard

Before laying out the black and white squares, let’s give some basic styling to the chessboard.

Here’s the HTML —

HTML
<div class="chessboard">
  <!-- Black and white squares go here -->
</div>

Here’s the CSS for styling the chessboard:

CSS
body {
  background: hsla(36, 70%, 70%, 0.25); /* light sepia */
}

/* basic styling of the chessboard */
.chessboard {
  width: 400px;
  aspect-ratio: 1;
  margin: auto; /* center horizontally */
  box-shadow: 5px 5px 2px 2px hsla(0, 40%, 20%, 0.5);
  padding: 40px;
  border: 1px solid #ccc;
  border-radius: 20px;
  background-color: #eee;
  border-radius: 20px;
  background-color: #eee;
}

Pasting these styles into the Codepen editor will give you a plain whitish card on a sepia background. This card will be our Chessboard on which we will draw black and white squares.

1. Brute force approach

The first method is what I call the brute-force method. You create 8 rows of 8 square elements each. And you give each individual square a class of either black or white to achieve the desired checkered pattern. And then you style the black and white squares using the background-color property.

This is what is looks like:

HTML
<!-- Row 1 -->
<div class="row">
  <div class="white"></div>
  <div class="black"></div>
  <!-- Remaining 6 squares -->
</div>

<!-- Row 2 -->
<div class="row">
  <div class="black"></div>
  <div class="white"></div>
  <!-- Remaining 6 squares -->
</div>

<!-- 6 more rows -->

This will be our CSS:

CSS
.row {
  display: flex;
}

/* Squares */
.row div {
  flex-grow: 1; /* Expand to cover the row width*/
  aspect-ratio: 1; /* width = height */
}

/* paint individual squares */
.black {
  background-color: #777;
}

.white {
 background-color: #ddd;
}

This will be your output:

<div class="chessboard">
  <div class="row">
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
  </div>
  <div class="row">
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
  </div>
  <div class="row">
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
  </div>
  <div class="row">
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
  </div>
  <div class="row">
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
  </div>
  <div class="row">
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
  </div>
  <div class="row">
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
  </div>
  <div class="row">
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
    <div class="black"></div>
    <div class="white"></div>
  </div>
</div>
body {
	background: hsla(36, 70%, 70%, 0.25);
}

.chessboard {
	width: 400px;
	aspect-ratio: 1;
	margin: auto;
	box-shadow: 5px 5px 2px 2px hsla(0, 40%, 20%, 0.5);
	padding: 40px;
	border: 1px solid #ccc;
	border-radius: 10px;
  background-color: #eee;
}

.row {
	display: flex;
}

.row div {
  flex-grow: 1;
	aspect-ratio: 1;
}

.black {
	background-color: #777;
}

.white {
	background-color: #ddd;
}

This approach works but it isn’t the most elegant one. You are manually labeling all 64 squares with their own classes. We can do better.

2. CSS Chessboard using gradient

This approach is not necessarily better than the previous one. It’s just another way of creating a chessboard pattern. However, this approach does require less HTML code.

The squares on a chessboard have a pattern: they can be thought of as 32 identical pairs of black-and-white squares.

Also read: CSS Margins (An Ultimate Guide)

So, we could create a linear gradient that resembles a pair of squares and then repeat it intelligently to mimic the chessboard.

For example, the following lines will create a pair of black and white squares:

HTML
<div></div>
CSS
body {
  background: gold; /* to make white square visible */
}

div {
  width: 100px;
  height: 50px;
  background: linear-gradient(
    to right,
    white,
    white 50px,
    black 50px,
    black 100px
  );
}

You will see this black-and-white pattern (ignore the yellow background):

How to Create a Chessboard Pattern in CSS

All we have to do now is repeat it throughout the chessboard. Thankfully, we have a property called repeating-linear-gradient for exactly this scenario:

CSS
div {
  background: repeating-linear-gradient(
      to right,
      white,
      white 50px,
      black 50px,
      black 100px
  );
}

Let’s now take a step back and understand what’s happening here: — we are creating the square pattern using CSS. Every row of the chessboard can be created with just the repeating-linear-gradient property we discussed above.

That means we don’t need to create any divs for squares in our HTML code. Eight divs for 8 rows will suffice for our purpose:

HTML
<div class="chessboard">
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
</div>

If you take a look at a chessboard, you will find that the odd rows in a chessboard have a white-black-white pattern whereas the even rows have a black-white-black pattern.

How to Create a Chessboard Pattern in CSS

You can create both these rows using the same repeating-linear-gradient declaration. On odd-numbered rows, the pattern will repeat from left to right whereas on even-numbered rows, it will go from right to left.

CSS
/* Odd rows */
.row:nth-child(odd) {
	background: repeating-linear-gradient(
		to right,
		white,
		white 50px,
		black 50px,
		black 100px
	);
}

/* Even rows */
.row:nth-child(even) {
	background: repeating-linear-gradient(
		to left,
		white,
		white 50px,
		black 50px,
		black 100px
	);
}

You will see this white-and-black pattern (ignore the yellow background):

How to Create a Chessboard Pattern in CSS

All we have to do now is repeat it throughout the chessboard. Thankfully, we have a property called repeating-linear-gradient for exactly this scenario:

CSS
div {
  background: repeating-linear-gradient(
      to right,
      white,
      white 50px,
      black 50px,
      black 100px
  );
}

Let’s now take a step back and understand what’s happening here:

We are creating the square patterns using CSS, so we don’t need to create individual divs in our HTML code. Eight divs for 8 rows will suffice for our purpose:

HTML
<div class="chessboard">
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
  <div class="row"></div>
</div>

After throwing in a few basic styles, this will be your output:

<div class="chessboard">
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
	<div class="row"></div>
</div>
body {
	display: flex;
	height: 100vh;
	background: hsla(36, 70%, 70%, 0.25);
}

.chessboard {
	width: 400px;
	aspect-ratio: 1;
	display: flex;
	flex-direction: column;
	margin: auto;
	box-shadow: 5px 5px 2px 2px hsla(0, 40%, 20%, 0.5);
	padding: 40px;
	border: 1px solid #ccc;
	border-radius: 20px;
	background: #eee;
}

.row {
	flex-grow: 1;
}

.row:nth-child(odd) {
	background: repeating-linear-gradient(
		to right,
		white,
		white 50px,
		black 50px,
		black 100px
	);
}

.row:nth-child(even) {
	background: repeating-linear-gradient(
		to left,
		white,
		white 50px,
		black 50px,
		black 100px
	);
}

This approach works but I don’t like it for two reasons:

  1. This is semantically wrong. We don’t have individual squares to place our chess pieces. Should we decide to implement a full-fledged chess game with this UI, it would be a nightmare to write code for placing those pieces at appropriate ‘squares’ in the running game.
  2. This approach isn’t dynamic. Remember, we had to manually set the breakpoints in the repeating-linear-background property.
How to Create a Chessboard Pattern in CSS

If you decide to change the dimensions of the chessboard later on, you will have to manually adjust these breakpoints once again.

We have another approach, which is better than both of these two.

3. Chessboard with the ‘:nth-child’ selector

In this approach, we again create a chessboard with 8 rows of 8 squares. This is the HTML for this approach:

HTML
<div class="row">
	<div class="square"></div>
	<div class="square"></div>
	<!-- 6 more such squares -->
</div>

<div class="row">
  <!-- 8 squares -->
</div>

<!-- 6 more such rows --> 

If you use Emmet, generating this HTML is a piece of cake:

(.row>.square*8)*8  (Press Tab)

With the HTML out of the way, it’s time to focus on the CSS part.

Apart from the basic styling, we have to discover a way to intelligently assign black and white colors to these squares.

As I discussed in the above method, the chessboard has a pattern:

Create a chessboard pattern in CSS

This pattern can be summarized in the following points:

  1. Odd rows’ odd squares are white.
  2. Even rows’ even squares are white.

This can be translated to CSS like this:

CSS
/* White squares */
.row:nth-child(odd) .square:nth-child(odd),
.row:nth-child(even) .square:nth-child(even) {
	background: #ccc; /* white */
}

Similarly, for black squares —

  1. Even rows’ odd squares are black.
  2. Odd rows’ even squares are black.
CSS
/* Black squares */
.row:nth-child(even) .square:nth-child(odd),
.row:nth-child(odd) .square:nth-child(even) {
	background: #444; /* black */
}

The nth-child is a pseudo-selector that selects sibling elements based on a pattern. For example, nth-child(even) selects every 2nd sibling.

Thus, the above 4 lines of CSS translate to exactly what we summarized in English above. We can apply a little bit of other styles and we will have our chessboard pattern.

This is the final output:

<div class="chessboard">
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
		<div class="square white"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
	<div class="row">
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
		<div class="square"></div>
	</div>
</div>
.chessboard {
	padding: 30px;
	background: hsl(30, 90%, 95%);
	border: 1px solid #ccc;
	border-radius: 20px;
	display: inline-block;
	margin: auto;
	box-shadow: 5px 5px 0px 0px rgba(0, 0, 0, 0.3);
	font-size: 2em;
	color: grey;
}

div.square {
	width: 30px;
	aspect-ratio: 1;
	display: inline-block;
	box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.05) inset;
	font-size: 1.5em;
	text-align: center;
	line-height: 1.5em;
	color: red;
}

.row {
	display: flex;
}

div.row:nth-child(odd) div.square:nth-child(odd),
div.row:nth-child(even) div.square:nth-child(even) {
	background: #ccc; /* white */
}

div.row:nth-child(even) div.square:nth-child(odd),
div.row:nth-child(odd) div.square:nth-child(even) {
	background: #111; /* black */
}

You can also also add the Chess pieces to this chessboard. Thankfully, Unicode has characters for all 12 pieces in chess, so we don’t have to draw them with CSS.

Here’s the table containing the Unicode for chess pieces.

Name of the PieceUnicode RepresentationU+ Code
King♔, ♚U+2654, U+265A
Queen♕, ♛U+2655, U+265B
Rook♖, ♜U+2656, U+265C
Bishop♗, ♝U+2657, U+265D
Knight♘, ♞U+2658, U+265E
Pawn♙, ♟U+2659, U+265F

You can copy and paste the Unicode representations directly at appropriate places in your HTML. You will have a full-fledged Chessboard, made entirely with HTML and CSS.

If you liked this tutorial, please share it with your friends.

Further reading:

  1. CSS Padding (An Ultimate Guide)
  2. How to Create a Radar Animation Effect in CSS