data-bs-backdrop="static"是唯一可靠写法,必须配合data-bs-keyboard="false"和tabindex="-1"才能彻底禁用点击背景和ESC键关闭,漏bs-前缀或缺失tabindex会导致失效。

data-bs-backdrop="static" 是唯一可靠写法
Bootstrap 5 中,data-backdrop="static" 已失效,必须用带 bs- 前缀的 data-bs-backdrop="static"。漏掉 bs- 或写成 false 都会导致遮罩层被移除(DOM 节点直接不渲染),而不是“有遮罩但不响应点击”——这是最常踩的命名错误。
它必须写在 modal 根元素上,例如:
<div class="modal fade" id="myModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
<p>仅靠这个属性就能阻止点击背景关闭,同时保留灰色遮罩层;但要注意:它不干涉 ESC 键,需额外配 <code>data-bs-keyboard="false"</code> 才算真正锁死。</p>
<h3>keyboard: false 必须配合 tabindex="-1"</h3>
<p><code>keyboard: false</code>(或 <code>data-bs-keyboard="false"</code>)只在 modal 元素存在 <code>tabindex="-1"</code> 时才生效。缺了这个,ESC 依然能关模态框——因为 Bootstrap 的键盘事件监听逻辑依赖该属性来识别模态框焦点上下文。</p>
<p>常见失效组合:</p>
<ul>
<li>写了 <code>data-bs-keyboard="false"</code> 但没写 <code>tabindex="-1"</code>
</li>
<li>JS 初始化传了 <code>{ keyboard: false }</code>,但 HTML 里 <code>tabindex</code> 被覆盖或遗漏</li>
<li>动态创建 modal 时 JS 拼接 HTML,忘了加 <code>tabindex="-1"</code>
</li>
</ul>
<p>建议始终把 <code>tabindex="-1"</code> 和 <code>aria-hidden="true"</code> 当作标配,二者缺一不可。</p>
<h3>JS 初始化比 HTML 属性更灵活</h3>
<p>如果模态框需要按业务状态动态切换关闭行为(比如表单未填完时禁用关闭,填完后允许),硬编码 HTML 属性就不够用了。此时应优先用 JS 初始化控制:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4914" title="VPS Bootstrap"><img
src="https://img.php.cn/upload/skill/000/000/081/179025304626966.jpg" alt="VPS Bootstrap" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill4914" title="VPS Bootstrap" class="overflowclass">VPS Bootstrap</a>
<p class="overflowclass">从零启动全新 VPS,完成 OpenClaw 完整部署,包括备份/恢复及恢复后验证。用于 OpenClaw 部署。</p>
</div>
<a rel="nofollow" href="/xiazai/skill4914" title="VPS Bootstrap" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;">$('#myModal').modal({ backdrop: 'static', keyboard: false });
注意:backdrop 和 keyboard 的值是字符串,不是布尔值;'static' 不是 true 或 'true'。
还可以运行时修改:
$('#myModal').data('bs.modal')._config.backdrop = 'static';
但更稳妥的做法是在每次 show() 前重设配置,避免状态残留。
背景残留问题常和 AJAX 关闭时机有关
即使设置了 data-bs-backdrop="static",AJAX 提交后手动调用 modal('hide') 仍可能留下半透明 .modal-backdrop DOM 节点——这不是 backdrop 设置问题,而是 modal('hide') 被多次调用、或在异步回调外提前执行导致的。
典型错误:
- 在按钮 click 里重复绑定 form submit 事件,每次触发都调一次
modal('hide') - success 回调里没加
if ($('#myModal').is(':visible'))就直接 hide - 用了
async: false导致 UI 更新卡顿,backdrop 节点未被及时清理
正确做法:只在 AJAX 成功回调末尾调一次 $('#myModal').modal('hide'),且确保该调用不在任何循环或重复绑定的 handler 内部。










