Radio Button Background Goes White in Windows Chrome When Using -Webkit-Backface-Visibility. Any Workarounds

How do I change the color of radio buttons?

A radio button is a native element specific to each OS/browser. There is no way to change its color/style, unless you want to implement custom images or use a custom Javascript library which includes images (e.g. this - cached link)

Changing radio button background on selected according to it value

Problems in your code:

  • The # colour codes that you had in your CSS didn't reflect the colours you were trying to assign. These hex codes need to be either abbreviated three-digit RGB values or six-digit RGB values with two digits per colour, i.e., either #RGB or #RRGGBB, but it was like you mixed the two options by adding "000" to the end of what would otherwise be the right three-digit hex codes for the colours you wanted. Either remove the trailing 000 from each one, or change to the correct six-digit hex codes.
  • You didn't have any code to remove the class from a button when the other buttons are clicked.

Your JS code seems overly complicated. I would bind the click handler to the radio buttons themselves, because then this.value will give you the value of the button just clicked, thus simplifying your if conditions a lot. You can use $(this).parent() to then get to the label element to style it.

I've introduced a variable called buttons that is the jQuery object containing all of the buttons, because then inside the handler you can say buttons.not(this).parent() to get a jQuery object containing all of the other buttons' parent label elements and remove the colour class from them to make them grey again.

