Search code examples
javascripthtmlcssuser-experience

How to use keyboard tab on hidden radio buttons


Within a form I have the following generic html:

<input type="text" autofocus placeholder="Full name" />

<input name="yesno" type="radio" value="Yes" id="yes">
<label for="yes">Yes</label>

<input name="yesno" type="radio" value="No" id="no">
<label for="no">No</label>

In this form I can TAB from the text input into the radio buttons and select "Yes" or "No" using the left / right keys.

I then apply some styling to make the radio buttons conform with the design:

input[type="text"] {
  height: 60px;
  text-indent: 1em;
}

input[type="radio"] {
  display: none;
}

input[type="radio"]+label {
  color: #106AA2;
  background: #fff;
  font-weight: 100;
  text-align: center;
  padding: 1em 2em;
  height: auto;
  font-size: 1.3em;
  border: 1px solid #C5DBE8;
  display: inline-block;
  letter-spacing: inherit;
  vertical-align: middle;
  cursor: pointer;
}

input[type="radio"]:checked+label {
  background: linear-gradient(#1275B2, #106AA2);
  color: #fff;
}
<input type="text" autofocus placeholder="Full name" />

<input name="yesno" type="radio" value="Yes" id="yes">
<label for="yes">Yes</label>

<input name="yesno" type="radio" value="No" id="no">
<label for="no">No</label>

However, I can now no longer TAB from the text input to the radio buttons. I am aware this is because I have display:noned them.

Is there a cross-browser way to enable a user to TAB onto these radio buttons?

Ideally I am looking for a solution that is pure CSS, however I am open to a javascript solution.


Solution

  • Don't make it non-existent with display: none; just shrink it.

    You can just set the width and height to 0 to make the input not visible but functional with tabbing.

    input[type="text"] {
      height: 60px;
      text-indent: 1em;
    }
    
    input[type="text"]:focus {
      outline: solid 1px lightblue;
    }
    
    input[type="radio"] {
      /* display: none; */
      width: 0;
      height: 0;
    }
    
    input[type="radio"]+label {
      color: #106AA2;
      background: #fff;
      font-weight: 100;
      text-align: center;
      padding: 1em 2em;
      height: auto;
      font-size: 1.3em;
      border: 1px solid #C5DBE8;
      display: inline-block;
      letter-spacing: inherit;
      vertical-align: middle;
      cursor: pointer;
    }
    
    input[type="radio"]:checked+label {
      background: linear-gradient(#1275B2, #106AA2);
      color: #fff;
    }
    
    input[type="radio"]:focus+label {
      outline: solid 1px black;
    }
    <input type="text" autofocus placeholder="Full name" />
    
    <input name="yesno" type="radio" value="Yes" id="yes">
    <label for="yes">Yes</label>
    
    <input name="yesno" type="radio" value="No" id="no">
    <label for="no">No</label>