Skip to content

Commit 21bb4d5

Browse files
authored
fix(material/radio): hidden circle visible on some zoom levels (#23154)
We transition the circle of a radio button to `scale(0.001)` in order to hide it and to work around an animation in IE. It seems that on higher system zoom levels (e.g. 125%+) the browser approximates the size to 1x1 which can be visible. These changes work around the issue by also setting `opacity: 0` while the circle is inactive and isn't animating. Fixes #22036.
1 parent 6e1cede commit 21bb4d5

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/material/radio/radio.scss

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,20 @@ $ripple-radius: 20px;
6767

6868
// The inner circle for the radio, shown when checked.
6969
.mat-radio-inner-circle {
70+
$transition-duration: 280ms;
71+
$base-transition: transform ease $transition-duration, background-color ease $transition-duration;
7072
border-radius: 50%;
7173
box-sizing: border-box;
7274
display: block;
7375
height: $size;
7476
left: 0;
7577
position: absolute;
7678
top: 0;
77-
transition: transform ease 280ms, background-color ease 280ms;
79+
// On some zoom levels the `scale(0.001)` from below can cause the circle to be shown as a 1x1
80+
// dot (see #22036). Ensure that it's hidden using `opacity`. There's a slight transition with
81+
// a long delay so that switching the opacity only applies after the `transform` is done.
82+
opacity: 0;
83+
transition: $base-transition, opacity linear 1ms $transition-duration;
7884
width: $size;
7985

8086
// Note: This starts from 0.001 instead of 0, because transitioning from 0 to 0.5 causes
@@ -84,19 +90,21 @@ $ripple-radius: 20px;
8490
// force browser to show background-color when using the print function
8591
@include vendor-prefixes.private-color-adjust(exact);
8692

87-
._mat-animation-noopable & {
88-
transition: none;
89-
}
90-
9193
.mat-radio-checked & {
9294
transform: scale(0.5);
95+
opacity: 1;
96+
transition: $base-transition;
9397

9498
@include a11y.high-contrast(active, off) {
9599
// Since we use a background color to render the circle, it won't be
96100
// displayed in high contrast mode. Use a border as a fallback.
97101
border: solid private.private-div($size, 2);
98102
}
99103
}
104+
105+
._mat-animation-noopable & {
106+
transition: none;
107+
}
100108
}
101109

102110
// Text label next to radio.

0 commit comments

Comments
 (0)