单选按钮导致浏览器跳转到顶部

21

问题:

当单击标签时(对于一个被有意隐藏的单选按钮,它已被定位到屏幕之外),浏览器会不希望地跳转到页面顶部。

注意: 这个问题在不同的浏览器上是不一致的——在 Safari 和 Chrome 中会出现,但在 Firefox 或 Opera 中不会出现。


问题:

如何防止点击单选按钮的标签时浏览器跳到页面顶部?


示例代码:

JS Fiddle

• HTML

<div class="rdbut">
    <label class="colour">
        <input id="option-AVGANT1Y2PC" type="radio" name="Multi-licence" value="1 Year 2 PC|+23.99|0" checked="checked" />
        <span>£24.99</span></label>
</div>
<div class="rdbut">
    <label class="colour">
        <input id="option-AVGANT2Y2PC" type="radio" name="Multi-licence" value="2 Year 2 PC|+34.00|0" checked="checked" />
        <span>£35.00</span></label>
</div>

• 层叠样式表(CSS)

.rdbut {
    margin: 0px;
}

.rdbut label {
    float: left;
    width: 65px;
    margin: 4px;
    background-color: #EFEFEF;
    box-shadow: 0px 1px 3px rgba(50, 50, 50, 0.25);
    border: none;
    overflow: auto;
    display: inline;
}

.rdbut label span {
    text-align: center;
    font-size: 12px;
    padding: 3px 8px;
    display: block;
}

.rdbut label input {
    position: absolute;
    top: -9999px;
    left: -9999px;
}

.rdbut input:checked+span {
    background-color: #404040;
    color: #F7F7F7;
}

.rdbut .colour {
    background-color: #FF8E22;
    color: #ffffff;
}

1
CSS对于点击后的页面位置没有影响。你的单选按钮上有任何附加的Javascript代码吗? - Frank Conijn - Support Ukraine
嗨,完全没有任何线索。通过搜索,我似乎找不到任何明确的答案。 - rob-tb
你能把它放到网上吗? - Frank Conijn - Support Ukraine
我在 JSFiddle 上有一个示例,请滚动到结果部分的单选按钮。http://jsfiddle.net/rob_tb/XkQ7T/ - rob-tb
明白了,看到了我的答案。 - Frank Conijn - Support Ukraine
8个回答

29

很有趣。我不确定为什么会出现这种行为,但是修复它很容易:将单选框输入的CSS topleft值替换为visibility: hidden

像这样:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo</title>
    <style>
    #content {
        width: 500px;
    }
    .rdbut {
        margin:0px;
    }
    .rdbut label {
        float:left;
        width:65px;
        margin:4px;
        background-color:#EFEFEF;
        border:none;
        overflow:auto;
        display:inline;
    }
    .rdbut label span {
        text-align:center;
        font-size: 12px;
        padding:3px 8px;
        display:block;
    }
    .rdbut label input {
        position:absolute;
        t/op: -9999px;
        l/eft: -9999px;
        visibility: hidden;
    }
    .rdbut input:checked + span {
        background-color:#404040;
        color:#F7F7F7;
    }
    .rdbut .colour {
        background-color:#FF8E22;
        color:#ffffff;
    }
    </style>
</head>
<body>
    <div id="content">
        <p>"Lorem ipsum" goes here.
        </p>
        <div class="rdbut">
            <label class="colour"><input id="option-AVGANT1Y2PC" type="radio" name="Multi-licence" value="1 Year 2 PC|+23.99|0" checked="checked" />
            <span>£24.99</span></label>
        </div>
        <div class="rdbut">
            <label class="colour"><input id="option-AVGANT2Y2PC" type="radio" name="Multi-licence" value="2 Year 2 PC|+34.00|0" checked="checked" />
            <span>£35.00</span></label>
        </div>
        <div class="rdbut">
            <label class="colour"><input id="option-AVGANT1Y2PC" type="radio" name="Multi-licence" value="1 Year 2 PC|+23.99|0" checked="checked" />
            <span>£24.99</span></label>
        </div>
    </div>
</body>
</html>

这里更新了JSFiddle链接:http://jsfiddle.net/XkQ7T/1/