$(document).ready(function() {  var buttons = $("input:radio[name='category']").click(function() {    buttons.not(this).parent().removeClass('whiteBG greenBG yellowBG redBG');    var label = $(this).parent();    if (this.value == 'W') {      label.addClass('whiteBG');    } else if (this.value == 'G') {      label.addClass('greenBG');    } else if (this.value == 'Y') {      label.addClass('yellowBG');    } else if (this.value == 'R') {      label.addClass('redBG');    }  });});
input[type=radio], input[type=checkbox] { display: none; }
label { display: block; appearance: button; -webkit-appearance: button; -moz-appearance: button; -ms-appearance: button; font-family: 'Roboto', sans-serif; font-weight: 400; background: #DDDDDD; font-size: 1.6rem; color: #111111; border: 2px solid #AAAAAA; padding: 8px; width: 40%; margin: 0 auto; text-align: center; transition: all 0.7s ease-in-out;}
.whiteBG { background-color: #FFF; }
.greenBG { background-color: #0F0; }
.yellowBG { background-color: #FF0; }
.redBG { background-color: #F00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><form>  <fieldset data-role="controlgroup">    <legend>PERSON CATEGORY SELECTION</legend>    <label for="neutral">        <input type="radio" class="button" id="neutral" name="category" value="W" >NEUTRAL</input>    </label>    <label for="good">         <input type="radio" class="button" id="good" name="category" value="G">GOOD</input>    </label>    <label for="watchlist">         <input type="radio" class="button" id="watchlist" name="category" value="Y">WATCHLIST</input>    </label>    <label for="monitor">         <input type="radio" class="button" id="monitor" name="category" value="R">UNDER MONOTORING</input>    </label>  </fieldset></form>

How to design a radio button, which looks the sam in Firefox, Chrome and IE11

Add this for IE11, used ::-ms-check

/* fallback for  IE11 */
.radiobtn[type="radio"]:checked::-ms-check {
border: 2px solid green;
color: green;
opacity: 1;
}

.radiobuttons{    background-color: white;    font: 16px Arial, sans-serif;}.radiolabel{    font: 16px Arial, sans-serif;    color: #000000;    opacity: 0.9;}
.radiobtn[type="radio"] {
/* remove standard background appearance */ -webkit-appearance: none; -moz-appearance: none; /* create custom radiobutton appearance */ display: inline-block; width: 25px; height: 25px; padding: 4px; /* background-color only for content */ background-clip: content-box; border: 2px solid #000000; opacity: 0.4; border-radius: 50%; vertical-align: bottom;}
/* appearance for checked radiobutton */.radiobtn[type="radio"]:checked { background-color: green; border: 2px solid green; opacity: 1;}.radiobtn[type="radio"]:checked::-ms-check { border: 2px solid green; color: green; opacity: 1;}
.radiogroup { vertical-align: middle; margin-bottom: 20px;}
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <title>Title</title>    <link rel = "stylesheet" href = "test.css"></head><body><div class="radiobuttons">    <div class="radiogroup">        <input class="radiobtn" type="radio" id="mc" name="Zahlmethode" value="Mastercard" >        <label class="radiolabel" for="mc"> Mastercard</label><br>    </div>    <div class="radiogroup">        <input class="radiobtn" type="radio" id="vi" name="Zahlmethode" value="Visa">        <label class="radiolabel" for="vi"> Visa</label><br>    </div>    <div class="radiogroup">        <input class="radiobtn" type="radio" id="ae" name="Zahlmethode" value="AmericanExpress">        <label class="radiolabel" for="ae"> American Express</label>    </div></div>
</body>

Change styles of radio container when radio is checked or hovered

The problem:

I tried with this CSS but didn't work:

  • It doesn't work because CSS selectors are "forward-only".

    • The ~ and + combinators in CSS selectors cannot select an element based on a descendant element or next-sibling element's attributes or DOM state.
    • Conversely: It can only select elements based on their ancestor and previous-sibling elements' attributes and DOM state.
    • Indeed, the + combinator doesn't mean "adjacent sibling", it means "next adjacent sibling", and ~ doesn't mean "any sibling", it means "any future siblings".
  • In your case: a CSS selector cannot use the :checked state of the <input id="choice_1_15_0" /> when selecting <div class="gchoice gchoice_1_15_0">...

    • ...but CSS can use it to select <label for="choice_1_15_0">.

CSS selectors work this way for multiple reasons, the main one thing performance: the algorithm for applying CSS rules with these restrictive forward-only rules is much simpler and faster than if it had to support any kind of "look-backwards and upwards" rules.

That said, what I'm referring to is actually supported by web-browsers: it's called the :has() relational selector, however because of those performance reasons it isn't supported in CSS stylesheets, only in in the DOM's querySeletor and querySelectorAll functions:

I note that since 2021, some (non-Google) Chrome devs are
investigating ways to try to implement support for limited kinds of sub-selectors in :has() in Chrome, read about it here: https://css-has.glitch.me/ - but I doubt support for this will enter Chrome for years, let alone other browser engines like Safari and Firefox.

Ideal solution: :has() selector:

If we could use :has(), then you could just do this and call it a day:

label[for]:has(input[type=radio]:checked) {
background: #EF8B22;
border: 1px solid #EF8B22;
box-shadow: 0px 0px 6px 0px rgb(239 139 4 / 30%);
}

Unfortunately they don't, so we can't do this.



Workaround: move your <input/> elements:

The workaround is to hoist up your <input/> to be located both above and before its container - but as you don't want the checkbox widget to be visually located there you'll need to either make the input invisible and use a replacement checkbox image in the <label> or use a CSS technique to relocate the rendered input element, perhaps using CSS grid or flex (or even position) but these don't give you much flexibility.

You can also use ::before to add a fake checkbox/radio button (either using an aesthetically pleasing SVG or PNG as background-image, or use CSS border to render a box directly).

Something like this:

input  { display: none; }

.gchoice_1_15_0,
.gchoice_1_15_1 {
width: 48%;
color: #58595B;
border: 1px solid #E4E4E4;
border-radius: 10px;
padding-left: 1em;
background: #fff;
transition: all ease-in-out .3s;
box-shadow: none;
}

#choice_1_15_0:checked ~ * label[for="choice_1_15_0"],
#choice_1_15_1:checked ~ * label[for="choice_1_15_1"] {
background: #EF8B22;
border: 1px solid #EF8B22;
box-shadow: 0px 0px 6px 0px rgb(239 139 4 / 30%);
}

/* CSS-only radio buttons: */
label::before {
display: inline-block;
content: ' ';
background: white;
border: 1px solid black;
border-radius: 7px;
box-sizing: border-box;
width: 14px;
height: 14px;
}

#choice_1_15_0:checked ~ * label[for="choice_1_15_0"]::before,
#choice_1_15_1:checked ~ * label[for="choice_1_15_1"]::before {
background: radial-gradient(circle, rgba(0,0,0,1) 40%, rgba(0,0,0,0) 40%);
}
<input class="gfield-choice-input" name="input_15" type="radio" value="Yes" id="choice_1_15_0" onchange="/*gformToggleRadioOther( this )*/">

<input class="gfield-choice-input" name="input_15" type="radio" value="No" id="choice_1_15_1" onchange="/*gformToggleRadioOther( this )*/">

//Yes option
<div class="gchoice gchoice_1_15_0">
<label for="choice_1_15_0" id="label_1_15_0">Yes</label>
</div>

//No option
<div class="gchoice gchoice_1_15_1">
<label for="choice_1_15_1" id="label_1_15_1">No</label>
</div>

Unwanted blue border on radio button, is possible to remove that?

The blue border you're seeing is the result of the RadioButton being focused.

You can prevent the RadioButton from receiving the focus automatically by setting focusTraversable to false:

.radio-button {
-fx-focus-traversable: false;
}

To modify the color, you can assign the -fx-focus-color and -fx-faint-focus-color properties:

.radio-button {
-fx-focus-color: red;

/* 2/15 th of the opacity of the focus color */
-fx-faint-focus-color: ladder(#222, transparent 0%, -fx-focus-color 100%);
}

Radio buttons wont align to the left

Theres a lot of work an little bugs in your code. I will focus on the radio buttons. 2 main errors.

1- You are setting the radio buttons width to 50% with:

input {
width: 50%;
display: block;
margin: 10px 0px;
}

Solution comes to reset it in its own style

input[type="radio"]{
width: auto;
display: inline;
}

2- You are making all your text and radio buttons to just one label tag. This is not a good pratice. We can set on label for each radio button and text. An by adding its display to block, they will align.

label {
display: block;
}

Hope this helps :>

.feedback-background{    width: 100%;    height: 100%;    background-color: rgba(0,0,0,0.7);    position: absolute;    top: 0px;    display: flex;    align-items: center;    justify-content: center;}.feedback-content{    width: 500px;    height: 600px;    background-color: white;    border-radius: 4px;    padding: 20px;}
input { width: 50%; display: block; margin: 10px 0px;}
label { display: block;}
input[type="radio"]{ width: auto; display: inline;}
<div class="feedback-background">    <div class="feedback-content">        <img src="E:\IIT\Lectures\WEB\coursework1\Images\feedbackimg1.jpg" alt="Givefeedback" style="width:100px;height:100px;">                <form action="">            Name:            <input type="text" placeholder="Name">            E-Mail:            <input type="text" placeholder="E-mail">            What do you think about us?<br>            <textarea rows="6" cols="33" "name="comment"></textarea>            <br>            How would you rate us?            <br>                        <label><input type ="radio" name="rating" id="rating" value="Excellent">Excellent</label>            <label><input type ="radio" name="rating" id="rating" value="Very Good">Very Good</label>            <label><input type ="radio" name="rating" id="rating" value="Average">Average</label>            <label><input type ="radio" name="rating" id="rating" value="Poor">Poor</label>            <label><input type ="radio" name="rating" id="rating" value="Extreamly Poor">Extremely Poor</label>            <br>            <br>                        <a href="#" id="btn1">SUBMIT</a>        </form>    </div></div>

Use images instead of radio buttons

  • Wrap radio and image in <label>
  • Hide radio button (Don't use display:none or visibility:hidden since such will impact accessibility)
  • Target the image next to the hidden radio using Adjacent sibling selector +
  • Don’t forget to provide alternative text in the alt attribute, especially since it functions as the radio button’s label

/* HIDE RADIO */
[type=radio] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}

/* IMAGE STYLES */
[type=radio] + img {
cursor: pointer;
}

/* CHECKED STYLES */
[type=radio]:checked + img {
outline: 2px solid #f00;
}
<label>
<input type="radio" name="test" value="small" checked>
<img src="https://via.placeholder.com/40x60/0bf/fff&text=A" alt="Option 1">
</label>

<label>
<input type="radio" name="test" value="big">
<img src="https://via.placeholder.com/40x60/b0f/fff&text=B" alt="Option 2">
</label>


Related Topics



Leave a reply



Submit