1

I replaced the platform-native radio button with a custom control because I had a problem to style radio button and checkbox with the :invalid pseudo class. I used -webkit-appearance: none; in the way described on https://css-tricks.com/custom-styling-form-inputs-with-modern-css-features/. Additionally, I decreased the size of control to 16px, to be like the custom controls in Bootstrap. Unfortunately, the radio button dot doesn't position equally in the center if scaling is enabled in the Windows screen settings. You can see it especially if you click several times on the included button. The dot inside the selected radio button will move relative to the radio button. The dot should be centrally in the center, but sometimes it shifts 1 pixel (or half a pixel?) left or right. If there is no scaling (scaling is 100%), the problem doesn't occur. At 125% scaling, the dot moves in a 4 button clicks cycle. When scaling is 150%, the dot moves in a 2 button clicks cycle.

The problem is practical and not only theoretical, because on a small radio button it is very visible that the dot isn't in the middle.

Why there is this problem with centering this radio dot?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  <style>
    body  { font-family: Arial, sans-serif;
            color: #222; }
  </style>
</head>
<body>
  <form id="form1" class="custom-toggles" style="margin-left: 0px;">
    <input id="r1" type="radio" value="1" name="radio" checked>
    <label for="r1">Radio1</label>
    <input id="r2" type="radio" value="2" name="radio">
    <label for="r2">Radio2</label>
    <br><br>
    <button type="button" id="btn1">Move right</button>
  </form>
</body>
</html>
.custom-toggles {
  @supports(-webkit-appearance: none) or (-moz-appearance: none) {
    input[type='radio'] {
      -webkit-appearance: none;  //don't use platform-native control
      -moz-appearance:    none;
      width: 16px; height: 16px;
      border-radius: 50%;
      border: 1px solid #aaa;
      background: white;
      outline: none;
    }

    input[type='radio']:checked  {
      background:   #07f;
      border-color: #07f;
    }

    input[type='radio']:after {  //a radio button inner dot
      content: '';
      display: block;
      width: 14px; height: 14px;
      border-radius: 50%;
      transform: scale(.5);
      background: white;
    }
  }
}
let i = 0;
btn1.addEventListener('click', () => { i++; form1.style.marginLeft = `${i}px`; })

You can run the code on your computer or here: https://codepen.io/iwis/pen/QWjrzvW

Web browser: Chrome, OS: Windows 10.

iwis
  • 1,382
  • 1
  • 13
  • 26

1 Answers1

1
.custom-toggles {
  position:relative
 }
input[type='radio']:after {
content: '';
display: block; 
width: 8px; 
height: 8px;
border-radius: 50%;
background: white; 
position: relative;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
}

You can try that, small better. When you create a dot with scaling 0.5, that get a new size. From 14 to 7 right? When you scale browser to 125% for Example you dot too scaling and reach 7*1.25 = 8.75 px. But we all have no perfect screen what can show 8.75px. Thay could show only 8 or 9. That why you see that "bug"

Dima Vak
  • 599
  • 5
  • 20
  • It works after changing "width: 7px; height: 7px;" to "width: 8px; height: 8px;". The full code for "input[type='radio']:after" selector should be: input[type='radio']:after { content: ''; display: block; width: 8px; height: 8px; border-radius: 50%; background: white; position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); } If somebody doesn't know what are the last 3 lines for - they are used to center the radio button inner dot inside the radio button like here: https://stackoverflow.com/a/23714832/ – iwis May 16 '20 at 15:07