javascripthtmlcssborder

Best way to make borders for a crossword in CSS?


I am trying to create a "crossword" where only two words cross with each other. I would like the squares to be separated between each other by 1px, but a thick, 5 or 10px border around the crossword itself. Here is a quick demonstration of what I would like to do, made with Excel:

enter image description here

For making the grid, I am creating a rectangle of 6x5 blocks, some of them being invisible, and some being visible:

let word_vertical = "GHIEJ";
let junction_vertical = 4;
let word_horizontal = "ABCDEF";
let junction_horizontal = 5;

let number_of_letters_vertical = word_vertical.length;
let number_of_letters_horizontal = word_horizontal.length;
let letter_junction = word_vertical[junction_vertical - 1];

let board = document.getElementById("board");

for (let i = 0; i < number_of_letters_vertical; i++) {
    let row = document.createElement("div");
    row.className = "letter-row";

    for (let j = 0; j < number_of_letters_horizontal; j++) {
        let box = document.createElement("div");
        if (i === junction_vertical - 1 || j === junction_horizontal - 1){
            box.className = "letter-box";
            if (j === junction_horizontal - 1) {
                box.innerText = word_vertical[i];
            } else if (i === junction_vertical - 1){
                box.innerText = word_horizontal[j];
            }
        } else {
            box.className = "empty-box";
        }

        row.appendChild(box)
    }

    board.appendChild(row)
}

And here is the CSS:

.letter-row {
    display: flex;
}

.letter-box {
    color: black;
    border: 1px solid black;
    background-color: white;
    font-size: 3.5rem;
    font-weight: 800;
    height: 5rem;
    width: 5rem;
    display: flex;
    justify-content: center;
    align-items: center;
    text-transform: uppercase;
}

.empty-box {
    border: 1px solid transparent;
    height: 5rem;
    width: 5rem;
    display: flex;
    justify-content: center;
    align-items: center;
}

Finally the HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
</head>
<body class="game-page">
    <div id="game-board">
        <div id="board"></div>
    </div>
<script src="index.js" type="module"></script>
</body>
</html>

This turns out to look like this:

enter image description here

As you can see, the borders around are very thin (1px) and the borders between two cells are 2px (1px for each cell contributing). I have tried a few things, including applying directional borders to the empty boxes but that gets complex very fast. Any ideas? Thanks :)


Solution

  • Use drop-shadow filter as @TemaniAfif suggested:

    let word_vertical = "GHIEJ";
    let junction_vertical = 4;
    let word_horizontal = "ABCDEF";
    let junction_horizontal = 5;
    
    let number_of_letters_vertical = word_vertical.length;
    let number_of_letters_horizontal = word_horizontal.length;
    let letter_junction = word_vertical[junction_vertical - 1];
    
    let board = document.getElementById("board");
    
    for (let i = 0; i < number_of_letters_vertical; i++) {
      let row = document.createElement("div");
      row.className = "letter-row";
    
      for (let j = 0; j < number_of_letters_horizontal; j++) {
        let box = document.createElement("div");
        if (i === junction_vertical - 1 || j === junction_horizontal - 1) {
          box.className = "letter-box";
          if (j === junction_horizontal - 1) {
            box.innerText = word_vertical[i];
          } else if (i === junction_vertical - 1) {
            box.innerText = word_horizontal[j];
          }
        } else {
          box.className = "empty-box";
        }
    
        row.appendChild(box)
      }
    
      board.appendChild(row)
    }
    #board {
      filter: drop-shadow(5px 0 0) drop-shadow(-5px 0 0) drop-shadow(0 -5px 0) drop-shadow(0 5px 0)
    }
    
    .letter-row {
      display: flex;
    }
    
    .letter-box {
      color: black;
      border: 1px solid black;
      background-color: white;
      font-size: 3.5rem;
      font-weight: 800;
      height: 5rem;
      width: 5rem;
      display: flex;
      justify-content: center;
      align-items: center;
      text-transform: uppercase;
    }
    
    .empty-box {
      border: 1px solid transparent;
      height: 5rem;
      width: 5rem;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <body class="game-page">
      <div id="game-board">
        <div id="board"></div>
      </div>
    </body>