【问题标题】:How to remove focus around buttons on click如何在单击时消除按钮周围的焦点
【发布时间】:2013-10-03 21:27:11
【问题描述】:

单击后,我的按钮周围都有一个突出显示。这是在 Chrome 中。

<button class="btn btn-primary btn-block">
    <span class="icon-plus"></span> Add Page
</button>

我正在使用带有主题的 Bootstrap,但我很确定不是它:我之前在另一个项目中注意到了这一点。

如果我使用&lt;a&gt; 标签而不是&lt;button&gt;,它就会消失。为什么?如果我想使用&lt;button&gt;,我该如何让它消失?

【问题讨论】:

  • 大纲:0;你可能会感兴趣
  • 点击后有没有添加类?
  • outline: 0 似乎没有帮助,webkit-appearance 也没有
  • 人们认为这种可访问性功能是一个问题,这证明了当今前端 Web 开发的糟糕状态。
  • 现在是 2020 年,终于有了:focus-visible 的官方解决方案。看我的回答stackoverflow.com/a/60219624/413538

标签: html css twitter-bootstrap


【解决方案1】:

我在使用 &lt;a&gt; 作为按钮时遇到了同样的问题,我发现 我错过了通过添加 attr type="button" 使其至少对我来说表现正常的解决方法。

&lt;a type="button" class="btn btn-primary"&gt;Release Me!&lt;/a&gt;

