这不是 Bootstrap 的 bug,而是 iOS 和部分安卓 WebView 对 fixed 元素与软键盘的渲染差异所致:键盘弹出时视口压缩,但 .modal 等 fixed 容器不自动重定位,导致输入框被顶出视口。

移动端键盘弹出后输入框被顶出视口
这不是 Bootstrap 的 bug,而是 iOS 和部分安卓 WebView 对 fixed 元素 + 软键盘的渲染差异:键盘拉起时页面视口压缩,但 .modal 或 .offcanvas 这类 fixed 容器不会自动重定位,导致输入框被顶到屏幕外、看不见也点不中。
- 确保
中有:—— 少了viewport-fit=cover,iOS 会强制缩放内容区,加剧错位 - 给 modal 容器加
style="min-height: 100vh;",防止键盘顶起后内容区域塌陷成一条线 - 监听搜索框
focusin事件,临时加固 body 高度:$('body').addClass('modal-open').css('height', '100vh');失焦时再清理(否则滚动卡顿)
输入框聚焦但键盘不弹(尤其 iOS Safari)
iOS 要求焦点必须由用户真实手势(tap/click)同步触发,任何异步回调(包括 shown.bs.modal)都会被浏览器静默拦截。写在事件回调里都不行,得“紧贴”用户操作。
- 触发按钮的 click 回调中,先
$('#searchModal').modal('show'),紧接着立刻执行:document.getElementById('searchInput').focus() - 不要用
$('#searchInput').focus()—— jQuery 对象不是原生 DOM,iOS 不认 - 如果模态框内容是 AJAX 加载的,
focus()必须放在.load()回调里,或监听loaded.bs.modal(Bootstrap 4+)
全屏搜索 Modal 中输入框被导航栏/状态栏遮挡
即使键盘没弹,初始打开时输入框也可能被顶部 safe area 遮住。iOS 的 env(safe-area-inset-top) 在某些版本不稳定,手动适配更可靠。
-
.modal-body的padding-top小屏下设为2rem(而不是默认4rem),留出状态栏空间 - 若用了自定义 navbar 高度(比如
height: 72px),需同步调整.modal-body的padding-top,否则视觉重心偏下 - 输入框聚焦后,补一句
input.scrollIntoView({ block: 'center' }),确保它真正在可视区内,不靠用户手动滚动
遮罩层存在但点击空白不关闭,又怕误关
全屏搜索场景下,用户点背景大概率是想继续输入,不是要退出。但直接设 backdrop: false 会彻底去掉灰色遮罩,失去视觉隔离感。
- 用
data-backdrop="static"或 JS 初始化时传{ backdrop: 'static', keyboard: false }—— 灰色遮罩保留,但点击不关闭 - 别删掉
.modal-backdrop元素,也不要用 CSSdisplay: none隐藏它,否则会影响 z-index 层级和过渡动画 - 如果用了自定义 wrapper(如
overflow: hidden的父容器),遮罩可能被裁剪,把它移到直接子级最稳
实际中最容易被忽略的是:iOS 下哪怕所有样式都对,只要 focus() 不是 click 后**立即同步调用**,键盘就一定不弹——没有例外,也不看 setTimeout 延时多短。











