How to Create Crossword Puzzle using HTML and CSS?

Crossword puzzles are like brain teasers that test how much you know. Words are hidden in a grid, going up and down or across. You fill in the empty spaces with letters to guess the words. When you’re done, hover over a button to see if you got them all right!

Approach

By following these steps, the crossword puzzle will be interactive, visually appealing, and user-friendly across different devices.

  • Create a grid where each cell represents a letter in the crossword puzzle.
  • Use HTML to build a grid structure with rows and columns. Each cell will be an input element to allow users to type in their answers. Unused cells will be marked and styled differently to maintain the structure.
  • Define the visual appearance of the grid, including cell size, spacing, and colors.
  • Use CSS to create a grid layout that looks like a traditional crossword puzzle. Define styles for used and unused cells, ensuring clarity and ease of use. Use CSS positioning to place clue numbers in the corner of the relevant cells.
  • Enhance user interaction by highlighting the cell currently being edited.
  • Apply CSS styles to change the background color of a cell when it is focused (clicked or typed in). This helps users easily identify where they are entering their answers.
  • Display the clues for the crossword puzzle in a separate section, with an option to reveal the answers.
  • Use HTML to list the clues and provide a button for each clue to show the answer. Initially, the answers are hidden using CSS, and JavaScript will handle the logic to reveal them when the button is clicked.
  • Ensure the crossword puzzle is usable on various screen sizes, including phones, tablets, and desktops.
  • Use CSS media queries to adjust the grid layout, cell size, and overall puzzle dimensions based on the screen size. This ensures the puzzle is readable and interactable on all devices.

Example: Creating a Pure CSS Crossword Puzzle.

HTML
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" 
          content="width=device-width,
                   initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Word Puzzle</title>
</head>

<body>

    <div class="game-container">

        <div class="puzzle-grid">
            <h1 style="position: absolute; top: 2px;">
                         Word Puzzle Game</h1>
            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">1</span>
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
            </div>
            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
            </div>
            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">2</span>
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

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

                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">3</span>
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">4</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">5</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

            </div>
            <div class="row">
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

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

                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">6</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>

                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

            </div>


            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive">


                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">7</span>
                </div>

            </div>
            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive">


                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive">


                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>

            </div>


            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">8</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">9</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>

            </div>


            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>

            </div>


            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">10</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                    <span class="number">11</span>
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />
                </div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>


            </div>

            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

            </div>

            <div class="row">
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>
                <div class="cell">
                    <input type="text" maxlength="1" />

                </div>
                <div class="cell inactive"></div>
                <div class="cell inactive"></div>

            </div>
        </div>








        <div class="clues">
            <h2>Clues</h2>

            <table>
                <thead>
                    <tr>
                        <th>Clue Number</th>
                        <th>Clue Direction</th>
                        <th>Clue Text</th>
                        <th>Answer</th>
                    </tr>
                </thead>

                <tbody>
                    <tr>
                        <td>1</td>
                        <td>Down</td>
                        <td>Fastest land animal</td>
                        <td><button id="show-answers-btn1">
                                Show Answer
                            </button>
                            <div class="h1">CHEETAH</div>
                        </td>
                    </tr>
                    <tr>
                        <td>2</td>
                        <td>Down</td>
                        <td>Starts life as a tadpole</td>
                        <td><button id="show-answers-btn2">
                                Show Answer
                            </button>
                            <div class="h2">FROG</div>
                        </td>
                    </tr>
                    <tr>
                        <td>3</td>
                        <td>Down</td>
                        <td>Man's best friend</td>
                        <td><button id="show-answers-btn3">
                                Show Answer
                            </button>
                            <div class="h3">DOG</div>
                        </td>
                    </tr>
                    <tr>
                        <td>4</td>
                        <td>Across</td>
                        <td>Has black and white stripes</td>
                        <td><button id="show-answers-btn4">
                                Show Answer
                            </button>
                            <div class="h4">ZEBRA</div>
                        </td>
                    </tr>
                    <tr>
                        <td>5</td>
                        <td>Down</td>
                        <td>Large animals with a trunk</td>
                        <td><button id="show-answers-btn5">
                                Show Answer
                            </button>
                            <div class="h5">ELEPHANT</div>
                        </td>
                    </tr>
                    <tr>
                        <td>6</td>
                        <td>Across</td>
                        <td>Tallest land animal</td>
                        <td><button id="show-answers-btn6">
                                Show Answer
                            </button>
                            <div class="h6">GIRAFFE</div>
                        </td>
                    </tr>
                    <tr>
                        <td>7</td>
                        <td>Down</td>
                        <td>King of the jungle</td>
                        <td><button id="show-answers-btn7">
                                Show Answer
                            </button>
                            <div class="h7">LION</div>
                        </td>
                    </tr>
                    <tr>
                        <td>8</td>
                        <td>Across</td>
                        <td>Hopping Australian marsupial</td>
                        <td><button id="show-answers-btn8">
                                Show Answer
                            </button>
                            <div class="h8">KANGAROOO</div>
                        </td>
                    </tr>
                    <tr>
                        <td>9</td>
                        <td>Down</td>
                        <td>Large animal with a horn</td>
                        <td><button id="show-answers-btn9">
                                Show Answer
                            </button>
                            <div class="h9">RHINO</div>
                        </td>
                    </tr>
                    <tr>
                        <td>10</td>
                        <td>Across</td>
                        <td>Likes to chase mice</td>
                        <td><button id="show-answers-btn10">
                                Show Answer
                            </button>
                            <div class="h10">CAT</div>
                        </td>
                    </tr>
                    <tr>
                        <td>11</td>
                        <td>Across</td>
                        <td>Like to roll around in the mud</td>
                        <td><button id="show-answers-btn11">
                                Show Answer
                            </button>
                            <div class="h11">PIG</div>
                        </td>
                    </tr>
                </tbody>
            </table>


        </div>
    </div>
