Ask the CSS Guy

Placing a Border Around a Thumbnail with a Form that Uses Radio Selection

I like how during the blogger sign-up process, while choosing a template, they offer clickable thumbnails of templates that work with their radio buttons. Here's a way to do that.

The markup

I'm going to use an unordered list, label, and radio button.

<ul id="choicesList">
<li id="li-michael">
	<img src="images/michael.jpg" /><br />
	<label for="radiomichael">
	<input
		type="radio"
		class="radio"
		name="choice"
		value="michal"
		id="radiomichael" /> Michael
	</label>
</li>
<li id="li-madonna">
	<img src="images/madonna.jpg" /><br />
	<label for="radiomadonna">
		<input
		type="radio"
		class="radio"
		name="choice"
		value="madonna"
		id="radiomadonna" /> Madonna
	</label>
</li>
<li id="li-elvis">
	<img src="images/elvis.jpg" /><br />
	<label for="radioelvis">
		<input
		type="radio"
		class="radio"
		name="choice"
		value="elvis"
		id="radioelvis" /> Elvis
	</label>
</li>

Notice how the input is within the label. I just started doing this with my latest projects. I've yet to hear of any reason why one shouldn't. This helps me meet my styling objectives while giving the added benefit of of having extra clickable space to activate the radio button for browsers that support it (all but Safari to my knowledge).

The main benefit of this technique is to have border around the selected item. In this case, all the li tags are styled to have a gray border by default. Once selected, that border turns green. If another radio becomes selected, then the first li returns to a gray border, while the newly selected radio will have a green border.

In order for the styling of the borders to change whenever a different radio button is selected, JavaScript is needed. By default, all li tags have a border of gray. When someone clicks on the image, I want JavaScript to insert class="on" to the li, and I will already have in my stylesheet that li.on will have a green border.

The JavaScript

I've realized that attempting to describe JavaScript functions can be a tricky thing in a blog. If it were just one function, I think I could get away with it, but because I'm using three main ones, it seems like any description could easily get lost in this narrative. For that reason, I'm going to do a very high-level description.

First there's the "addLoadEvent" function, which allows me to have several functions load at a time. I use it all the time, not just with this particular effect.

Next is "clearChoices". When I click on a new selection, how does the JavaScript know to remove class="on" from the previous choice? Using "clearChoices", the JavaScript returns the classes on all the lis to normal, resulting in a default gray border.

"highlightChoices" first calls the "clearChoices" function above, then attaches the class of "on" to selected li tag.

When someone clicks an image, "imageClick" will make sure the corresponding radio button is checked, then highlights the surrounding li tag in green by calling "highlightChoices".

Finally, there is "prepareChoices", so if someone clicks the actual radio and not the image, the highlight effect still happens.

Comments (9)

Nate said:

Just FYI,

Try not to use relative URLs in your posts (e.g. the "example" link) because they cannot be followed from RSS readers.

CSS Guy said:

@Nate:

Noted.

Gonzo said:

there is some xhtml validation errors, perhaps you should see to fix it at example page

CSS Guy said:

@Gonzo,

Ahh, so there is. I left alt attributes off the images. I'll try and correct that in due time. The other errors are because I use a less than symbol in the javascript, and the validator seems to think that's the opening of an xhtml tag, which isn't the case.

If you see anything else that the validator missed, please let me know.

Peritus said:

You could've achieved the behaviour like this:

<li>
<label>
<img src="images/michael.jpg" alt=""/><br/>
<input />
Michael
</label>
</li>

No Javascript needed ;)

CSS Guy said:

@Peritus:

Yeah - putting the image within the label makes great sense.

I would still have needed javascript to change the list item's border color.

Safari doesn't treat labels the way most other browsers do - allowing the user to click the label to select the radio. In Safari, clicking the label doesn't do diddly. For many developers and companies, though, Safari users are not priority.

Thanks for commenting. I think it's good for people to know the alternatives.

burned said:

Thank you so much for putting this up. I was wondering how can you make for example one of the choices have another default than the others, for example orange border instead of default gray one?

CSS Guy said:

@burned:

In the style sheet, specify unique border colors based on the list item id. For example:

ul#choicesList li#li-michael {border-color: aqua; }

K said:

Is there anyway to modify this so that when a user selects a radio the location of the associated image is copied to their clipboard?

 

Post a comment