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 is510px
, now 10% comes to51px
. Actual width of an element includes its padding, so here it will become351px
and when UA tries to calculate 50% of the width forbackground-size
, the resulting value will be175.5px
. This is where the catch is. Some browsers round it down to175px
, 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 becauseIt goes away when we setbackface-visibility
tohidden
. 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
Why Doesn't Justify-Content: Stretch Work
Box Sizing on Inputs in Firefox Hides Text
Fixed Persistent Header and Scroll to Focussed Input Fields
Relative Padding Is Relative to What
Is Decimal Precision When Specifying a Font-Size Respected by All Browsers
CSS Modules - Referencing Classes from Other Modules
How to Add List-Style-Type: "Disc" to <P> Tag
Input Padding Cutting Out Text in Firefox
What's the Trick to Inspect Popout/Dropdown Menu Style with Firebug
Create a W3C Validated Anchor Link with Target="_Blank"
Ie CSS Bug: Table Border Showing Div with Visibility: Hidden, Position: Absolute
Grails 2.3 Changes CSS Font-Face Url to "Resource:/..."
Twitter Bootstrap Remove Table Row Highlight with Row Stripes