Bootstrap 5布局需求:多行列网格堆叠,单行列保持居中
Bootstrap 5 响应式网格布局解决方案
需求概述
使用Bootstrap 5的row配合justify-content-center实现列居中,要求:
container左右间距不受页面尺寸影响- 每行固定4列,列间距固定
- 单行(如仅2列)时保持居中对齐
- 元素超过一行(≥5列)时,堆叠行左对齐但整体仍在容器内居中(禁用
justify-content-start)
解决方案
通过自定义CSS结合Bootstrap工具类实现,核心是控制不同列数下的对齐逻辑,同时保持响应式特性。
自定义CSS
.state-online { color: #00adef; } /* 自定义行样式:固定列间距+动态列宽 */ .custom-row { --col-gap: 0.5rem; /* 固定列间距,按需调整 */ gap: var(--col-gap); } /* 计算每列宽度:基于每行列数减去间距 */ .custom-row > .col { flex: 0 0 calc(25% - var(--col-gap)); max-width: calc(25% - var(--col-gap)); } /* 响应式适配:不同屏幕尺寸调整每行列数 */ @media (max-width: 1199.98px) { .custom-row > .col { flex: 0 0 calc(25% - var(--col-gap)); max-width: calc(25% - var(--col-gap)); } } @media (max-width: 991.98px) { .custom-row > .col { flex: 0 0 calc(50% - var(--col-gap)); max-width: calc(50% - var(--col-gap)); } } @media (max-width: 575.98px) { .custom-row > .col { flex: 0 0 100%; max-width: 100%; } }
修改后的HTML代码
<head> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="container"> <!-- 使用自定义类+justify-content-center实现需求 --> <div class="row custom-row justify-content-center m-0" id="row"> <!-- 列1 --> <div class="col p-0"> <div class="table-responsive card m-0 mt-2"> <table class="table table-borderless align-middle m-0"> <tbody> <tr> <td class="text-start">Name 1</td> <td class="text-end text-nowrap"> <svg class="state-online align-text-top" width="16" height="16" fill="currentColor" viewBox="0 0 512 512"> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"></path> </svg> <span>online</span> </td> </tr> <tr> <td colspan="2" class="text-center"> <img class="img-fluid" src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png" style="height: 150px;"> </td> </tr> <tr> <td colspan="2" class="text-center"> <a class="btn btn-primary w-100">Connect</a> </td> </tr> </tbody> <tfoot class="table-group-divider" style="display: none;"></tfoot> </table> </div> </div> <!-- 列2 --> <div class="col p-0"> <div class="table-responsive card m-0 mt-2"> <table class="table table-borderless align-middle m-0"> <tbody> <tr> <td class="text-start">Name 2</td> <td class="text-end text-nowrap"> <svg class="state-online align-text-top" width="16" height="16" fill="currentColor" viewBox="0 0 512 512"> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"></path> </svg> <span>online</span> </td> </tr> <tr> <td colspan="2" class="text-center"> <img class="img-fluid" src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png" style="height: 150px;"> </td> </tr> <tr> <td colspan="2" class="text-center"> <a class="btn btn-primary w-100">Connect</a> </td> </tr> </tbody> <tfoot class="table-group-divider" style="display: none;"></tfoot> </table> </div> </div> <!-- 列3 --> <div class="col p-0"> <div class="table-responsive card m-0 mt-2"> <table class="table table-borderless align-middle m-0"> <tbody> <tr> <td class="text-start">Name 3</td> <td class="text-end text-nowrap"> <svg class="state-online align-text-top" width="16" height="16" fill="currentColor" viewBox="0 0 512 512"> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"></path> </svg> <span>online</span> </td> </tr> <tr> <td colspan="2" class="text-center"> <img class="img-fluid" src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png" style="height: 150px;"> </td> </tr> <tr> <td colspan="2" class="text-center"> <a class="btn btn-primary w-100">Connect</a> </td> </tr> </tbody> <tfoot class="table-group-divider" style="display: none;"></tfoot> </table> </div> </div> <!-- 列4 --> <div class="col p-0"> <div class="table-responsive card m-0 mt-2"> <table class="table table-borderless align-middle m-0"> <tbody> <tr> <td class="text-start">Name 4</td> <td class="text-end text-nowrap"> <svg class="state-online align-text-top" width="16" height="16" fill="currentColor" viewBox="0 0 512 512"> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"></path> </svg> <span>online</span> </td> </tr> <tr> <td colspan="2" class="text-center"> <img class="img-fluid" src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png" style="height: 150px;"> </td> </tr> <tr> <td colspan="2" class="text-center"> <a class="btn btn-primary w-100">Connect</a> </td> </tr> </tbody> <tfoot class="table-group-divider" style="display: none;"></tfoot> </table> </div> </div> <!-- 列5(用于测试多行布局) --> <div class="col p-0"> <div class="table-responsive card m-0 mt-2"> <table class="table table-borderless align-middle m-0"> <tbody> <tr> <td class="text-start">Name 5</td> <td class="text-end text-nowrap"> <svg class="state-online align-text-top" width="16" height="16" fill="currentColor" viewBox="0 0 512 512"> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"></path> </svg> <span>online</span> </td> </tr> <tr> <td colspan="2" class="text-center"> <img class="img-fluid" src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png" style="height: 150px;"> </td> </tr> <tr> <td colspan="2" class="text-center"> <a class="btn btn-primary w-100">Connect</a> </td> </tr> </tbody> <tfoot class="table-group-divider" style="display: none;"></tfoot> </table> </div> </div> </div> </div> </body>
原理说明
- 利用CSS变量
--col-gap统一控制列间距,保证间距固定 - 通过
calc()计算每列宽度,确保每行4列时刚好占满对应空间,剩余空间由justify-content-center均匀分配在容器左右,实现多行左对齐但整体居中 - 媒体查询适配不同屏幕尺寸,自动调整每行列数,保持响应式特性
内容的提问来源于stack exchange,提问作者sopryshko
相关产品推荐
相关产品推荐