【讨论】:

  • type 属性应该对此没有影响,button 是一个无效值。该属性接受一个 MIME 类型,并告诉客户端如果它遵循链接,它应该期望获得什么样的数据(例如&lt;a type="application/pdf" ...&gt;
  • @Quentin 谢谢。是的,我知道这一点。我从role="button" 开始,但它不起作用(在使用&lt;button&gt; 而不是&lt;a&gt; 之后)。我的实现特别需要&lt;a&gt; 而不是&lt;button&gt;。所以在修补了很多之后,我发现了这个解决方法(很可能是一个 BS 错误)!
【解决方案2】:

直接在 html 标记中(在您可能希望将引导主题留在设计中的其他位置的情况下)..

尝试示例..

<button style="border: transparent;">
<button style="border: 1px solid black;">

..ect,.取决于想要的效果。

【讨论】:

    【解决方案3】:

    对于 sass 用户,Bootstrap 4 应该通过覆盖变量来操作。

    如果您想在按钮周围禁用框阴影:

    $btn-focus-box-shadow: none;
    

    您还可以使用以下方法禁用焦点周围的框阴影:

    $input-focus-box-shadow: none;
    

    或两者都有一个变量:

    $input-btn-focus-box-shadow: none;
    

    【讨论】:

      【解决方案4】:

      您可以使用按钮的焦点事件。 这在有角度的情况下有效

      <button (focus)=false >Click</button
      

      【讨论】:

        【解决方案5】:

        我找到了一个解决方案,只需在您的 css 代码中添加以下行。

        button:focus { outline: none }
        

        【讨论】:

          【解决方案6】:

          我没有找到既不破坏可访问性也不破坏功能的可靠答案。

          也许结合几个整体效果会更好。

          <h1
            onmousedown="this.style.outline='none';"
            onclick="this.blur(); runFn(this);"
            onmouseup="this.style.outline=null;"
          >Hello</h1>
          

          function runFn(thisElem) { console.log('Hello: ', thisElem); }

          【讨论】:

            【解决方案7】:

            2021焦点可见解决方案

            注意 1:在下面列出的 3 个选项中,按钮的行为方式相同(点击时没有焦点环),但选择和输入的默认行为略有不同。 只有选项 3 始终移除按钮、输入和选择周围的焦点环。请比较所有方法并确保您了解其中的含义。

            注意 2:由于 CSS 的级联特性,CSS 规则的顺序很重要。

            选项 1:使用 :focus-visible 伪类

            :focus-visible 伪类可用于为不通过键盘导航(即通过触摸或鼠标单击)的用户消除难看的轮廓和按钮和各种元素上的焦点环。

            警告:截至 2021 年,:focus-visible pseudo-class is ** widely supported across modern browsers but fails on fringe browsers**。如果旧浏览器支持很重要,下面选项 2 中的 Javascript polyfill 是最接近的近似值。

            /**
             * Remove focus styles for non-keyboard focus.
             */
            :focus:not(:focus-visible) {
              outline: 0;
              box-shadow: none;
            }
            
            /**
             * Cross-browser styles for explicit focus via 
             * keyboard-based (eg Tab) navigation or the
             * .focus-visible utility class.
             */
            :focus,
            .focus-visible:focus:not(:focus-visible) {
              outline: 0;
              box-shadow:
                0 0 0 .2rem #fff,
                0 0 0 .35rem #069;
            }
            <h3>Defaults:</h3>
            <button>Foo</button>
            <input type="button" value="Bar"/> 
            <select><option>Baz</option></select>
            <input type="text" placeholder="Qux"/>
            <textarea placeholder="Quux" rows="1"></textarea>
            
            <h3>Force focus on click:</h3>
            <button class="focus-visible">Foo</button>
            <input class="focus-visible" type="button" value="Bar"/> 
            <select class="focus-visible"><option>Baz</option></select>
            <input class="focus-visible" type="text" placeholder="Qux"/>
            <textarea class="focus-visible" placeholder="Quux" rows="1">
            </textarea>

            选项 2:使用 .focus-visible polyfill

            此解决方案使用普通的 CSS 类而不是上面提到的伪类,并且具有更广泛的浏览器支持(2021 年)。它需要在您的 HTML 中添加 1 或 2 个 Javascript;一个用于official focus-visible polyfill,另一个用于不支持support classList 的旧版浏览器。

            注意:在 Chrome 中,polyfill 处理选择的方式似乎与原生 :focus-visible 伪类不同。

            /**
             * Cross-browser focus ring for explicit focus 
             * via keyboard-based (eg Tab) navigation or the
             * .focus-visible utility class.
             */
            :focus {
              outline: 0;
              box-shadow:
                0 0 0 .2rem #fff,
                0 0 0 .35rem #069;
            }
            
            /**
             * Remove focus ring for non-explicit scenarios.
             */
            :focus:not(.focus-visible) {
              outline: 0;
              box-shadow: none;
            }
            <h3>Defaults:</h3>
            <button>Foo</button>
            <input type="button" value="Bar"/> 
            <select><option>Baz</option></select>
            <input type="text" placeholder="Qux"/>
            <textarea placeholder="Quux" rows="1"></textarea>
            
            <h3>Force focus on click:</h3>
            <button class="focus-visible">Foo</button>
            <input class="focus-visible" type="button" value="Bar"/> 
            <select class="focus-visible"><option>Baz</option></select>
            <input class="focus-visible" type="text" placeholder="Qux"/>
            <textarea class="focus-visible" placeholder="Quux" rows="1">
            </textarea>
            
            <!-- place this code just before the closing </html> tag -->
            <script src="https://cdn.polyfill.io/v2/polyfill.js? 
            features=Element.prototype.classList"></script>
            <script src="https://unpkg.com/focus-visible"></script>

            选项 3:使用全局键导航与鼠标导航状态

            焦点可见的反向解决方案是禁用mousemove 上的轮廓,并在keydown -&gt; "Tab" 上启用它们。在这种情况下,您必须指定哪些元素应该显示轮廓,而不是指定哪些元素不应该显示轮廓。

            document.addEventListener("mousemove", () => 
              document.body.classList.remove("focus-visible")
            );
            
            document.addEventListener("keydown", ({key}) => 
              (key === "Tab") && document.body.classList.add("focus-visible")
            );
            /**
             * Cross-browser focus ring for explicit focus 
             * via keyboard-based (eg Tab) navigation or the
             * .focus-visible utility class.
             */
            :focus {
              outline: 0;
              box-shadow:
                0 0 0 .2rem #fff,
                0 0 0 .35rem #069;
            }
            
            /**
             * Remove focus ring for non-explicit scenarios.
             */
            body:not(.focus-visible) :focus:not(.focus-visible) {
              outline: 0 !important;
              box-shadow: none !important;
            }
            <h3>Defaults:</h3>
            <button>Foo</button>
            <input type="button" value="Bar"/> 
            <select><option>Baz</option></select>
            <input type="text" placeholder="Qux"/>
            <textarea placeholder="Quux" rows="1"></textarea>
            
            <h3>Force focus on click:</h3>
            <button class="focus-visible">Foo</button>
            <input class="focus-visible" type="button" value="Bar"/> 
            <select class="focus-visible"><option>Baz</option></select>
            <input class="focus-visible" type="text" placeholder="Qux"/>
            <textarea class="focus-visible" placeholder="Quux" rows="1">
            </textarea>

            关于可访问性的说明

            删除所有焦点环(如:focus { outline: none; }:focus { outline: 0; })是一个已知的可访问性问题,不推荐使用。此外,无障碍社区中有些人希望您永远不要删除焦点环轮廓,而是让所有内容都具有:focus 样式——outlinebox-shadow 可能是有效的,如果样式适当的。

            最后,可访问性社区中的一些人认为,开发人员不应在其网站上实现:focus-visible,直到所有浏览器都实现并公开用户偏好,让人们选择是否所有项目都应该是可聚焦的。我个人并不认同这种想法,这就是为什么我提供了这个我觉得比有害的:focus { outline:none } 好得多的解决方案。我认为:focus-visible 是设计关注点和可访问性关注点之间的一个愉快的媒介。

            资源:

            演示:

            【讨论】:

            • 但如果连 Chrome 都不支持,它可能不是最好的解决方案(目前)
            • 你有什么建议?
            • 像其他答案所说的那样隐藏大纲,直到这个解决方案更加标准化
            • 根据我的阅读,如果可访问性是一个问题,使用&lt;whatever&gt;:focus { outline: none } 隐藏大纲 carte blanche 比这个解决方案更糟糕。实际上,可访问性社区中有些人宁愿您永远不要删除轮廓,而是让 everything 具有 :focus 样式(轮廓或框阴影),并且不想支持 :focus-visible直到浏览器实现了一种方法,让用户指定用户偏好是否所有项目都应该是可聚焦的。我喜欢认为:focus-visible 是设计关注点和 a11y 之间的一种快乐媒介。
            • 我认为任何一种方式都可以正常工作。只要代码负载保持小而简单,我怀疑它会带来一些其他不会实现它的人。我相信它是您随心所欲地策划的答案。
            【解决方案8】:

            这里有两种可能的解决方案。

            1.) button type="button" className="btn-cart"onClick{(event)=&gt;this.blur(event)}

            2.) button type="button" className="btn-cart" onclick={this.blur}

            这两种解决方案都会删除按钮周围的突出显示部分 即 -> blur() 有自己的规范,可以删除周围突出显示的部分。

            【讨论】:

              【解决方案9】:

              有点核,但这是在 Angular 9 上对我有用的简单方法。与 causon 一起使用,因为它会影响每个 html 元素。

              *:focus {
                outline: 0 !important;
              }
              

              【讨论】:

                【解决方案10】:

                虽然这里提供的 CSS 解决方案有效,但

                对于喜欢使用Bootstrap 4方式的任何人,如官方Bootstrap Theming guide所建议的那样, 这应该会有所帮助:

                在您添加变量覆盖的 custom.scss 文件(请参阅上面的指南 ^)中,添加以下变量以删除按钮的框阴影:

                // import bootstrap's variables & functions to override them
                @import "node_modules/bootstrap/scss/functions";
                @import "node_modules/bootstrap/scss/variables";
                @import "node_modules/bootstrap/scss/mixins";
                
                // override the variables you want (you can look them up in node_modules/bootstrap/scss/variables file, they're the ones that have the !default keyword at the end)
                $btn-focus-box-shadow: none;
                
                // option A: include all of Bootstrap (see the above guide for other options)
                @import "node_modules/bootstrap/scss/bootstrap";
                

                这对我有用。

                请注意,引导程序的变量文件中有许多用于 box-shadow 的变量,对于其他控件也是如此,因此如果您想使用它们可能需要更多的研究和/或者这个特定的变量对你不起作用。

                【讨论】:

                  【解决方案11】:

                  与 TS 解决方案反应

                    const btnRef = useRef<HTMLButtonElement | null>(null);
                    const handleOnMouseUp = () => {
                      btnRef.current?.blur();
                    };
                    
                    <button
                      ref={btnRef}
                      onClick={handleOnClick}
                      onMouseUp={handleOnMouseUp}
                    >
                      <span className="icon-plus"></span> Add Page
                    </button>
                  

                  【讨论】:

                    【解决方案12】:

                    如果您想在mousedown 而不是键盘tab 上完成轮廓的删除,并且您正在使用VueJS,则解决方案如下:

                    <button @mousedown="$event.preventDefault()">No Online On Click</button>
                    

                    这基本上可以防止它在点击时接收焦点,但任何其他接收焦点的方式都会保持活动状态。

                    【讨论】:

                      【解决方案13】:

                      对于使用 react-bootstrap 并遇到此问题的任何人,这是我为使其正常工作所做的工作:

                      .btn:focus {
                          /* the !important is really the key here, it overrides everything else */
                          outline: none !important;
                          box-shadow: none !important;
                      }
                      

                      在添加 !important 之前,事情并没有奏效。

                      【讨论】:

                      • 谢谢伙计,这就是我要找的东西
                      【解决方案14】:

                      我很好奇为什么有人要删除大纲。就像许多人提到的那样,如果您删除大纲,则会出现可访问性问题。使用屏幕阅读器等辅助技术的用户在访问网站/应用程序时需要知道焦点在哪里。我知道按钮周围的蓝色可能会“搞砸”设计,但是,您可以使用 CSS 更改颜色:

                      outline-color: your color hex here;
                      

                      另一种编辑方法是在焦点上添加边框。

                      【讨论】:

                        【解决方案15】:

                        如果 button:focus {box-shadow: none} 不适合您,可能有一些库添加了边框,就像我使用伪选择器 ::after 一样。

                        所以我使用以下解决方案删除了​​焦点显示的边框:

                        button:focus::after {
                            outline: none;
                            box-shadow: none;
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-12-02
                          • 2011-01-04
                          • 2019-11-05
                          • 1970-01-01
                          相关资源
                          最近更新 更多