我们有一些用css样式的按钮,并有一些这样的图标:
此按钮具有默认的轮廓属性,因此每次单击该按钮时,它都有一个轮廓(铬蓝色):
要摆脱它,我们当然可以覆盖此属性,例如:
outline: none
但是,当我们依次浏览并到达此按钮时,它也没有任何轮廓,这对于可访问性来说是一个不好的做法。
我们能否实现这一点,以便仅在带有选项卡的按钮上出现此轮廓,而在单击它时不出现?
仅作为信息:我们还有一些 a 标签,这些标签在外观上看起来像这样,并且通过标签,我们可以精确地实现所需的这种行为,只有当我们点击该链接时,轮廓才会出现,但不能点击。我们只希望按钮标签也具有完全相同的行为。
答案 0 :(得分:6)
当您单击某个元素时,它会在其上投射:active
,因此您想将:active
和:focus
链接在一起:
button:active:focus {
outline: none;
}
<button>Button</button>
正如您所说的,这不适用于其他CSS,在这种情况下,您必须实现一个有点复杂的解决方案,即在用户第一次使用Tab时在正文中添加类,否则一起删除轮廓
function handleFirstTab(e) {
if (e.keyCode === 9) { // the "I am a keyboard user" key
document.body.classList.add('user-is-tabbing');
window.removeEventListener('keydown', handleFirstTab);
}
}
window.addEventListener('keydown', handleFirstTab);
body:not(.user-is-tabbing) button:focus {
outline: none;
}
button {
background-color: red;
}
<button>Button</button>
答案 1 :(得分:1)
我们能否做到这一点,以便仅在我们使用带有选项卡的按钮出现时才显示此轮廓,而在单击它时不显示?
是的,您可以使用 :focus-visible
。
如果您希望在按钮被标签化且未被点击时显示轮廓,请在 outline: none
上的按钮上设置 :focus
而不是在 :focus-visible
上:
button:focus:not(:focus-visible) {
outline: none;
}
答案 2 :(得分:0)
如果您的图标是某种字体,则最好的选择是使用Traceback (most recent call last):
30: from bin/rails:4:in `<main>'
29: from
/Users/username/project/vendor/bundle/ruby/2.5.0/gems/activesupport-
5.1.0/lib/active_support/dependencies.rb:292:in `require'
28: from
/Users/username/project/vendor/bundle/ruby/2.5.0/gems/activesupport-
5.1.0/lib/active_support/dependencies.rb:258:in `load_dependency'
27: from
/Users/username/project/vendor/bundle/ruby/2.5.0/gems/activesupport-
5.1.0/lib/active_support/dependencies.rb:292:in `block in require'
26: from
/Users/username/project/vendor/bundle/ruby/2.5.0/gems/bootsnap-
1.3.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:29:in
`require'
.
.
.
.
58:in `load_dependency'
1: from /Users/username/project
/vendor/bundle/ruby/2.5.0/gems/activesupport-
5.1.0/lib/active_support/dependencies.rb:292:in `block in require'
/Users/username/project/vendor/bundle/ruby/2.5.0/gems/bootsnap-
1.3.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in
`require': cannot load such file -- active_storage/engine
(LoadError)
gemfile
ruby '2.5.1'
gem 'rails', '5.1.0'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
application.rb
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Project
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails
version.
config.load_defaults 5.2
# Settings in config/environments/* take precedence over those
specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after
loading
# the framework and any gems in your application.
# Don't generate system test files.
config.generators.system_tests = nil
end
end
:
text-shadow
button {
outline: none!important;
background: transparent;
border-color: transparent;
color: red;
font-size: 30px;
}
button:focus i.fa {
text-shadow: 1px 1px 5px rgba(255, 0, 0, 0.7);
}
在此示例中,我使用font-awesome-4.7并用text-shadow
generator生成了<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<button class="btn">
<i class="fa fa-heart-o"></i>
</button>
。
答案 3 :(得分:0)
使用.btn:focus{ outline:0; }
删除outline
并使用addEventListener
定位Tab
点击并设置box-shadow
(如果元素上的标签为1>)
document.addEventListener('keydown', function(e) {
var elem=document.getElementById('heart');
if (e.key === 'Tab' && document.activeElement === elem) {
elem.style.boxShadow="0 0 0 0.2rem rgba(0,123,255,.25)";
}
else{
elem.style.boxShadow="none";
}
});
.btn {
width: 80px;
height: 80px;
transform: rotate(-46deg);
border: none;
background: url(https://image.flaticon.com/icons/svg/579/579268.svg);
}
.btn:focus{
outline:0;
}
<button class="btn" id="heart">
</button>
您可以使用此插件通过{strong> css 定位tab
点击:https://github.com/ten1seven/track-focus
body[data-whatinput="keyboard"] .btn:focus {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
答案 4 :(得分:0)
由于上述所有答案在所有情况下均不适用于我(大多数情况至少忽略了一个事实,那就是人们可以再次切换到鼠标,然后必须从按钮中删除boxshow。)总是从事件侦听器中删除),这是我的答案:
如果您的html标记或多或少处于同一级别(因此您不必为整个页面创建侦听器):
上一个元素(其“选项卡”应将焦点切换到按钮)应该具有keydown / keyup事件,然后该事件将运行:
if ($event.keyCode === '9' && !$event.shiftKey) {
$event.target.nextSibling.style.boxShadow = '0 0 5px 1px #305C73';
}
当您还希望支持shift + tab(后退制表)时,下一个元素也需要此功能:
if ($event.keyCode === '9' && $event.shiftKey) {
$event.target.previousSibling.style.boxShadow = '0 0 5px 1px #305C73';
}
按钮本身显示通过其自身的模糊事件将其删除:
$event.target.style.boxShadow = 'none';
按钮本身仍可以将其轮廓设置为无:
outline: none
由于我在后台提出了独立于JS技术的问题,因此这里不包括事件处理部分。但是如果是有角度的应用,则可以使用sth。像这样:
<previousTag (keydown)="addBoxShadowBorButtonOnTab($event)">
<button (blur)="removeBowShadow($event)">
<nextTag (keydown)="addBoxShadowBorButtonOnShiftTab($event)">
在普通的javascript中,这部分的操作类似于上述事件监听器中的操作。
如果您的标签位于其他标签内,并且您具有分层的DOM结构,或者您无法更改“上一个”和“下一个”标签:
就我而言,我们有……。像这样:
<li>
<previousTag>
<button>
</li>
<li>
<nextTag>
<li>
最好注册用于添加boxShadow的keyup / keydown事件的侦听器,因为这样您将更独立于HTML结构和将来的DOM更改。因此,您可以设置轮廓,而与来自哪个元素无关。
在我的Angular应用中,似乎……。像这样:
@HostListener('document:keyup.shift.tab', ['$event'])
@HostListener('document:keyup.tab', ['$event']) onTabHandler(event: KeyboardEvent) {
const focusedElm = event.target;
if (focusedElm.id === 'my-heart-button') {
focusedElm.style.boxShadow = '0 0 5px 1px #305C73';
}
}
删除轮廓仍应与上述完全相同。
这是确保按钮“总是在分页时集中注意力”时始终具有轮廓的唯一方法,但不会在涉及美观的鼠标单击上出现。
答案 5 :(得分:0)
我找到了一个简单的方法,那就是纯 html/css 并且不使用任何 javascript。
将按钮的内容包装在额外的外部元素(例如 div)中,并使用 tabindex="0"
内部元素得到tabindex="-1"
所以代替:
<button>Buttontext</button>
这样做:
<div tabindex="0">
<button tabindex="-1">
Buttontext
</button>
</div>
通过这种方式,您可以在外部 div 上使用 Tab 键,浏览器会绘制其焦点轮廓。当您点击按钮时,您选择了没有轮廓的内部元素 (outline: none
)