Because input is one of those elements that cannot have content, and thus, don't take :before or :after, as this relies on content: ...;.
Explanation:
Check this example:
<p class="my-element">some text</p>
If you apply
.my-element:before {
content: "My element: ";
}
the browser will render it as
<p class="my-element">My element: some text</p>
So p can have something inside - content.
Now where is the browser supposed to put "My element: " in the following case?
<input type="checkbox" class="my-element" />
This element cannot have anything inside it, so there is nothing that content: "My element: " could possibly be added to.
Solution
So if you want to apply styles using :checked, and you want to hide the checkbox, yet still need it 'clickable', you need to attach a label to it not by wrapping the checkbox, but by using the for attribute of the label element, which must match the id attribute of the checkbox. Place the label after the input in the HTML, and you can use :before or :after on the label element (which can have content):
<input type="checkbox" id="a1" style="display: none;" />
<label class="checkmarklabel" for="a1"></label>
:checked + .checkmarklabel:before {
/* put the required CSS for your font's checkmark here */
}