Why Doesn't This Radial-Gradient Complete the Circle

Why doesn't this radial-gradient complete the circle?

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>

Radial-gradient doesn’t create perfect circles

There are a few solutions to this, discussed in this Medium article by
Mandy Michael.

One elegant one is to use calc to add a single pixel of the second color, as seen below, which renders enough blur to offset the jaggedness.

div {
width: 400px;
height: 400px;
background: radial-gradient(circle, blue 50%, pink calc(50% + 1px));
}
<div></div>

Radial gradient shows some backlines, gap, spaces or margins

There were two problems in your snippet and when we fix both those that weird gap or line that shows up in the middle would be gone completely..

  • Issue 1: You were setting padding: 10% on the element instead of a fixed value. When we give the value as a percentage, we are at the mercy of the UA in terms of rounding-off logic. Each UA has its own rounding-off logic. Take for example the width of the box's containing block is 510px, now 10% comes to 51px. Actual width of an element includes its padding, so here it will become 351px and when UA tries to calculate 50% of the width for background-size, the resulting value will be 175.5px. This is where the catch is. Some browsers round it down to 175px, some like FF has unique logic which rounds down some but rounds up the others, some just round it up etc. When the value is rounded down, the total size of the two background pieces becomes 350px but the actual width of the box is 351px and this 1px difference is the gap that you see.
  • Issue 2: When we apply a transform on an element, this sort of gap always comes up. My feeling is that this has something to do with the backface of the element because It goes away when we set backface-visibility to hidden. We have added a detailed explanation at the bottom of the answer. (This is tested in Chrome but should work in all. If it doesn't then there is no solution.)

In the below snippet, I've fixed both these issues and you can see how it works fine. There is also an extra catch with the backface-visibility: hidden. When you set this on a container element, all the text that is within that element get blurred. So, it is better to create the background using a pseudo as it would not affect the display of the p element.

* {  margin: 0;  outline: 0;  border: 0;}.round {  position: relative;  width: 300px;  height: 300px;  padding: 30px;}.round:after {  position: absolute;  content: '';  height: 100%;  width: 100%;  top: 0px;  left: 0px;  background: radial-gradient(circle at 0 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 0, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 0 0, rgba(204, 0, 0, 0) 70%, #c00 71%);  background-position: bottom left, bottom right, top right, top left;  background-size: 50% 50%;  background-repeat: no-repeat;  transform: rotate(45deg);  backface-visibility: hidden;  z-index: -1;}p {  width: 125px;  margin: 85px;}
<div class="round">  <p>By using radial gradients, you can simulate rounded corners with a negative radius. Just in this case,</p></div>

Make radial-gradient() span two elements

This can achieved using calc() to position the radial in the second in the bottom semi-circle.
I'm using calc(100px - 5em), because 100px is the offset of the center of the gradient in the top half and 5em is the height of one semi-circle.

EDIT: I also had to specify the size of the gradient to make them match, by default the sizes are different, probably because the distance from the center and the various sides are different.

.top-semi-circle {  width: 10em;  height: 5em;  background: radial-gradient(10em at 100px 100px, red, #000);}.bottom-semi-circle {width: 10em;  height: 5em;  background: radial-gradient(10em at 100px calc(100px - 5em), red, #000);}.top-semi-circle {  border-radius: 10em 10em 0 0;}.bottom-semi-circle {  border-radius: 0 0 10em 10em;}.full-circle {  width: 10em;  height: 10em;  border-radius: 10em;  background: radial-gradient(circle at 100px 100px, red, #000);}
Make this:<div class="top-semi-circle"></div><div class="bottom-semi-circle"></div>Look like this:<div class="full-circle"></div>

CSS3 radial gradient

It might be simpler to go with multiple overlaid gradients as a background.

The first a simple linear gradient, left to right, and a second radial gradient on top.

Then it's just a matter of positioning (absolutely) your text element over the white circle (remember you know where it's positioned)

A quick and dirty demo:

div {  height: 350px;  width: 90%;  margin: 1em auto;  border: 1px solid lightgrey;  background:     radial-gradient(circle closest-side at 75% 50%, white, white 60%, transparent),     linear-gradient(to right, #344862, white 75%, yellow);  position: relative;}span {  position: absolute;  left: 75%;  top: 50%;  transform: translate(-50%, -50%);}
<div>  <span>Lorem ipsum dolor.</span></div>

Why does a border that has opacity make a square inside a circle when I use radial-gradient(circle at)?

You need to adjust the background-origin to make it border-box so that the gradient consider the border as its area too. By default background-origin is set to padding-box whereas background-clip is set to border-box making the background to repeat on the border creating the strange effect:

I also added the 27px of the border to the center of the circle since now the border is considered in the calculation.

.style {  width: 200px;  height: 200px;  border-radius: 50%;  border: 27px solid #00000030;  background: radial-gradient(circle at 102px 77px, #5cabff, #003) border-box;}
<div class="style"></div>

CSS3 radial gradient appears as line

Set your body height to 100%, your body element is empty, and thus it doesn't have any height, the background is simply repeated there.. Bad Demo

html, body {
height: 100%;
}

Demo

Also, you background will be repeated, so you will need background-attachment: fixed; as well as background-repeat: no-repeat

Demo 2



Related Topics



Leave a reply



Submit