:active 伪类在 mobile safari 中不起作用
在 iPhone/iPad/iPod 上的 Webkit 中,当您点击元素时,不会触发为 标记的 :active 伪类指定样式。我怎样才能触发这个?示例代码:
<style>
a:active {
background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>
In Webkit on iPhone/iPad/iPod, specifying styling for an :active pseudo-class for an <a>
tag doesn't trigger when you tap on the element. How can I get this to trigger? Example code:
<style>
a:active {
background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
仅应用一次,而不是每个按钮元素似乎都修复了页面上的所有按钮。或者,您可以使用这个名为“Fastclick”的小型 JS 库。它加速了触摸设备上的点击事件并解决了这个问题。
Applied just once, as opposed to every button element seemed to fix all buttons on the page. Alternatively you could use this small JS library called 'Fastclick'. It speed up click events on touch devices and takes care of this issue too.
正如其他答案所述,iOS Safari 不会触发
:active
伪类,除非触摸事件附加到元素,但到目前为止,这种行为一直是“神奇的”。我在 Safari 开发者库上看到了这个小简介 解释了这一点(强调我的):换句话说,设置
ontouchstart
事件(即使它为空)就是明确告诉浏览器对触摸事件做出反应。在我看来,这是有缺陷的行为,并且可能可以追溯到“移动”网络基本上不存在的时候(看看链接页面上的那些屏幕截图,看看我的意思),并且一切都是面向鼠标的。有趣的是,其他较新的移动浏览器,例如 Android 上的浏览器,在触摸时可以很好地显示“:active”伪状态,而无需像 iOS 那样进行任何修改。
(旁注:如果您想在 iOS 上使用自己的自定义样式,您还可以通过使用
禁用 iOS 使用的默认灰色半透明框来代替
CSS 属性,如上面同一链接页面中所述。):active
伪状态>-webkit-tap-highlight-color经过一些实验,在
上设置
元素无法完全正常工作。如果页面加载时该元素在视口中可见,则它可以正常工作,但向下滚动并点击视口外的元素不会触发ontouchstart
事件的预期解决方案所有触摸事件随后冒泡到的:active
像它应该的那样伪状态。因此,不要将事件附加到所有元素,而不是依赖事件冒泡到主体(使用 jQuery):
但是,我不知道这样做对性能的影响,所以要小心。
编辑:此解决方案有一个严重缺陷:即使在滚动页面时触摸某个元素也会激活
:active
伪状态。敏感度太强了。 Android 通过在状态显示之前引入一个非常小的延迟来解决这个问题,如果页面滚动,该延迟就会被取消。鉴于此,我建议仅在选定的元素上使用它。就我而言,我正在开发一个在现场使用的网络应用程序,它基本上是一个用于导航页面和提交操作的按钮列表。因为在某些情况下整个页面几乎都是按钮,这对我来说不起作用。但是,您可以设置:hover
伪状态来填充此内容。禁用默认的灰框后,效果非常好。As other answers have stated, iOS Safari doesn't trigger the
:active
pseudo-class unless a touch event is attached to the element, but so far this behaviour has been "magical". I came across this little blurb on the Safari Developer Library that explains it (emphasis mine):In other words, setting an
ontouchstart
event (even if it's empty) is explicitly telling the browser to react to touch events.In my opinion, this is flawed behaviour, and probably dates back to the time when the "mobile" web was basically nonexistent (take a look at those screenshots on the linked page to see what I mean), and everything was mouse oriented. It is interesting to note that other, newer mobile browsers, such as on Android, display `:active' pseudo-state on touch just fine, without any hacks like what is needed for iOS.
(Side-note: If you want to use your own custom styles on iOS, you can also disable the default grey translucent box that iOS uses in place of the
:active
pseudo-state by using the-webkit-tap-highlight-color
CSS property, as explained in the same linked page above.)After some experimentation, the expected solution of setting an
ontouchstart
event on the<body>
element that all touch events then bubble to does not work fully. If the element is visible in the viewport when the page loads, then it works fine, but scrolling down and tapping an element that was out of the viewport does not trigger the:active
pseudo-state like it should. So, instead ofattach the event to all elements instead of relying on the event bubbling up to the body (using jQuery):
However, I am not aware of the performance implications of this, so beware.
EDIT: There is one serious flaw with this solution: even touching an element while scrolling the page will activate the
:active
pseudo state. The sensitivity is too strong. Android solves this by introducing a very small delay before the state is shown, which is cancelled if the page is scrolled. In light of this, I suggest using this only on select elements. In my case, I am developing a web-app for use out in the field which is basically a list of buttons to navigate pages and submit actions. Because the whole page is pretty much buttons in some cases, this won't work for me. You can, however, set the:hover
pseudo-state to fill in for this instead. After disabling the default grey box, this works perfectly.在 中添加 ontouchstart 的事件处理程序标签。这使得 CSS 神奇地工作。
Add an event handler for ontouchstart in your <a> tag. This causes the CSS to magically work.
截至 2016 年 12 月 8 日,接受的答案 (
...
) 在 Safari 10 (iPhone 5s) 上不适用于我: hack 仅适用于页面加载时可见的那些元素。但是,添加:
到
head
确实可以按照我想要的方式工作,但缺点是现在滚动期间的所有触摸事件也会触发触摸元素上的:active
伪状态。 (如果这对您来说是个问题,您可以考虑使用 FighterJet:hover
解决方法。)As of Dec 8, 2016, the accepted answer (
<body ontouchstart="">...</body>
) does not work for me on Safari 10 (iPhone 5s): That hack only works for those elements that were visible on page load.However, adding:
to the
head
does work the way I want, with the downside that now all touch events during scrolling also trigger the:active
pseudo-state on the touched elements. (If this is a problem for you, you might consider FighterJet's:hover
workaround.)这有效对我来说:
注意:如果您执行此技巧,还值得使用以下 CSS 规则删除 Mobile Safari 应用的默认点击突出显示颜色。
This works for me:
Note: if you do this trick it is also worth removing the default tap–highlight colour Mobile Safari applies using the following CSS rule.
这对我有用,将 CSS 添加到您想要突出显示的元素上
This works for me, add to your CSS on the element that you want to highlight
您使用所有伪类还是仅使用一个?如果您至少使用两个,请确保它们的顺序正确,否则它们都会损坏:
..按该顺序。另外,如果您只是使用 :active,请添加一个:link,即使您没有设计它的样式。
Are you using all of the pseudo-classes or just the one? If you're using at least two, make sure they're in the right order or they all break:
..in that order. Also, If you're just using :active, add a:link, even if you're not styling it.
对于那些不想使用ontouchstart的人,可以使用这段代码
For those who don't want to use the ontouchstart, you can use this code
我发布了一个工具可以为您解决这个问题。
表面上看,这个问题看起来很简单,但实际上,触摸和触摸是一个很大的问题。单击行为需要进行广泛的自定义,包括超时功能以及诸如“滚动链接列表时会发生什么”或“按下链接然后将鼠标/手指移离活动区域时会发生什么”之类的事情,
这应该可以解决所有问题立即: https://www.npmjs.com/package/active-touch
您需要将 :active 样式分配给 .active 类,或者选择您自己的类名称。默认情况下,该脚本将适用于所有链接元素,但您可以使用自己的选择器数组覆盖它。
非常感谢诚实、有用的反馈和贡献!
I've published a tool that should solve this issue for you.
On the surface the problem looks simple, but in reality the touch & click behaviour needs to be customized quite extensively, including timeout functions and things like "what happens when you scroll a list of links" or "what happens when you press link and then move mouse/finger away from active area"
This should solve it all at once: https://www.npmjs.com/package/active-touch
You'll need to either have your :active styles assigned to .active class or choose your own class name. By default the script will work with all link elements, but you can overwrite it with your own array of selectors.
Honest, helpful feedback and contributions much appreciated!
我尝试了 这个答案 及其变体,但似乎没有一个可靠地工作(而且我不喜欢依赖“魔法”来完成诸如这)。因此,我做了以下操作,它在所有平台上都完美运行,而不仅仅是 Apple:
:active
的 css 声明重命名为.active
。列出了所有受影响的元素,并添加了
pointerdown/mousedown/touchstart
事件处理程序以应用.active
类和pointerup/mouseup/touchend< /code> 事件处理程序将其删除。使用 jQuery:
这有点乏味,但现在我有了一个更不容易在 Apple 操作系统版本之间出现损坏的解决方案。 (谁需要这样的破坏?)
I tried this answer and its variants, but none seemed to work reliably (and I dislike relying on 'magic' for stuff like this). So I did the following instead, which works perfectly on all platforms, not just Apple:
:active
to.active
.Made a list of all the affected elements and added
pointerdown/mousedown/touchstart
event handlers to apply the.active
class andpointerup/mouseup/touchend
event handlers to remove it. Using jQuery:This was a bit tedious, but now I have a solution that is less vulnerable to breakage between Apple OS versions. (And who needs something like this breaking?)
解决方案是依赖
:target
而不是:active
:当锚点被当前 url 定位时,样式就会被触发,即使在移动设备上也是如此。缺点是您需要其他链接来清除网址中的锚点。完整示例:
A solution is to rely on
:target
instead of:active
:The style will be triggered when the anchor is targeted by the current url, which is robust even on mobile. The drawback is you need an other link to clear the anchor in the url. Complete example:
与这个问题没有100%相关,
但你也可以使用 css 兄弟 hack 来实现这一点
HTML
SCSS
如果你想使用纯 html/css 工具提示
No 100% related to this question,
but you can use css sibling hack to achieve this as well
HTML
SCSS
If you would like to use pure html/css tooltip