CSS3 - Inlining inputs using: checked selector in older browsers (i.e. 7 / ie8)
I am drawing my input [type = radio] with CSS because I need to replace the standard radio with an image. In fact what I am doing is hide the input element and show a styled label with an image background.
For this, I use the new CSS3 selectors "#myinputradio + label" and "myinputradio: checked + label". Everything works well using the latest versions of every browser (including IE9), but I need to get it to work with IE7.
I can link to JQuery as well, but I would like to use the same CSS selector for JS and CSS3 browsers (I have a lot of radio inputs and each has its own background image placed from a shared sprite).
Is there a way to do this while still supporting older browsers?
Here's an example from HTML:
<input id="euro" type="radio" value="euro" checked="" name="currency">
<label for="euro"></label>
And here is the CSS used to style it:
#euro + label /*and all other checkboxes*/ {
display: inline-block;
width: 37px;
height: 37px;
background: url(../img/sprites.png);
}
#euro + label {
background-position: 1042px 898px;
}
#euro:checked + label {
background-position: 1108px 898px;
}
If you need more information, please ask me. Thank.
source to share
This should work pretty well (Fiddle: http://jsfiddle.net/p5SNL/ ):
//Loops through each radio input element
$('input[type="radio"]').each(function(){
// Checks if the next element is a label, and whether the RADIO element
// has a name or not (a name attribute is required)
if(/label/i.test($(this).next()[0].tagName) && this.name){
// Adds an onchange event handler to the RADIO input element
// THIS FUNCTION will ONLY run if the radio element changes value
$(this).change(function(){
// Loop through each radio input element with the a name attribute
// which is equal to the current element name
$('input[type="radio"][name="'+this.name+'"]').each(function(){
/*****
* The next line is an efficient way to write:
* if(this.checked){ // Is this element checked?
* // Adds "labelChecked" class to the next element (label)
* $(this).next().addClass("labelChecked");
* } else {
* //Removes "labelChecked" class from next element (label)
* $(this).next().removeClass("labelChecked");
* }
*****/
$(this).next()[this.checked?"addClass":"removeClass"]("labelChecked");
/* Alternatively, setting the CSS background:
* CSS background = IF "radio checked?" THEN "green" ELSE "red"
$(this).next().css("background", this.checked?"green":"red");
*/
});
}); //end of event handler declaration
//Adds "labelChecked" class to the current element IF it checked
if(this.checked) $(this).next().addClass("labelChecked");
/*Alternative way, setting a CSS background instead of a className:
if(this.checked) $(this).next().css("background", "green");
*/
} //end of IF
}); //end of the loop through all RADIO elements
Note that I have intentionally added the wrong attribute for
on the last one label
(fiddle) to show what happens (and should) when you attach the wrong attribute for
to the label.
EDIT
Read the comments for an explanation of the code. I added an alternative way of defining the style inside comments (2x).
source to share
Two questions I see here:
inline block
Part of the problem is this bit of code:
#euro + label /*and all other checkboxes*/ {
display: inline-block;
width: 37px;
height: 37px;
background: url(../img/sprites.png);
}
IE7 does not support display:inline-block;
You can try changing this to float
.
: checked
Also IE7 has problems with attribute selectors
.
So that #euro:checked
won't work.
But it could be #euro[checked]
. If so, you can post it in IE <9 with a conditional comment.
JQuery
I could just use some scripts. In this case leave the css as it is and add something like this for IE <9 (untested)
$('#euro:checked').next('label').css('background-position','1108px 898px');
source to share