Your percentage will be converted to pixel relatively to the width/height of your element. In your case, your element is small thus 99%
and 100%
will most likely be converted to the same value or very close values and you will have subpixel rendring issue.
Instead you can rely on calc()
where you can easily define the thickness as a pixel value independently of the element size.
You need to also adjust background-origin
and make it border-box
so that you draw the gradient considering the border area and you will have a perfect circle.
.container {
background: #ddd;
width: 400px;
height: 200px;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 2px solid transparent;
width: 20px;
height: 20px;
margin-right: 20px;
background-origin:border-box;
}
.radio1 { background-image: radial-gradient(circle closest-side, white calc(100% - 1px), red 100%); }
.radio2 { background-image: radial-gradient(circle closest-side, white calc(100% - 2px), red 100%); }
.radio3 { background-image: radial-gradient(circle closest-side, white calc(100% - 3px), red 100%); }
.radio4 { background-image: radial-gradient(circle closest-side, white calc(100% - 4px), red 100%); }
<div class="container">
<div class="radio"></div>
<div class="radio radio1"></div>
<div class="radio radio2"></div>
<div class="radio radio3"></div>
<div class="radio radio4"></div>
</div>
Here is an example with big values of border to better illustrate the issue related to background-origin
.container {
background: #ddd;
width: 400px;
height: 200px;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 20px solid rgba(0,0,0,0.2);
width: 50px;
height: 50px;
margin-right: 20px;
background-image: radial-gradient(circle closest-side, white calc(100% - 4px), red 100%); }
<div class="container">
<div class="radio radio4"></div>
</div>
The background is drawn on the padding box then it's getting repeated over all the area (border box).
If you disable the repeat you will have this:
.container {
background: #ddd;
width: 400px;
height: 200px;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 20px solid rgba(0,0,0,0.2);
width: 50px;
height: 50px;
margin-right: 20px;
background-image: radial-gradient(circle closest-side, white calc(100% - 4px), red 100%);
background-repeat:no-repeat;
}
<div class="container">
<div class="radio"></div>
</div>
Here is if we repeat only on the X axis
.container {
background: #ddd;
width: 400px;
height: 200px;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 20px solid rgba(0,0,0,0.2);
width: 50px;
height: 50px;
margin-right: 20px;
background-image: radial-gradient(circle closest-side, white calc(100% - 4px), red 100%);
background-repeat:repeat-x;
}
<div class="container">
<div class="radio"></div>
</div>
And here is what is happening when using 100% for both colors which is similar to your situation and you will better understand why you have coloration only on the corners.
.container {
background: #ddd;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 20px solid rgba(0, 0, 0, 0.2);
width: 50px;
height: 50px;
margin-right: 20px;
background-image: radial-gradient(circle closest-side, white 100%, red 100%);
}
.one {
background-repeat: no-repeat;
}
.two {
background-repeat: repeat;
}
.three {
border-width: 5px;
}
.four {
width:20px;
height:20px;
border-width: 2px;
}
<div class="container">
<div class="radio one"></div>
<div class="radio two"></div>
<div class="radio three"></div>
<div class="radio four"></div>
</div>
And if we change the origin it's fine:
.container {
background: #ddd;
width: 400px;
height: 200px;
padding: 20px;
}
.radio {
display: inline-block;
background: white;
border-radius: 50%;
border: 20px solid rgba(0,0,0,0.2);
width: 50px;
height: 50px;
margin-right: 20px;
background-image: radial-gradient(circle closest-side, white calc(100% - 4px), red 100%);
background-origin:border-box;
}
<div class="container">
<div class="radio"></div>
</div>
box-shadow
. Something likebox-shadow: inset 0 0 3px 3px red;
. Of course, you asked why and how with a radial gradient, so this isn't really an answer - just an option :) – Datarybackground: radial-gradient(circle closest-side, white 99%, red 100%);
will not cover a single pixel in a 20px square boxe, so it's even impossible mission to draw a gradient, at 75% to 100% the gradient has about 2.5 pixels to be drawn ... It does not work because your boxes are too small :( the second box has 2pixel to faint from red to white, third and fourth have no chance to draw your gradient – Tasker