Quantcast
Viewing all articles
Browse latest Browse all 1318

CSS Radio Button: Inner Circle Misaligned During Zoom/Dezoom

I am developing a custom Angular component for a radio button with specific design requirements:

Outer circle size: Fixed at 16px x 16px.Inner circle size (checked state): Fixed at 8px x 8px.The inner circle must always remain perfectly centered inside the outer circle, even when zooming in or out (browser scaling).However, despite using various CSS techniques (e.g., Flexbox, transform: translate), the inner circle slightly shifts out of alignment when zooming or dezooming in the browser. I’m looking for a robust solution to ensure the inner circle stays centered.

Technical Context:Framework: Angular 16.Code: Both HTML and SCSS are provided below.Goal: A CSS solution to ensure a stable alignment of the inner circle regardless of zoom levels.

Here my HTML

<span class="waldo-radio-button"      [class.disabled]="disabled"      [class.checked]="checked"      [class.label-after]="labelPosition === 'after'"      [class.label-bottom]="labelPosition === 'bottom'"      (click)="onRadioChange($event)"><span class="radio-container"><span class="radio-button"           [class.checked]="checked"          [class.disabled]="disabled"><span class="inner-circle" *ngIf="checked"></span></span></span><input type="radio"         class="mat-radio-input"         [id]="id"         [name]="name"         [value]="value"         [checked]="checked"         [disabled]="disabled"         [required]="required"         [attr.aria-describedby]="ariaDescribedby"         [attr.aria-label]="ariaLabel"         [attr.aria-labelledby]="ariaLabelledby" /><span class="mat-ripple mat-radio-ripple mat-focus-indicator"><span class="mat-ripple-element mat-radio-persistent-ripple"></span></span><label [for]="id" [style.color]="color"><ng-content></ng-content></label></span>

And my SCSS

.waldo-radio-button {  display: inline-flex;  align-items: center; /* Vertical alignment */  cursor: pointer;  position: relative;  gap: 8px;&.disabled {    cursor: not-allowed;    .radio-button {      border-color: var(--neutral-400);      .inner-circle {        background-color: var(--neutral-400);      }    }    label {      color: var(--neutral-400);    }  }&.checked {    .radio-button {      border: 2px solid var(--primary-600);      .inner-circle {        width: 8px;        height: 8px;        background-color: var(--primary-600);        border-radius: 50%;        transform: translateZ(0); /* To maintain sharp rendering */      }&:hover {        border-color: var(--primary-700);      }&:active {        border-color: var(--primary-800);      }    }  }  .radio-container {    position: relative;    width: 16px; /* Outer circle size */    height: 16px;    display: flex;    justify-content: center; /* Horizontal centering */    align-items: center; /* Vertical centering */  }  .radio-button {    width: 16px;    height: 16px;    border: 2px solid var(--neutral-500); /* Default border color */    border-radius: 50%; /* Perfect circle */    display: flex;    justify-content: center;    align-items: center; /* Center the inner circle */    transition: border-color 0.2s ease;    .inner-circle {      width: 8px; /* Inner circle size */      height: 8px;      background-color: transparent; /* Initially invisible */      border-radius: 50%; /* Perfect circle */      transform: scale(0); /* Hidden by default */      transition: transform 0.2s ease, background-color 0.2s ease;    }  }  input[type='radio'] {    position: absolute;    opacity: 0;    pointer-events: none;  }  label {    color: var(--neutral-700);    cursor: pointer;    display: inline-block;  }}

What I’ve Tried:Flexbox: Used in .radio-container and .radio-button to center the inner circle.Transformations: Applied transform: scale and translateZ(0) to stabilize rendering.Fixed Sizes: Set fixed dimensions for both the outer circle (16px) and the inner circle (8px).


Viewing all articles
Browse latest Browse all 1318

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>