I would like to, once having an HTML table, be able to take a group of cells and write a text (in this case, a single character) centered both vertically and horizontally across that group of cells, just as in the image below.
I have explored the possibility of writing the text in the first (top-left) td
and then use the overflow
CSS property over that td
element in order for the text to go over the limits of the td
. However, this would not work for centering the text vertically (across tr
).
Is there any way to do this just using a simple HTML table and CSS, or should I consider using a canvas in order to overlap a text over the table?
Solution 1:
Use rowspan and colspan, together with valign
and align
(which are specific <table>
centering attributes):
td {
border: 1px solid #eee;
padding: 1rem;
}
td[rowspan] {
background-color: rgba(255,0,0,.07);
border: 1px solid red;
}
<table>
<tr>
<td rowspan="2" colspan="2" valign="center" align="center">
A
</td>
<td>x</td>
</tr>
<tr>
<td>x</td>
</tr>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
Solution 2:
The hacky way I was describing in the comment:
td {
border: 1px solid #eee;
padding: 1rem;
}
.hacky-td {
position: relative;
overflow: visible;
}
.hacky-content {
font-size: 3rem;
position: absolute;
transform: translate(-50%,-50%);
border: 1px solid red;
padding: 1rem;
background-color: rgba(255,0,0,.07);
left: -1px; /* should be 0, it's 1 because of the border */
top: -1px; /* should be 0, it's 1 because of the border */
}
<table>
<tr>
<td></td>
<td></td>
<td>x</td>
</tr>
<tr>
<td></td>
<td class="hacky-td"><div class="hacky-content">A</div></td>
<td>Lorem<br>ipsum,<br>dolor<br>sit<br>amet</td>
</tr>
<tr>
<td>x</td>
<td>Lorem ipsum, dolor sit amet</td>
<td>x</td>
</tr>
You'll notice the A will remain centered on the junction regardless of the size of each of the 4 cells.
Solution 3: - CSS Grid
If you want to center across the entire area, you'll have to use CSS grid, which makes it kind of trivial:
.grid {
display: grid;
grid-template:
"a b c" auto
"d e f" auto
"g h i" auto
/1fr 2fr 1fr;
grid-gap: 2px;
}
.grid > *:not(.overlay) {
padding: 1rem;
content: 'x';
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #eee;
}
.a { grid-area: a;}
.b { grid-area: b;}
.c { grid-area: c;}
.d { grid-area: d;}
.e { grid-area: e;}
.f { grid-area: f;}
.g { grid-area: g;}
.h { grid-area: h;}
.i { grid-area: i;}
.overlay {
grid-area: 1/1/3/3;
display: flex;
align-items: center;
justify-content: center;
padding: .5rem;
}
.overlay span {
border: 1px solid red;
font-size: 3rem;
font-weight: bold;
background-color: rgba(255,0,0,.07);
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="a">x</div>
<div class="b">Lorem<br>ipsum<br>dolor<br>sit<br>amet</div>
<div class="c">x</div>
<div class="d">x</div>
<div class="e">x</div>
<div class="f">x</div>
<div class="g">x</div>
<div class="h">Amet sit door ipsum lorem, ipsum dolor sit amet.</div>
<div class="i">x</div>
<div class="overlay"><span>A</span></div>
</div>
Solution 4: - Centering across the entire table
This one's a general centering method and it works with anything (you could put any other element instead of the <table>
):
.relative {
position: relative;
display: inline-block;
}
.overlay {
position: absolute;
top: 0.5rem;
bottom: 0.5rem;
left: 0.5rem;
right: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(255,0,0,.07);
font-size: 2.4rem;
border: 1px solid red;
}
td {
padding: 1rem;
border: 1px solid #eee;
}
<div class="relative">
<table>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</table>
<div class="overlay">
A
</div>
</div>