CSS实现Nonogram游戏多表格及单元格固定尺寸位置对齐
Nonogram(数织)游戏布局对齐修复方案
问题根源
对齐失效是三个因素共同导致的:
- Bootstrap默认
.table类自带border-collapse: separate、单元格内边距、默认边距属性,嵌套表格时这些属性会叠加,直接撑大单元格尺寸 - Angular组件样式默认隔离,
board.component.css中定义的单元格固定尺寸规则不会作用到父组件的提示表格,两边盒模型计算规则不统一 - 原有固定宽高样式没有重置Bootstrap自带的单元格内边距,也没有设置
box-sizing: border-box,提示单元格实际占位为「20px + 左右内边距 + 边框宽度」,和棋盘格20px的单元格尺寸不匹配 - 外层父表格未设置
border-collapse: collapse,单元格之间的默认间隙被保留
修复步骤
1. 统一父组件所有表格的基础样式
替换game.component.css原有代码,强制覆盖Bootstrap默认样式:
#game table { table-layout: fixed; border-collapse: collapse; margin: 0; padding: 0; border-spacing: 0; } /* 上面代码中border-collapse: collapse为核心属性,作用是合并单元格边框,彻底消除单元格之间的默认间隙 */ #game td { width: 20px; height: 20px; padding: 0 !important; /* 强制移除Bootstrap自带的单元格内边距 */ box-sizing: border-box; /* 边框宽度计入20px总尺寸,不会额外撑大单元格 */ text-align: center; vertical-align: middle; line-height: 20px; font-size: 12px; } #columnGroup, #rowGroup { width: auto; height: auto; } app-board { display: block; } /* 左上角空单元格移除多余边框和内边距 */ #game > div > table > tbody > tr:first-child > td:first-child { padding: 0 !important; border: none; }
2. 对齐棋盘组件样式规则
修改board.component.css,保证和父组件盒模型规则一致:
table { border-collapse: collapse; border-spacing: 0; margin: 0; table-layout: fixed; } td { width: 20px; height: 20px; padding: 0; box-sizing: border-box; border: 1px solid #000; } .empty { background-color: white; text-indent: -9999px; background: url(../../../assets/x.svg); background-size: 20px 20px; } .black { background-color: black; }
3. 精简HTML结构,移除冗余样式类
修改game.component.html,去掉会触发Bootstrap默认表格样式的冗余class,同时移除重复使用的id(id为页面唯一标识,多元素共用会导致样式匹配异常):
<div id="game" class="container"> <div class="d-flex justify-content-center"> <table> <tr> <td></td> <td> <table id="columnGroup" class="border border-dark"> <tr *ngFor="let line of createRange(calculateMaxArray(columnGroups)); index as i"> <td *ngFor="let row of createRange(width); index as j" class="border border-dark"> {{columnGroups[j][i]}} </td> </tr> </table> </td> </tr> <tr> <td> <table id="rowGroup" class="border border-dark"> <tr *ngFor="let line of createRange(height); index as i"> <td *ngFor="let row of createRange(calculateMaxArray(rowGroups)); index as j" class="border border-dark"> {{rowGroups[i][j]}} </td> </tr> </table> </td> <td> <app-board [width]="width" [height]="height"></app-board> </td> </tr> </table> </div> </div>
后续优化提示
- 不要在多个重复元素上使用同一个id,通用样式尽量用类选择器定义
- 如果后续需要适配不同难度的棋盘,只需要统一修改单元格尺寸变量,三个表格会自动保持对齐,不需要单独调整每个表格的宽高
- 如果提示数字过长,可以适当缩小字体大小,不要修改单元格尺寸,避免破坏对齐规则
内容的提问来源于stack exchange,提问作者מיכל זוניס
相关产品推荐
相关产品推荐