.
顺便说一下,对每个单选框设置checked是没有用的 - 只有最后一个才会被选中。而且这会使你的代码无效。此外,你需要在单选按钮组周围添加form标签。


1
这个很好用,因为我正在使用这个:https://codepen.io/davidicus/pen/pvObpV 但是我想把我的<label>放在底部而不是顶部。visibility: hidden解决了令人烦恼的“跳动”问题。 :) - CodeFinity
1
不要这样做。这会破坏可访问性(键盘和屏幕阅读器)。 - John_911
@John_911 - 如果不这样做,正常用户和残障用户都会遭受无线跳跃问题的困扰;而如果这样做,只有残障用户会受到影响吗? - Frank Conijn - Support Ukraine
1
今天我遇到了同样的问题,你解决了,现在这个问题已经被修复了。谢谢 :) - Prabhat Kumar
1
谢谢!我之前使用了opacity:0;来隐藏它,因为我需要它仍然可以作为锚点链接,但这会导致页面的跳动。 - Davbog

16

我有同样的问题,我使用了 @Frank Conijn 的解决方案,但是如果单选按钮设置了 visibility: hidden; 或者 display:none,在 IE8 中,label(for="#id")无法起作用,最后,我像这样修复了它:

.rdbut label input {
  position:absolute;
 left: -9999px;
 }

不要设置top


1
IE8?在2016年?Windows XP的扩展支持已于2014年4月8日结束。IE8也是如此。如果用户必须继续使用XP,您应该警告他们应该使用Chrome或Firefox。 - Frank Conijn - Support Ukraine
@FrankConijn IE还没有达到它的巅峰,IE是强大而沉睡的巨人,人们谈论缺乏支持,我们谈论支持,IE是Chrome永远无法成为的东西,IE一直对开发人员友好,IE拥有一个从不滞后的伟大调试器,IE非常棒。 - ii iml0sto1
@iiiml0sto1 -- 每个人都有自己的观点。但我在谈论IE8。 - Frank Conijn - Support Ukraine

10

被接受的答案不可访问:visibility: hidden;会使您的内容对屏幕阅读器不可见。无论如何,问题在这里:

.rdbut label input {
    position: absolute;
    top: -9999px;
    left: -9999px;
}

具体来说,top: -9999; 会导致浏览器尝试向上滚动到该点。

我喜欢为这样的隐藏内容设置一个类,并使用以下参数。然后你可以把它放在任何地方:

.visually-hidden {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

注意 top: auto; 这应该可以防止跳动。


6

这是我所做的,它很好用,同时也允许可访问性。

.hiddenInput {
  opacity: 0;
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  position: fixed;
  top: 0;
}

这样输入框始终处于“视图”中,标签不必强制滚动到它。 'top: 0' 是可选的,对我来说,默认在屏幕中间,我只是将它明确放在某个地方。


其他的方法对我没用,但这个有效。 +1 - Benjamin Intal
1
非常感谢您的回答!使用position: fixed而不是position: absolute解决了我的问题。对于那些想要了解为什么使用visibility: hidden不好的人,可以参考这篇Medium文章:https://blog.bitsrc.io/customise-radio-buttons-without-compromising-accessibility-b03061b5ba93 - eriklharper
这确实是最好的答案。其他所有方法都会破坏可访问性。没有必要将单选按钮发送到屏幕之外。 - John Churchill

2
只需将"display:none"添加到单选按钮即可。
input[type="radio"]{display:none;}

2

如果您自定义单选按钮,请不要使用display:none隐藏它,也不要使用big left:-9999px。

最好使用opacity:0, width:1px, height:1px,让单选按钮靠近您的虚拟单选按钮。

<style>
.radio-button__container{
  position: relative
}
.radio-button{
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  bottom: 0; 
  left: 0;
}

</style>

0
浏览器跳转的原因是输入(单选框或复选框)和其标签相距较远,当您单击可见的

0

display: none; 或 visibility: hidden -> 如果您需要可访问性,这些方法都不会对您有所帮助 :(

虽然它可以解决页面滚动的问题,但却会给屏幕阅读器带来问题。

对我来说,这个变种很好用(感谢@James Hang!):

    input{
          opacity: 0;
          height: 0;
          width: 0;
          margin: 0;
          padding: 0;
          position: fixed;
          top: 0;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接