You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JS或CSS检测iOS 15 Safari中地址栏的位置(顶部/底部)

iOS 15+ Safari 地址栏位置检测方案

核心原理

iOS 15及以上版本的Safari地址栏位置变化,会直接反映在视口高度差、安全区域变量的数值差异上,基于这个特征可以分别用CSS配合JS实现检测。

CSS 适配方案

你可以直接利用env()安全区域变量适配不同位置的地址栏,不需要额外判断逻辑:

/* 底部固定元素自动适配地址栏高度 */
.fixed-bottom-element {
  /* env(safe-area-inset-bottom)会自动包含底部地址栏的高度 */
  bottom: calc(16px + env(safe-area-inset-bottom));
}

如果需要根据地址栏位置做差异化样式,可以配合JS注入的属性实现:

/* 底部地址栏时的样式 */
:root[address-bar-pos="bottom"] .some-element {
  margin-bottom: 60px;
}
/* 顶部地址栏时的样式 */
:root[address-bar-pos="top"] .some-element {
  margin-bottom: 20px;
}

JS 检测方案

通过计算浏览器外高度和内高度的差值,可以准确判断地址栏位置,代码如下:

function getSafariAddressBarPos() {
  // 前置校验:仅iOS 15+ Safari执行检测
  const ua = navigator.userAgent;
  const isIOS = /iPhone|iPad|iPod/.test(ua) && !window.MSStream;
  const isSafari = /Safari/.test(ua) && !/CriOS|Chrome/.test(ua);
  const iosVer = parseFloat((ua.match(/OS (\d+)_(\d+)/) || []).slice(1,3).join('.')) || 0;
  if (!isIOS || !isSafari || iosVer < 15) return null;

  const heightDiff = window.outerHeight - window.innerHeight;
  const safeAreaBottom = parseInt(getComputedStyle(document.documentElement).getPropertyValue('env(safe-area-inset-bottom)')) || 0;

  // 底部地址栏时高度差超过90px,且安全区域底部高度大于40px(排除手势条的34px)
  return heightDiff > 90 && safeAreaBottom > 40 ? 'bottom' : 'top';
}

// 监听地址栏位置变化事件
['resize', 'visibilitychange'].forEach(evt => {
  window.addEventListener(evt, () => {
    const pos = getSafariAddressBarPos();
    if (!pos) return;
    // 将结果写入根元素属性,供CSS使用
    document.documentElement.setAttribute('address-bar-pos', pos);
    // 后续业务逻辑处理
  });
});

注意事项

  • 用户滑动页面触发地址栏悬浮缩小的时候,检测结果会临时失效,等地址栏恢复固定状态后会自动更新
  • 横竖屏切换时会自动触发resize事件,不需要额外适配

内容的提问来源于stack exchange,提问作者Wei Yan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:48:02