【问题标题】:Detect Browser lost focus in CSS检测浏览器在 CSS 中失去焦点
【发布时间】:2021-11-29 01:40:00
【问题描述】:

不久前我在设计中看到了这个功能,并认为“干草,这看起来是个好主意”。但进一步研究它,我不确定使用“just css”是否完全有可能。

左侧下方有一个导航栏:

ul{
  background:red;
  display:inline-block;
  padding:20px;
  }
<ul>
  <li>link 1</li>
  <li>link 2</li>
  <li>link 3</li>
  <li>link 4</li>
</ul>

当浏览器窗口失去焦点时,有没有办法改变这种情况?

即当用户点击关闭浏览器时,例如改变这个nav的背景颜色?


唯一的可能(可能更低效的方法是做类似的事情):

body:hover ul {
  background: red;
}
body ul {
  display: inline-block;
  padding: 20px;
  background: blue;
}
<ul>
  <li>link 1</li>
  <li>link 2</li>
  <li>link 3</li>
  <li>link 4</li>
</ul>
我能想到的。

但这很明显

  • (A) 效果不佳
  • (B) 实际上并没有正确执行此操作。

我更希望浏览器在更改 css 之前物理上“失去焦点”。

有人对如何实现这一点有任何想法吗?

【问题讨论】:

  • 使用 CSS 这是不可能的。您是否愿意接受其他方法来实现这一目标?另外我觉得hover body方法不是一个好方法,如果你把鼠标移到浏览器的顶部,它看起来有点便宜和俗气。
  • @Ruddy:我想 JQuery 是替代品?
  • 有一个recent (Jan 2015) article in smashingmagazine 讨论了以前的方法来查看标签是否与即将推出的 API 一起可见。 (但是:都是 JS 方法。)
  • @jbutler483 Demo,这就是你如何在 jQuery 中做到这一点(我知道的唯一方法),但它与悬停几乎相同。
  • @jbutler483 但是使用这种方法会更好,因为它可以确定页面是否仍然处于焦点(与悬停不同)。

标签: html css


【解决方案1】:

当前和即将推出的 CSS 标准都没有为用户代理不在前台时定义任何选择器或媒体查询。1

cmets 中提到的Page Visibility API 并不能完全满足您的要求,因为它不能告诉您浏览器是否在前台,只告诉您页面是否可见。浏览器窗口可以在后台,但如果窗口没有最小化或没有被另一个窗口完全遮挡,它的当前选项卡仍然可见(使用上述 API,您甚至不会获得与后者一致的结果)。

你能做的最好的就是使用 JavaScript 监听窗口焦点和模糊事件:

window.addEventListener('focus', function() {
  document.body.classList.add('blur');
});

window.addEventListener('blur', function() {
  document.body.classList.remove('blur');
});
ul {
  display: inline-block;
  padding: 20px;
  background: red;
}
.blur ul {
  background: blue;
}
<ul>
  <li>link 1</li>
  <li>link 2</li>
  <li>link 3</li>
  <li>link 4</li>
</ul>

需要注意的是,如果页面在 iframe 中(例如在堆栈片段中,如上所述),这将无法正常工作,因为当 iframe 本身失去焦点时,iframe 的 window 对象将失去焦点。

我不知道有什么方法可以可靠地检测浏览器窗口何时变为活动或不活动。


1Firefox 在内部使用 :-moz-window-inactive 伪类,它的工作方式与您的预期完全一样,但显然这是一个特定于浏览器的功能,因此不应在生产代码:

ul {
  display: inline-block;
  padding: 20px;
  background: red;
}
ul:-moz-window-inactive {
  background: blue;
}
<ul>
  <li>link 1</li>
  <li>link 2</li>
  <li>link 3</li>
  <li>link 4</li>
</ul>

WebKit 也有自己的:window-inactive 伪类,这实际上是激发 Firefox 中相同功能的原因,只是 WebKit 出于某种奇怪的原因没有为其添加前缀,并且它目前仅适用于滚动条伪-元素。

【讨论】:

    【解决方案2】:

    由于 css 在文档范围内执行,因此您肯定无法检测到 css 中的窗口焦点。但是您可以使用 html5 tabindex 属性检测到它,比如body

    body:focus ul {
      background: red;
    }
    body ul {
      display: inline-block;
      padding: 20px;
      background: blue;
    }
    <body tabindex="0">
      <ul>
        <li>link 1</li>
        <li>link 2</li>
        <li>link 3</li>
        <li>link 4</li>
      </ul>
    </body>

    【讨论】:

      【解决方案3】:

      你可以试试:window-inactive:

      ::selection {
        background: hsl(136,65%,45%);
        color: white;
      }
      ::selection:window-inactive {
        background: hsl(136,25%,65%);
      }
      

      它是在at least in firefox 上实现的,你可以看到它在its test page (firefox only) 上运行。

      【讨论】: