首页 > 解决方案 > Unable to center an element when Windows scaling is enabled (125%)

问题描述

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.

标签: css

解决方案


.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%);
}

你可以试试,小的更好。当你创建一个缩放为 0.5 的点时,它会得到一个新的大小。从14到7对吗?当您将浏览器缩放到示例的 125% 时,您的点太缩放并达到 7*1.25 = 8.75 像素。但是我们都没有完美的屏幕可以显示 8.75px。Thay 只能显示 8 或 9。这就是为什么你会看到那个“错误”


推荐阅读