1

I have a few radio buttons replaced with images. I have a second set of images I'd like the original ones to change to when a certain button is selected.

HTML

<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <img src="./images/10.png"/>
</label>
...

CSS

label.item > input {
    visibility: hidden;
    position: absolute;
}

In this case, the image is 10.png. I'd like it to change to 10S.png when selected, but revert back to 10.png when another option is selected.

My best idea was to use JS to append an S to the end of the image path onclick, but reverting back proved troublesome. Is there a strictly HTML/CSS way to do it, or is JS a must? All images used for the radio buttons are in the form #.png from 1-10, and the updated images are #S.png from 1-10 (ie. 2.png will become 2S.png, etc).

I'd rather not use JQuery if possible and I'm hoping for a solution with the most browser compatibility.

TaoPR
  • 5,932
  • 3
  • 25
  • 35
gator
  • 3,465
  • 8
  • 36
  • 76
  • I know you say not use of Jquery but take a lokk here: http://stackoverflow.com/questions/3469789/changing-radio-buttons-image-help?rq=1 – Akul Von Itram Jul 01 '15 at 16:28
  • 1
    could you eventually merge the image 10 + 10s side by side? Doing so you could use `clip` property depending on the `:checked` status of the previous input – Fabrizio Calderan Jul 01 '15 at 16:29
  • 1
    @FabrizioCalderan do you mean CSS sprites? – gator Jul 01 '15 at 16:30
  • 1
    yes. doing so you could save several requests and obtain at the same time a preload for "free" of all `-s` images :) – Fabrizio Calderan Jul 01 '15 at 16:31
  • I bet on pure CSS, see http://stackoverflow.com/questions/1431726/css-selector-for-a-checked-radio-buttons-label – pdem Jul 01 '15 at 16:37

2 Answers2

4

There is an HTML and CSS only solution using the :checked pseudo-class and a pseudo-element.

label.item {
  display: inline-block;
  position: relative;
}
label.item > input {
    visibility: hidden;
    position: absolute;
}
label.item > .radio-image::before {
  content: url("http://placehold.it/50x50");
}
label.item > input[type="radio"]:checked + .radio-image::before {
  content: url("http://placehold.it/75x75");
}
<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <div class="radio-image"></div>
</label>
<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <div class="radio-image"></div>
</label>
<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <div class="radio-image"></div>
</label>
<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <div class="radio-image"></div>
</label>
<label class="item">
    <input type="radio" value="10" name="size" required="required"/>
    <div class="radio-image"></div>
</label>

As far as I know, this is compatible in modern browsers and IE9+

Jacob
  • 2,212
  • 1
  • 12
  • 18
  • How would I make it dynamic? Say I had five radio buttons, your solution suggests I would need to hardcode `content: url(#.png)` and `content; url(#S.png)` for all five buttons. Is there a solution where only two styles are needed instead of ten (for the example of five buttons)? – gator Jul 01 '15 at 18:10
  • 1
    Edited to use multiple radio buttons. If you want to dynamically populate the image URL's then you'll need to use JavaScript. – Jacob Jul 01 '15 at 19:49
0

I would do it like this, allowing you to be very flexible and let the content in the HTML as you apparently need to :

HTML

<input type="radio" value="10" id="size10" name="size" required="required"/>
<label for="size10" class="item">
    <img src="http://placehold.it/50x50">
    <img src="http://placehold.it/100x100">
</label>
<input type="radio" value="15" id="size15" name="size" required="required"/>
<label for="size15" class="item">
    <img src="http://placehold.it/30x30">
    <img src="http://placehold.it/60x60">
</label>

CSS

/* Hiding radio button */
input[type='radio'] {display:none;}
/* Hiding second image in label tags */
label.item > img:nth-child(2) {display:none;}
/* When radio-button is checked, display second image in the following label tag */
input[type='radio']:checked + label.item > img:nth-child(1) {display:none;}
input[type='radio']:checked + label.item > img:nth-child(2) {display:inline-block;}

Here's the fiddle for demo.

Note I did move the radiobutton out of the label cause I like it better that way, and selectors will probably need to be adapted to your situation, but once you understand the logic it shouldn't be an issue.

Laurent S.
  • 6,816
  • 2
  • 28
  • 40