</body>

</html>
CSS
/* style.css */
@import url(
'https://fonts.googleapis.com/css2?family=Poppins:wght@100;300;800&display=swap');
*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    font-family: 'Poppins', sans-serif;
}

.game-container {
    padding: 10px;
    display: flex;
    width: 100%;
    justify-content: space-around;
    min-height: 100vh;
    align-items: center;
}

.puzzle-grid {
    display: grid;
    grid-template-rows: repeat(13, 40px);
}

.row {
    display: grid;
    grid-template-columns: repeat(13, 40px);
    box-shadow: rgba(17, 12, 46, 0.15) 0px 48px 100px 0px;
}

.cell {
    width: 40px;
    height: 40px;
    background-color: white;
    border: 1px solid green;
}

.inactive {
    background-color: green;
}

h1 {
    text-align: center;
    color: green;
    font-size: 2.2rem;
}

.number {
    position: relative;
    font-weight: 300;
    color: #000;
    bottom: 45px;
    font-size: small;
    left: 3px;
    z-index: 10;
}

input:focus {
    outline: none;
    background-color: #bddebe;
    width: 37.5px;
    height: 37.5px;
}

input {
    display: block;
    position: relative;
    font-size: 16px;
    text-align: center;
    height: 40px;
    width: 40px;
    background-color: transparent;
    border: none;
    z-index: 1;
}

.clues {
    max-width: 40%;
   
}

h2 {
    font-size: 1.5rem;
    color: green;
    text-align: center;
}

#clues-list {
    line-height: 2.5rem;
    font-size: 1rem;
    padding: 10px;

}

#clues-list li {
   gap: 20px;
    padding: 0;
    display: flex;
    text-align: center;
    list-style-position: inside;
    justify-content: space-between;
    align-items:center ;
}

button {
    display: block;
   
    padding: 5px;
    background-color: green;
    color: #fff;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
    border: 2px solid transparent;
}

.h1,.h2,.h3,.h4,.h5,.h6,.h7,.h8,.h9,.h10,.h11 {
   
    visibility: hidden;
    color: green;

}

#show-answers-btn1:hover~.h1 {
    visibility: visible;
}
#show-answers-btn2:hover~.h2{
    visibility: visible;
}
#show-answers-btn3:hover~.h3 {
    visibility: visible;
}
#show-answers-btn4:hover~.h4 {
    visibility: visible;
}
#show-answers-btn5:hover~.h5 {
    visibility: visible;
}
#show-answers-btn6:hover~.h6 {
    visibility: visible;
}
#show-answers-btn7:hover~.h7 {
    visibility: visible;
}
#show-answers-btn8:hover~.h8 {
    visibility: visible;
}
#show-answers-btn9:hover~.h9 {
    visibility: visible;
}
#show-answers-btn10:hover~.h10 {
    visibility: visible;
}
/* #show-answers-btn11:hover~.h11 {
    visibility: visible;
} */
#show-answers-btn11:hover~#show-answers-btn11 {
    visibility: hidden;
}

button:hover {
    background-color: #fff;
    border: 2px solid green;
    color: green;
    cursor: pointer;
    transition: all .2s ease;
}
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;

}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}



@media screen and (max-width: 980px) {
    .game-container {
        flex-direction: column;
        align-items: center;
        padding-top: 70px;
        gap: 30px;
    }

    .puzzle-grid {
        display: grid;
        grid-template-rows: repeat(13, 40px);
    }

    .row {
        display: grid;
        grid-template-columns: repeat(13, 40px);
    }

    .cell {
        width: 40px;
        height: 40px;
    }

    input {
        width: 40px;
        height: 40px;
        font-size: 1rem;
    }

    input:focus {
        height: 40px;
        width: 40px;
    }

    .number {
        bottom: 47px;
        font-size: .8rem;
    }

    .clues {
        max-width: 100%;
    }
}

@media screen and (max-width: 480px) {
    .game-container {
        flex-direction: column;
        align-items: center;
         padding-top: 70px;
        gap: 30px;
    }

    .puzzle-grid {
        display: grid;
        grid-template-rows: repeat(13, 27px);
    }

    .row {
        display: grid;
        grid-template-columns: repeat(13, 27px);
    }

    .cell {
        width: 27px;
        height: 27px;
    }

    ol {
        line-height: 1rem;
        font-size: 10px;
    }

    input {
        width: 25px;
        height: 25px;
        font-size: .5rem;
    }

    input:focus {
        height: 27px;
        width: 27px;
    }

    .number {
        bottom: 35px;
        font-size: .5rem;
    }

    .clues {
        max-width: 100%;
    }
}

Output:

crossword puzzle using HTML and CSS