Input effect on keyboard tab -> focus, but NOT on

2019-02-05 00:13发布

When a user 'tabs over' to an input, I want the focus effect to be normally displayed, but on click, I don't want it to be visible.

User hits tab, now focussed on toggle button, I would like the toggle button to have slight glowing outline, which I'm currently able to do.

Now,

User clicks on the toggle button or it's associated label, toggle changes as usual, BUT, I want the glow to never appear in the first place, or to disappear as quickly as possible.

I know about .blur(), and right now I'm having to use a setTimeout for a lazy fix, but I'd like to know if there's a better way to accomplish this, or if there's possibly a CSS only solution

3条回答
Lonely孤独者°
2楼-- · 2019-02-05 00:46

I think a lot of front-end developers struggle to find a balance between aesthetics and the best-practices for accessibility. This seems like a great compromise.

Here's how I do it. The idea is to toggle outlining on when the user uses the tab key and turn it back off when they click.

JS

document.addEventListener('keydown', function(e) {
  if (e.keyCode === 9) {
    $('body').addClass('show-focus-outlines');
  }
});

document.addEventListener('click', function(e) {
  $('body').removeClass('show-focus-outlines');
});

Styles

body:not(.show-focus-outlines) button:focus, 
body:not(.show-focus-outlines) [tabindex]:focus {
  outline: none;
}
查看更多
forever°为你锁心
3楼-- · 2019-02-05 00:55

If you use the what-input.js plugin you can apply styles specifically for keyboard users. You can use the following code to highlight a button that has been tabbed to. I've found what-input to be a reliable plugin (comes bundled with Zurb Foundation) and is currently regularly maintained.

// scss
body[data-whatinput="keyboard"] {
  button {
    &:focus {
      // other highlight code here
      box-shadow: 0 0 5px rgba(81, 203, 238, 1);
    }
  }
}

or

/* vanilla css */
body[data-whatinput="keyboard"] button:focus {
  box-shadow:  0 0 5px rgba(81, 203, 238, 1);
}
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-02-05 01:00

I'm currently doing something similar for my company. Unfortunately you must use JavaScript since CSS doesn't support this use case.

Here's what I've done.

var btns = document.querySelectorAll('button');

var onMouseDown = function (evt) {
  evt.target.dataset.pressed = 'true';
};

var onMouseUp = function (evt) {
  evt.target.dataset.pressed = 'false';
};

var onFocus = function (evt) {
  var element = evt.target;
  if (element.dataset.pressed !== 'true') {
    element.classList.add('focus');
  }
};

var onBlur = function (evt) {
  evt.target.classList.remove('focus');
};

for(var i = 0, l = btns.length; i < l; i++) {
  btns[i].addEventListener('mousedown', onMouseDown);
  btns[i].addEventListener('mouseup', onMouseUp); 
  btns[i].addEventListener('focus', onFocus);
  btns[i].addEventListener('blur', onBlur);
}
* { box-sizing: border-box; }

body { background-color: white; }

button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  min-width: 100px;
  margin: 0 1px;
  padding: 12px 10px;
  font-size: 15px;
  color: white;
  background-color: #646e7c;
  border: none;
  border-radius: 5px;
  box-shadow: 0 2px 2px 0 rgba(0,0,0,.2);
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

button:focus { outline: none; }

button:active {
  -webkit-transform: translateY(1px);
  -moz-transform: translateY(1px);
  transform: translateY(1px);
  box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2);
}

button.focus {
  font-weight: bold;
}

button.primary { background-color: #2093d0; }

button.success { background-color: #71a842; }

button.danger { background-color: #ef4448; }
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <button>Default</button>
  <button class="primary">Primary</button>
  <button class="success">Success</button>
  <button class="danger">Danger</button>
</body>
</html>

Basically instead of relying on browser's native focus I add/remove a focus class on my button depending on the situation.

查看更多
登录 后发表回答