本文详解如何在 Thymeleaf 模板中结合 HTML <table> 标签,优雅地将单列表数据(如数据库查询结果)以“每行两列”的布局渲染,避免常见误区(如错误嵌套 th:each 在 <table> 上),并提供可直接运行的结构化代码与关键注意事项。
本文详解如何在 thymeleaf 模板中结合 html `
在 HTML 表格中实现“每行显示两个数据项”(例如图书/歌手卡片并排展示),关键在于正确理解表格语义结构:<table> 定义整体容器,<tr> 表示一行,<td> 表示该行中的单元格。初学者常误将 th:each 直接放在 <table> 上(如原代码),导致每个数据项生成一个独立表格,完全破坏布局逻辑。
正确的做法是:在外层 <table> 中遍历数据索引,按步长为 2 动态生成 <tr> 行,并在每行内通过索引计算填充两个 <td> 单元格。以下是优化后的完整代码:
<table class="vocalist-table"> <tr th:each="vocalist, iterStat : ${bookList}" th:if="${iterStat.index % 2 == 0}"> <!-- 左侧单元格:当前索引项 --> <td> <div class="bookdiv" th:id="'vocalist-' + ${iterStat.index}"> <img src="images/ClosedBook.png" class="closeBook" alt="Book cover"> <span class="bookName" th:text="${vocalist.vocaName}">Vocalist Name</span> </div> </td> <!-- 右侧单元格:下一索引项(需校验不越界) --> <td th:if="${iterStat.index + 1 < bookList.size()}"> <div class="bookdiv" th:id="'vocalist-' + ${iterStat.index + 1}"> <img src="images/ClosedBook.png" class="closeBook" alt="Book cover"> <span class="bookName" th:text="${bookList[iterStat.index + 1].vocaName}">Vocalist Name</span> </div> </td> </tr></table>
✅ 核心要点说明:
⚠️ 重要注意事项:
立即学习“前端免费学习笔记(深入)”;
.vocalist-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }@media (max-width: 768px) { .vocalist-grid { grid-template-columns: 1fr; } }
此方案兼顾语义正确性、浏览器兼容性与 Thymeleaf 最佳实践,可稳定支撑中等规模数据的双列表格展示需求。