Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw an even table border with different border widths?

Tags:

css

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: Crossword 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 divs, 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.

like image 429
Tomasz Lewowski Avatar asked Nov 20 '16 13:11

Tomasz Lewowski


2 Answers

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>
like image 194
jafarbtech Avatar answered Oct 19 '22 07:10

jafarbtech


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>
like image 35
Johannes Avatar answered Oct 19 '22 06:10

Johannes