I implement a crossword generator. It generates a crossword with row-per-word and letter-per-cell, and keyword is marked with wider border and gray background, like in the image:
To achieve this, my generated code is roughly the following:
#crossword {
border-spacing: 0px;
border-collapse:collapse;
}
.word {
vertical-align: middle;
align-items: center;
text-align: center;
justify-content: center;
margin: 0;
padding: 0;
}
.cell {
width: 30px;
height: 30px;
margin: 0;
padding: 0;
}
.letter {
border: 1px solid black;
}
.keyword {
border-width: 2px;
background-color: gray;
}
<table id="crossword">
<tr class="word">
<td class="cell letter">W</td>
<td class="cell letter keyword">C</td>
<td class="cell letter">A</td>
</tr>
</table>
My problem is marked by red ellipses in the image - the border of keyword, being 1px wider than the rest, breaks the top and bottom line of the crossword. I tried removing border-collapse
property, but that caused double borders to appear on each row connection.
Currently I use table
, tr
and td
for generation, but if there is a solution using div
s, I'll be happy to switch.
So my question is: assuming that I'm able to uniquely address each of the cells (including adding special classes to them etc.), how to make the top and bottom border appear inside the keyword cell, instead of outside?
I found one solution using box-shadow
, but it's not really cross-browser, and involves a lot of magic, so I'd prefer to avoid it if possible.
keep outermost border of the table to match the table's default border by using
table#crossword tr:first-child td {
border-top: 1px solid black;
}
table#crossword tr:last-child td {
border-bottom: 1px solid black;
}
table#crossword tr td:first-child {
border-left: 1px solid black;
}
table#crossword tr td:last-child {
border-right: 1px solid black;
}
It looks a bit low, but you have no other option to other than this to make outermost border evenly aligned
Demo
#crossword {
border-spacing: 0px;
border-collapse:collapse;
}
.word {
vertical-align: middle;
align-items: center;
text-align: center;
justify-content: center;
margin: 0;
padding: 0;
}
.cell {
width: 30px;
height: 30px;
margin: 0;
padding: 0;
}
.letter {
border: 1px solid black;
}
.keyword {
border-width: 2px;
background-color: gray;
}
table#crossword tr:first-child td {
border-top: 1px solid black;
}
table#crossword tr:last-child td {
border-bottom: 1px solid black;
}
table#crossword tr td:first-child {
border-left: 1px solid black;
}
<table id="crossword">
<tr class="word">
<td class="cell letter">W</td>
<td class="cell letter keyword">C</td>
<td class="cell letter">A</td>
</tr>
<tr class="word">
<td class="cell letter">W</td>
<td class="cell letter keyword">C</td>
<td class="cell letter">A</td>
</tr>
<tr class="word">
<td class="cell letter">W</td>
<td class="cell letter keyword">C</td>
<td class="cell letter">A</td>
</tr>
</table>
If you add 'box-sizing: border-box;' only for the .keyword
class , it works - at least it doesn't go out of the outer border of the table:
#crossword {
border-spacing: 0px;
border-collapse: collapse;
}
#crossword .keyword {
box-sizing: border-box;
}
.word {
vertical-align: middle;
align-items: center;
text-align: center;
justify-content: center;
margin: 0;
padding: 0;
}
.cell {
width: 30px;
height: 30px;
margin: 0;
padding: 0;
}
.letter {
border: 1px solid black;
}
.keyword {
border-width: 2px;
background-color: gray;
}
<table id="crossword">
<tr class="word">
<td class="cell letter">W</td>
<td class="cell letter keyword">C</td>
<td class="cell letter">A</td>
</tr>
<tr class="word">
<td class="cell letter">B</td>
<td class="cell letter keyword">K</td>
<td class="cell letter">L</td>
</tr>
<tr class="word">
<td class="cell letter">F</td>
<td class="cell letter keyword">R</td>
<td class="cell letter">V</td>
</tr>
<tr class="word">
<td class="cell letter">T</td>
<td class="cell letter">E</td>
<td class="cell letter">Q</td>
</tr>
</table>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With