CSS3 - Style radio inputs using the :checked selector on older browsers (ie7/ie8)
I'm styling my input[type=radio]'s with CSS, because I need to replace the default radio with an image. Actually what I am doing is hide the input element, and show the styled label with the image background.
To do this I'm using new CSS3 selectors "#myinputradio + label" and "myinputradio:checked + label". All works well using the last versions of each browser (i开发者_运维技巧ncluding IE9), but I need to get it working up to IE7.
I can also refer on JQuery, but I'd like to exploit the same CSS selector for JS and CSS3-ready browsers (I have a lot of radio inputs and each one has its own background image, placed from a common sprite).
Is there any way to do this supporting also older browsers?
Here a sample from HTML:
<input id="euro" type="radio" value="euro" checked="" name="currency">
<label for="euro"></label>
And here 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 informations, please ask me. Thanks.
This should work very 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's 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's 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 deliberately added the wrong for
attribute at the last label
(fiddle), to show what does (and should) happen when you attach the wrong for
attribute to a label.
EDIT
Read the comments for the explanation of the code. I have added an alternative way to define a style inside comments (2x).
Two issues 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 might try changing that to float
.
:checked
Also, IE7 has issues with attribute selectors
.
So #euro:checked
won't work.
But this might #euro[checked]
. If it does, you could serve it to IE<9 with a conditional comment.
jQuery
I might just use some scripting, though. In that case, leave the css as is and add something this for the IE<9 (untested)
$('#euro:checked').next('label').css('background-position','1108px 898px');
精彩评论