Home > Software design >  Using button HTML element for implementing custom checkbox
Using button HTML element for implementing custom checkbox

Time:08-06

Is it viable to use <button> element instead of <input type="checkbox" />? Can it break accessibility or in any way affect the user experience? From what I noticed, we lose the element's value and onChange callback, but that's something easily fixed in React. If anyone wonders, the reason for using would be much easier customization (styling).

CodePudding user response:

To respect accessibility (a11y), if you wish to customize a checkbox, you can use anything, but you will have to map to your change event using an hidden but real <input type="checkbox" /> behind it.

Here is an example taken from the source below.

html {
  box-sizing: border-box;
  background: #f2f2f2;
  padding: 20px 50px
}

/* Inherit box-sizing to make it easier to change the property
 * for components that leverage other behavior.*/
*,
*::before,
*::after {
  box-sizing: inherit;
}

/*style form to limit width and highlight the long label*/
form {
    margin: 1rem auto;
    max-width: 750px;
}

/*style wrapper to give some space*/
.wrapper {
    position: relative;
    margin-bottom: 1rem;
    margin-top: 1rem;
}

/*style label to give some more space*/
.wrapper label {
    display: block;
    padding: 12px 0 12px 48px;
}

/*style and hide original checkbox*/
.wrapper input {
  height: 40px;
  left: 0;
  opacity: 0;
  position: absolute;
  top: 0;
  width: 40px;
}

/*position new box*/
.wrapper input   label::before {
  border: 2px solid;
  content: "";
  height: 40px;
  left: 0;
  position: absolute;
  top: 0;
  width: 40px;
  border-radius: 50%;
}

/*radio pseudo element styles*/
.wrapper input   label::after {
  content: "";
  opacity: 0;
  border: 10px solid;
  border-radius: 50%;
  position: absolute;
  left: 10px;
  top: 10px;
  transition: opacity 0.2s ease-in-out;
}

/*reveal check for 'on' state*/
.wrapper input:checked   label::after {
  opacity: 1;
}

/*focus styles*/
.wrapper input:focus   label::before {
  box-shadow: 0 0 0 3px #ffbf47;  
  outline: 3px solid transparent; /* For Windows high contrast mode. */
}
<form>
  <fieldset>
    
    <legend>
      <h3>What type of accessibilty issues do you see most often?</h3>
    </legend>

    <div >
      <input id="a11y-issue-1" name="a11y-issues" type="radio" value="no-issues">
      <label for="a11y-issue-1">There are no issues</label>
    </div>

    <div >
      <input id="a11y-issue-2" name="a11y-issues" type="radio" value="no-focus-styles">
      <label for="a11y-issue-2">Focus styles are not present</label>
    </div>

    <div >
      <input id="a11y-issue-3" name="a11y-issues" type="radio" value="html-markup">
      <label for="a11y-issue-3">HTML markup is used in bizarre way. Also, what happens if the label text is very looooooooong, like this one?</label>
    </div>
    
  </fieldset>
</form>

Source: https://webdesign.tutsplus.com/tutorials/how-to-make-custom-accessible-checkboxes-and-radio-buttons--cms-32074

  • Related