开发者

Forcing a tab stop on a hidden element? Possible?

开发者 https://www.devze.com 2023-01-12 18:38 出处:网络
The site is here I have opt to using the radiobutton\'s labels as customized buttons for them. This means the radio inputs themselves are display:none. Because of this, the browsers don\'t tab stop a

The site is here

I have opt to using the radiobutton's labels as customized buttons for them. This means the radio inputs themselves are display:none. Because of this, the browsers don't tab stop at the radio labels, but I want them to.

I tried forcing a tabindex to them, but no cigar.

I have came up with just putting a pointless checkbox right before the labels, and set it to width: 1px; and height 1px; which seems to only really work on chrome & safari.

So do you have any other ideas for forcing a tab stop at those locations without showing an element?

Edit:

Just incase someone else comes by this, this is how I was able to insert small checkboxes into chrome & safari using JQuery:

if ($.browser.safari) {
    $("label[for='Unlimited']").parent().after('<input style="height:1px; width:1px;" type="checkbox">');
    $("label[for='cash']").parent().after('<input style="height:1px; width:1px;" type="checkbox">');
    $("label[for='Length12']").p开发者_运维技巧arent().after('<input style="height:1px; width:1px;" type="checkbox">');
}

Note: $.browser.webkit was not becoming true...so I had to use safari


a working solution in my case to enable tab selection / arrow navigation was to set the opacity to zero rather than a "display: none"

.styled-selection input {
    opacity: 0;         // hide it visually
    z-index: -1;        // avoid unintended clicks
    position: absolute; // don't affect other elements positioning
}


Keep the radio input hidden, but set tabindex="0" on the <label> element of reach radio input.

(A tab index of 0 keeps the element in tab flow with other elements with an unspecified tab index which are still tabbable.)


If you separate the label from any field and set a tabIndex you can tab to it and capture mouse and key events. It seems more sensible to use buttons or inputs with type="button", but suit yourself.

<form>
    <fieldset>
        <input value="today">
        <label tabIndex="0" onfocus="alert('label');">Label 1</label>
    </fieldset>
</form>


I have an alternative answer that I think has not been mentioned yet. For recent work I've been reading the Mozilla Developer Docs MDN Docs, Forms, especially the Accessibility Section MDN Docs, Accessible HTML(5), for information related to keyboard accessibility and form structure.

One of the specific mentions in the Accessibility section is to use HTML5 elements when and where possible -- they often have cross-browser and more accessible support by default (not always true, but clear content structure and proper elements also help screen reading along with keyboard accessibility).

Anyway, here's a JSFiddle: JSFiddle::Keyboard Accessible Forms

Essentially, what I did was:

  1. shamelessly copy over some of the source code from a Mozilla source code to a JSFiddle (source in the comments of the fiddle)
  2. create a TEXT-type and assign it the "readonly" HTML5 attribute
  3. add attribute tabindex="0" to the readonly
  4. Modify the "readonly" CSS for that input element so it looks "blank" or hidden"

HTML

<title>Native keyboard accessibility</title>
<body>

  <h1>Native keyboard accessibility</h1>

  <hr>

  <h2>Links</h2>

  <p>This is a link to <a href="https://www.mozilla.org">Mozilla</a>.</p>

  <p>Another link, to the <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>

  <h2>Buttons</h2>

  <p>
    <button data-message="This is from the first button">Click me!</button>
    <button data-message="This is from the second button">Click me too!
    </button>
    <button data-message="This is from the third button">And me!</button>
  </p>

  <!-- "Invisible" HTML(5) element -->
  <!-- * a READONLY text-input with modified CSS... -->
  <hr>
  <label for="hidden-anchor">Hidden Anchor Point</label>
  <input type="text" class="hidden-anchor" id="hidden-anchor" tabindex="0" readonly />
  <hr>

  <h2>Form</h2>

  <form name="personal-info">
    <fieldset>
      <legend>Personal Info</legend>
      <div>
        <label for="name">Fill in your name:</label>
        <input type="text" id="name" name="name">
      </div>
      <div>
        <label for="age">Enter your age:</label>
        <input type="text" id="age" name="age">
      </div>
      <div>
        <label for="mood">Choose your mood:</label>
        <select id="mood" name="mood">
          <option>Happy</option>
          <option>Sad</option>
          <option>Angry</option>
          <option>Worried</option>
        </select>
      </div>
    </fieldset>
  </form>


  <script>
    var buttons = document.querySelectorAll('button');

    for(var i = 0; i < buttons.length; i++) {
      addHandler(buttons[i]);
    }

    function addHandler(button) {
      button.addEventListener('click', function(e) {
        var message = e.target.getAttribute('data-message');
        alert(message);
      })
    }
  </script>

</body>

CSS Styling

input {
  margin-bottom: 10px;
}

button {
  margin-right: 10px;
}

a:hover, input:hover, button:hover, select:hover,
a:focus, input:focus, button:focus, select:focus {
  font-weight: bold;
}


.hidden-anchor {
  border: none; 
  background: transparent!important;
}
.hidden-anchor:focus {
  border: 1px solid #f6b73c;
}

BTW, you can edit the CSS rule for .hidden-anchor:focus to remove the highlight for the hidden anchor if you want. I added it just to "prove" the concept here, but it still works invisibly as requested.

I hope this helps!


My preference:

.tab-only:not(:focus) {
  position: fixed;
  left: -999999px;
}

<button class="tab-only">Jump to main</button>


Another great option would be to nest your input + div in a label and hide the input by setting width and height to 0px instead of display: none

This method even allows you to use pseudo-classes like :focus or :checked by using input:pseudo + styleDiv

<label>
    <input type="radio">
    <div class="styleDiv">Display text</div>
</label>

input
{
    width: 0px;
    height: 0px;
}

input + .styleDiv
{
    //Radiobutton style here
    display: inline-block
}

input:checked + .styleDiv
{
   //Checked style here
}


Discard the radio-buttons and instead; keep some hidden fields in your code, in which you store the selected value of your UI components.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号