Em muitos casos é necessário criar um input radio ou checkbox com uma aparência diferente do padrão, normalmente utilizando uma imagem como botão. Este objetivo pode ser alcançado através de CSS. Então vamos aos exemplos.

Para começar vamos ao clássico input radio de seleção de sexo, como visto abaixo:

Exemplo de input radio de seleção de sexo

Começamos com o HTML, devemos colocar tanto o input radio quanto a imagem dentro do elemento label. Este label deve estar associado ao input através da propriedade for, propriedade que deve conter o id do input. Agora ao ser clicada, a imagem que está dento do label marca o elemento input radio.

<fieldset class="radio-image">
    <label for="M">
        <input type="radio" name="sexo" id="M" value="M">
        <img src="img/male_black.png" alt="Masculino">
    </label>
    <label for="F">
        <input type="radio" name="sexo" id="F" value="F">
        <img src="img/female_black.png" alt="Feminino">
    </label>
</fieldset>

Agora vamos ao estilo CSS.

.radio-image label > input{
    visibility: hidden;
}
.radio-image label > input + img{
    cursor:pointer;
    border:4px solid #EEE;
    border-radius:15px;
    padding:10px;
}
.radio-image label > input:checked + img{
    border:4px solid #3F51B5;
}

Como vemos na linha 1, selecionamos o input radio que é filho imediado do label e alteramos a propriedade visibility para hidden, fazendo o elemento input não ser visível, ou seja, desaparecendo com a bolinha de marcação clássica.

Na linha 4, selecionamos o elemento img adjacente ao input, e alteramos as propriedade da imagem para que ela fique como queremos quando o input radio não está selecionado, no exemplo, alteramos o cursor do mouse, e colocamos uma borda e um padding, bem simples.

Na linha 10, selecionamos o elemento img subjacente ao input, mas com a pseudo classe checked, ou seja, que esteja selecionado. Então alteramos as propriedades para o estado que queremos quando o elemento esteja selecionado.

Agora, a imagem começa com as propriedades da linha 4, e ao ser clicada, como esta dentro do label associado ao input, ele seleciona o input e passa a ter as propriedade definidas no seletor da linha 10.

Bom, o mesmo processo pode ser aplica ao input check com pequenas modificações, vamos ao exemplo.

Exemplo de Checkbox usando imagem
<fieldset class="check-image">
    <label for="like">
        <input type="checkbox" name="like" id="like">
        <i></i>
    </label>
</fieldset>

Neste exemplo trocamos o elemento img, pelo elemento i, no qual colocaremos a imagem que desejamos como fundo.

.check-image label > input{
    visibility: hidden;
}
.check-image label > input + i {
    display:inline-block;
    cursor:pointer;
    width: 70px;
    height:70px;
    background:url(img/heart-regular.svg) no-repeat;
    transition:0.5s;
}
.check-image label > input:checked + i {
    background:url(img/heart-solid.svg) no-repeat;
}

Realizamos o mesmo processo que o anterior, apenas ao invés de uma img, selecionamos o i alterando sua propriedade display para podermos alterar as propriedade de largura(width) e altura(height) para o elemento ter as dimensões da imagem e colocamos a imagem desejada como background, esta será a imagem para quando o checkbox não estiver selecionado. Na linha 12 selecionamos o elemento i quando o elemento input estiver selecionado e alteramos a imagem para a qual desejamos que seja mostrada quando o input estiver selecionado.

Também podemos dessa maneira fazer facilmente que o input checkbox fique com a aparecia dos toggle switch.

Exemplo de checkbox como toggle switch
<fieldset class="check-switch">
    <label for="switch">
        <input type="checkbox" name="switch" id="switch">
        <i></i>
    </label>
</fieldset>

O HTML permanece o mesmo.

.check-switch label > input{
    visibility: hidden;
}
.check-switch label > i {
    display: block;
    width: 32px;
    height: 16px;
    border: 1px solid #AAA;
    border-radius: 5px;
}
.check-switch label > input + i:after {
    content: "";
    display: block;
    width: 12px;
    height:12px;
    background: #AAA;
    margin:2px;
    border-radius:3px;
    transition:0.2s;
}
.check-switch label >input:checked + i:after {
    background: #333;
    margin-left: 16px
}

A diferença deste exemplo para o anterior é que neste iremos desenhar o elemento por CSS. Começamos na linha 4 selecionando e estilizando o i como um retângulo com bordas arredondadas. Na linha 11 utilizamos o pseudo-elemento :after de i em conjunto da propriedade content para criar um elemento filho dentro de i e o estilizamos como um pequeno quadrado de bordas arredondadas. Na linha 21, selecionamos o pseudo-elemento criado quando o input estiver selecionado e trocamos a cor de fundo e deslocamos ele para a direita adicionando uma margem a esquerda.

Para ver os exemplos funcionando clique aqui

Era isso, espero que tenha ajudado.