0

I am trying to get CSS only radio and checkbox buttons using FontAwesome. I have a jsfiddle here.

I am using the following CSS which works well, when the checkbox has a label with content. i am now trying to just create a matrix of checkboxes in a table on my page and the icons appear OK but cannot be clicked / changed state.

My CSS:

/**
 * Checkboxes
 */


input[type=checkbox] {
  display: none;
}


/* to hide the checkbox itself */

input[type=checkbox] + label:before {
  display: inline-block;
  letter-spacing: 5px;
  content: "\f0c8";
  font-family: 'Font Awesome 5 Pro';
}


/* unchecked icon */

input[type=checkbox]:checked + label:before {
  content: "\f14a";
  letter-spacing: 5px;
}


/**
 * Radio buttons
 */

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


/* to hide the radio itself */

input[type=radio] + label:before {
  display: inline-block;
  letter-spacing: 5px;
  content: "\f111";
  font-family: 'Font Awesome 5 Pro';
}


/* unchecked icon */

input[type=radio]:checked + label:before {
  content: "\f192";
  letter-spacing: 5px;
}

input[type=checkbox] + label:hover,
input[type=radio] + label:hover {
  cursor: pointer;
}

My HTML:

<div>
  <i class="fas fa-square"></i> SAMPLE UNCHECKED
  <br/>
  <i class="fas fa-check-square"></i> SAMPLE CHECKED
  <br/>
  <br/>
  <br/>
  <input name="access_chk[]" class="access_chk" type="checkbox" checked>
  <label for="access_chk[]"></label>
  <br/>
  <input name="access_chk[]" class="access_chk" type="checkbox" checked>
  <label for="access_chk[]"></label>
  <br/>
  <input name="access_chk[]" class="access_chk" type="checkbox" checked>
  <label for="access_chk[]"></label>
</div>
TheRealPapa
  • 4,393
  • 8
  • 71
  • 155
  • What is your question? – Julien Ambos Jan 14 '18 at 23:06
  • 1
    The icons cannot be clicked, because you are not clicking the checkbox, just the pseudo element before. The only walk around, to style checkboxes, is to mimic the events with js – Marcelo Origoni Jan 14 '18 at 23:07
  • Hi @Julien Ambos the checkboxes / radios are not working using FA. See fiddle. – TheRealPapa Jan 14 '18 at 23:08
  • Hi @Andrei Gheorghiu I am using each checkbox to trigger a on the fly AJAX update on back end. So I do not need the values. But I have added values to JSFiddle and still the same. – TheRealPapa Jan 14 '18 at 23:10
  • 1
    @MarceloOrigoni are you sure about that? http://jsfiddle.net/d0do7sff/19/ – Jon P Jan 14 '18 at 23:33
  • 1
    I'm arguing this is not a dupe of the flagged question. The flagged question is regarding padding/spacing. This question is regarding actual functionality. The solutions are quite different. – Jon P Jan 15 '18 at 00:12

2 Answers2

5

Here's a possible solution: Since your labels are empty anyway, why use them at all (unless you have some hidden screenreader-properties, you don't need empty labels...ever).

The trick is to use the pseudo-elements on the checkboxes themselves instead of the labels. To make the checkboxes work, use visbility:hidden on them and visibility:visible on the pseudo-elements.

Minor drawback: You'll have to fiddle around with font-size a bit, otherwide the glyphs might appear too small.

input[type=checkbox] {
  visibility:hidden;
}

input[type=checkbox]::before {
  visibility: visible;
  font-size:16px;
  display: inline-block;
  letter-spacing: 5px;
  content: "\f0c8";
  font-family: 'Font Awesome 5 Free';
}

input[type=checkbox]:checked::before {
  content: "\f14a";
  letter-spacing: 5px;
  font-family: 'Font Awesome 5 Free';
}
<link href="https://use.fontawesome.com/releases/v5.0.4/css/all.css" rel="stylesheet">
<div>
  <input type="checkbox" checked>
  <br/>
  <input type="checkbox" checked>
  <br/>
  <input type="checkbox" checked>
</div>
mmgross
  • 3,064
  • 1
  • 23
  • 32
  • Even better solution. Many thanks! – TheRealPapa Jan 14 '18 at 23:43
  • I wouldn't say my solution is better. It might fit your particular case better. But Jon P points out something very important about how to use labels and his solution is equally valid. – mmgross Jan 14 '18 at 23:58
  • Happy for yours to be the accepted answer. Mine points out the fundamental issue. Yours provides a more streamlined solution. – Jon P Jan 15 '18 at 00:13
  • 1
    Its not a good practice to use pseudo-elements `:before`, `:after` on input elements. It works only on chrome, `firefox` does not support it. Check your answer in `firefox` you will see the difference. [**Read this**](https://stackoverflow.com/questions/2587669/can-i-use-a-before-or-after-pseudo-element-on-an-input-field) – Bhuwan Jan 15 '18 at 06:56
  • Damn, you're right. @TheRealPapa I suggest, you accept the other answer again, mine is flawed. – mmgross Jan 15 '18 at 08:57
  • Thought I'd checked this in FF, apparently not. Good catch @BhuwanBhatt – Jon P Jan 15 '18 at 22:18
2

Note that the for attribute applies to the id attribute of the target element not the name attribute.

Change your markup to:

<div>
  <i class="fas fa-square"></i> SAMPLE UNCHECKED
  <br/>
  <i class="fas fa-check-square"></i> SAMPLE CHECKED
  <br/>
  <br/>
  <input name="access_chk[]" value="1" class="access_chk" type="checkbox" id="cb1" checked>
  <label for="cb1">LABEL WITH CONTENT</label>
  <br/>
  <input name="access_chk[]" value="2" class="access_chk" type="checkbox" id="cb2" checked>
  <label for="cb2"></label>
  <br/>
  <input name="access_chk[]" value="3" class="access_chk" type="checkbox" id="cb3" >
  <label for="cb3"></label>
  <br/>
  <input name="access_chk[]" value="4" class="access_chk" type="checkbox" id="cb4" checked>
  <label  for="cb4"></label>
</div>

Demo

Jon P
  • 19,442
  • 8
  • 49
  • 72