跨单元格组在 HTML 表格中居中文本
Posted
技术标签:
【中文标题】跨单元格组在 HTML 表格中居中文本【英文标题】:Center text in an HTML table across group of cells 【发布时间】:2019-05-22 01:15:51 【问题描述】:我希望,一旦有了一个 html 表格,就能够获取一组单元格并在该组单元格中垂直和水平居中编写一个文本(在本例中为单个字符),就像在下图。
我已经探索了在第一个(左上角)td
中编写文本的可能性,然后在该 td
元素上使用 overflow
CSS 属性以使文本超出td
。但是,这不适用于垂直居中文本(跨越tr
)。
有没有办法只使用一个简单的 HTML 表格和 CSS,或者我应该考虑使用画布来在表格上重叠文本?
【问题讨论】:
能否提供您已经编写的代码? 几个问题。 #1 从语义上讲,文本是否需要存在于表格中? #2 单元格组将始终是整个表格还是始终只是表格的一部分,或者两者皆有可能? #3 表格里面会不会有内容,文字会叠加在上面? #1 文本不需要成为表格的一部分,它可以是不同的元素(我虽然使用两个重叠的表格并使用position
)#2 组单元格可以只是表格的一部分。
为了提供正确的答案,我们需要知道任何边缘情况,例如单元格可能大小不等、单元格/行的动态数量等。提供minimal reproducible example 以使其更加清晰。
@LG。我刚刚意识到你的答案是正确的。它与表格nothing有关。将<table>
更改为<img>
,这个问题被问了1000 次。这不是以一组单元格为中心(这是我回答的),而是以整个<table>
为中心。因此作为重复关闭。
【参考方案1】:
解决方案 1:
使用rowspan 和colspan,以及valign
和align
(它们是特定的<table>
居中属性):
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>
解决方案 2: 我在评论中描述的 hacky 方式:
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>
您会注意到,无论 4 个单元格中每个单元格的大小如何,A 都将保持在连接点的中心。
解决方案 3:- CSS 网格 如果你想在整个区域居中,你必须使用 CSS 网格,这使得它有点微不足道:
.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>
解决方案 4:- 在整个表格中居中
这是一种通用的居中方法,它适用于任何东西(你可以放置任何其他元素而不是 <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>
【讨论】:
问题是,我想保持单元格原样,即在我的左侧图像中总共保留 4 个td
。我想要这个有两个原因:1)我需要显示所有边框(包括内部边框); 2) 我需要 4 个td
,因为它们有唯一的 ID,我需要使用它们。
你不能一边吃蛋糕一边吃,@dsesto。仅使用 CSS 和 HTML 是无法实现的。一种或另一种方式,您将需要 javascript(要么获取大小并模仿 rowspan/colspan 元素内的“单元格”,要么使用其中一个单元格并将其内容溢出到其他单元格之上。实际上,会有一种 hacky 方式做到这一点。将内容放在靠近中间的单元格中并使用transform: translate(-50%, -50%)
使其将 let 和 top 移动其大小的一半。您还需要根据 td 的填充和边距。会工作。
@AndreiGheorghiu 它是一个简单的位置,它与表格作为相对祖先,然后将其转换为中心......发布了答案:***.com/a/53887567/2827823
@LGSon,如果您希望它在大小不等的行/列中居中,则不是。这就是 CSS 网格派上用场的地方。
好吧,现在我们不是在谈论这个,因为 OP 询问了 HTML Table,并且图像显示它们的大小相同,但是当然,如果想要的话,也可以将任何东西扭曲成不工作.【参考方案2】:
可能有更好的方法来做到这一点。但是当你覆盖元素时,事情会变得一团糟,因为你需要使用绝对定位。无论如何,这里有一些代码和示例可以帮助您入门。
我不知道您的确切情况是什么,但您可以使用 JavaScript 动态获取所需的尺寸以动态设置 CSS。
https://codepen.io/anon/pen/xmqPbo
HTML
<span id="table-overlay-text-2">B</span>
<span id="table-overlay-text-1">A</span>
<table id="table1">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
<br />
<table id="table1">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
CSS
#table1 td, #table2 td
border: 1px solid black;
height: 75px;
width: 75px;
#table-overlay-text-1
font-size:50px;
position: absolute;
z-index:2;
margin-top: 50px;
margin-left: 65px;
#table-overlay-text-2
font-size:50px;
position: absolute;
z-index:2;
margin-top: 275px;
margin-left: 140px;
【讨论】:
不要使用硬编码的边距。关键是:您不知道列或行的高度或宽度。它们可以不包含任何内容,也可以包含整个段落。您不想在内容更改时修改 CSS。您需要将关注点分开。 帖子中没有关于此的信息。也许他永远都知道细胞的大小。我们不知道他为什么需要这个,也不知道他会在哪里使用它。这个问题没有上下文。如果他想要更好的答案,需要在问题中包含更多上下文。 我的意思是:以像素为单位的硬编码大小来设计 any 元素通常被认为是一个糟糕的编码决策。可能会有一些设备无法正确渲染。人们应该努力提供尽可能灵活的解决方案。 不,我完全同意你的看法。这就是为什么我在顶部提到有更好的方法来做到这一点。以上是关于跨单元格组在 HTML 表格中居中文本的主要内容,如果未能解决你的问题,请参考以下文章