Radial gradient in shape of ring in CSS - css

I would like to create "ring" shape with specified thickness (in px) with radial gradient. Desired result is:
However, I don't know how to specify thickness in pixels and ensure that the color transition is smooth from green to transparent (not cut off). My current state is:
div {
background-image: radial-gradient(transparent, green, transparent);
border-radius: 100%;
height: 300px;
width: 300px;
}
<div></div>
Is there any way to make it in HTML and CSS, without using canvas or svg (fiddle). I can't use the image, because I would like to render different widths and thicknesses of this shape.

You can play with CSS radial gradient in this site.
I achieved what you want, here's a demo. Just play around with the percentages to get the desired output.
div {
background: radial-gradient(circle, rgba(0,128,0,0) 50%, rgba(0,128,0,1) 60%, rgba(0,128,0,0) 70%);
width: 300px;
height: 300px;
}
<div></div>

Here is a solution that will give you exactly the 50px of thickness you want. You can also make it a variable to adjust it like you want:
.box {
--t:50px;
background:
radial-gradient(farthest-side,transparent calc(100% - var(--t)), green, transparent 100%);
display:inline-block;
height: 250px;
width: 250px;
}
<div class="box"></div>
<div class="box" style="--t:80px;"></div>
<div class="box" style="--t:100px"></div>

div {
background-image: radial-gradient(transparent, transparent 100px, green 150px, transparent 200px, transparent);
border-radius: 100%;
height: 300px;
width: 300px;
}
<div></div>
I've just used some random px values. Edit them as your requirements. Here is the Santax: radial-gradient(color width, color width, color width, ...) width can be set in px, rem, % or any css unit.

It's not a perfect replica but it's close enough. The trick is to use mask.
div {
border-radius:50%;
background:linear-gradient(green, green, green);
-webkit-mask: radial-gradient(transparent 330px, #000 90px);
mask: radial-gradient(transparent 330px, #000 90px);
}
div:before {
content:"";
display:block;
padding-top:100%;
}
<div class="box"></div>

Related

Is it possible to create a css based gradient on a fixed height scale?

I have a div that gets resized programmatically and sits inside a wrapper div. I would like the background color of the (inner) div to be a gradient, but with the gradient based on the height of the wrapper div.
For example, the gradient could be something like background: linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%)
When the inner div is less than 50% of the height of the wrapper div, I want it to be completely green, but if it gets to 70%, it would start to turn yellow at the top, at 80% it starts going orange at the top and if it hit 100% it would have the full gradient. See the codepen below for an example of what I mean in terms of the colors.
The inner div will be resized every 10th of a second or so and will look similar to an audio peak meter.
Is this possible to achieve with pure CSS, or do I need to use javascript? If I use javascript, would it be more performant to have a bunch of css classes and switch them depending on percentage, or color things directly?
I could achieve this with multiple blocks, something like https://codepen.io/octod/pen/vPQLVo (not mine), but ideally I want it to be one continuous block of color with a smooth gradient.
I could also achieve it by keeping the inner div full height and resizing an overlay div, but unfortunately I have a transparent background, so this is not ideal.
EDIT: As requested, this is what I currently have that does not work (it shows the full gradient when the inner div is not the full height). I have simplified it and put css inline for this post.
real snippet: (Edited by Mister Jojos - this is not representative of my code, but the accepted answer is based on this version, so I have left it like this)
.outer {
display: inline-block;
height: 400px;
width: 40px;
background-color: dimgrey;
padding: 5px;
margin: 1em;
}
.outer > div {
width: 100%;
}
#inner50 {
height: 50%;
background: linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%);
}
#inner70 { /* please set the gradient values */
height: 70%;
background: linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%);
}
#inner100 { /* please set the gradient values */
height: 100%;
background: linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%);
}
<!-- result in case 50% -->
<div class="outer"> <div id="inner50"></div> </div>
<!-- result in case 70% -->
<div class="outer"> <div id="inner70"></div> </div>
<!-- result in case 100% -->
<div class="outer"> <div id="inner100"></div> </div>
Javascript snippet:
// this function is called every 1/10th of a second
function updateMeter(newHeight) {
getElementById("inner").style.height = newHeight+'px';
}
Simply fix the size of the gradient to the size of the outer div:
.outer {
display: inline-block;
height: 400px;
width: 40px;
background-color: dimgrey;
padding: 5px;
margin: 1em;
}
.outer>div {
width: 100%;
background:
linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%)
top/ /* place it on the top */
100% 400px; /* width=100% height=400px */
}
#inner50 {
height: 50%;
}
#inner70 {
height: 70%;
}
#inner100 {
height: 100%;
}
<!-- result in case 50% -->
<div class="outer">
<div id="inner50"></div>
</div>
<!-- result in case 70% -->
<div class="outer">
<div id="inner70"></div>
</div>
<!-- result in case 100% -->
<div class="outer">
<div id="inner100"></div>
</div>
Also like below:
.outer {
display: inline-flex;
height: 400px;
width: 40px;
background-color: dimgrey;
padding: 5px;
margin: 1em;
}
.outer>div {
width: 100%;
margin-top:auto;
background:
linear-gradient(0deg, green 0%, green 50%, yellow 80%, orange 90%, red 100%)
bottom/ /* place it on the top */
100% 400px; /* width=100% height=400px */
}
#inner50 {
height: 50%;
}
#inner70 {
height: 70%;
}
#inner100 {
height: 100%;
}
<!-- result in case 50% -->
<div class="outer">
<div id="inner50"></div>
</div>
<!-- result in case 70% -->
<div class="outer">
<div id="inner70"></div>
</div>
<!-- result in case 100% -->
<div class="outer">
<div id="inner100"></div>
</div>

Only fade part of a background to white with CSS style sheet

I'm trying to use this code in a CSS stylesheet:
.layered-image {
background: linear-gradient( to right, transparent, white 40% ),
url("http://www.azlro.org/chad/images/IMG_3699-1920x1080.JPG");
}
...to fade the background image from the image itself to white from left to right. However, I want some of image (500 pixels) to not fade at all and then start fading from there. Is that possible?
This can be achieved by using the ::before selector.
The ::before selector inserts something before the content of each selected element(s), in your case, the linear-gradient 'layer'.
I'm not totally sure this is what you are after, but hopefully this will guide you to a solution for your project. You will have to play around with the opacity, width and possibly other factors to get it exactly how you want.
As the above commenter suggested, you can add values to each color inside your linear gradient to determine the amount that you want to persist, such as:
linear-gradient(to right, transparent 500px, white);
html, body {
width: 100%;
height: 100%;
}
.layered-image {
width: 100%;
height: 100%;
background: url('https://upload.wikimedia.org/wikipedia/commons/6/62/Starsinthesky.jpg') center center no-repeat;
background-size: cover;
}
.layered-image:before {
content: '';
position: absolute;
background-image: linear-gradient(to right, transparent, white);
opacity: 2.5;
height:100%;
width:100%;
}
<div class="layered-image">
</div>
Use opacity:
.layered-image {
opacity:0.8;
}
Simply adjust the gradient:
.layered-image {
height: 200px;
background: linear-gradient( to right, transparent 0,transparent 200px /*edit this value*/ ,white 60%),
url("https://lorempixel.com/1000/800/") center/cover;
}
<div class="layered-image">
</div>

Background gradient as two tone solid color - one color width in px

div {
height: 50px;
width: 100%;
background-image: linear-gradient(to right, white 50%, red 46px);
}
body {
padding: 20px;
}
<div></div>
I'm trying to use linear gradients as a two tone solid color background in a div.
The div can be any width, and I would like one of the colors to have a specified width in px - and the other color to fill up whatever is left of the total width. Is that possible as all?
Like:
div {
background-image: linear-gradient(to right, white auto, red 46px);
}
You Can simply go with:
Use the fixed background colour first then just put 0 in the second colour it will fill the rest of the div.
background: linear-gradient(to right, lightgreen 19px, darkgreen 0);
This will work fine for you.
div {
display: inline-block;
background: linear-gradient(to right, lightgreen 19px, darkgreen 0);
width: 50%;
height: 100px;
color: white;
text-align: center;
}
<div>
Test
</div>
Hope this was helpfull.
You can try this :
Use the value needed for the first color (here 46px) and simply use a small value for the second color (between 0 and 45px). Then change the direction of the gradient depending on your needs.
div.first {
height:100px;
background-image: linear-gradient(to right, red 46px, blue 40px);
}
div.second {
margin-top:10px;
height:100px;
background-image: linear-gradient(to left, red 46px, blue 0px);
}
<div class="first">
</div>
<div class="second">
</div>
I think this is a nice time to use css variables, we can set a variable as a breakpoint and only have to update that one variable when moving the gradient.
div {
--gradient-break: calc(100% - 46px);
height: 50px;
background-image: linear-gradient(to right, darkgreen var(--gradient-break), tomato var(--gradient-break));
}
<div></div>
You can use this method to make a Javascript controlled progress bar.
let progressCounter = 0;
setInterval(function() {
if (progressCounter >= 100) {
progressCounter = 0;
} else {
progressCounter++;
}
document.querySelector('.progress').style.setProperty('--gradient-break', progressCounter + "%")
}, 50)
div.progress {
--gradient-break: 0%;
height: 50px;
background-image: linear-gradient(to right, darkgreen var(--gradient-break), tomato var(--gradient-break));
}
<div class="progress"></div>
I'm setting the progress percentage with document.querySelector('.progress').style.setProperty('--gradient-break',progressCounter+"%") and the css is taking care of the rest.
Hope this is helpful.

CSS gradient: define width in pixels

Please take a look at this fiddle: http://jsfiddle.net/jpftqc26/
A CSS gradient, starts black from left, turns into red, then back to black again. Really simple.
Is there any way I can make the red part 500px wide and the black parts fill the screen, whatever the resolution? With red in the middle, just like in the fiddle.
Is there a way do define a width in pixels, between color stops, in a CSS gradient?
Code:
.test_gradient {
background:
linear-gradient(
to right,
#000000,
#000000 20%,
#ff0000 20%,
#ff0000 80%,
#000000 80%
);
Yes. you can do this with hard pixels points and the use of the calc function.
Just set them as such:
http://jsfiddle.net/jpftqc26/9/
CSS:
.test_gradient {
background:
linear-gradient(
to right,
#000000 0px, /* Starting point */
#000000 calc(50% - 250px), /* End black point */
#ff0000 calc(50% - 250px), /* Starting red point */
#ff0000 calc(50% + 250px), /* End red point */
#000000 calc(50% + 250px), /* Starting black point */
#000000 100% /* End black point */
);
Another way to do it, without using calc(), is to use 2 different gradients
.test_gradient {
background-image:
linear-gradient( to left, #ff0000 0px, #ff0000 250px, #000000 100px), linear-gradient( to right, red 0px, #ff0000 250px, #000000 100px);
background-size: 50.1% 1000px;
background-position: top left, top right;
background-repeat: no-repeat;
}
One goes to the right, the other to the left, and each one has half the total width
fiddle
At the moment I can't think of how to do it with only CSS gradients and a single element.
Given your example, and assuming an extra div is ok, then here's an alternative approach without gradients (http://jsfiddle.net/jpftqc26/2/):
HTML
<body class="background">
<div class="foreground"/>
</body>
CSS
html, body {
width: 100%;
height: 100%;
}
.background {
background-color: #000000;
}
.foreground {
background-color: #ff0000;
width: 100%;
max-width: 500px;
height: 100%;
margin-left: auto;
margin-right: auto;
}
This produces the same effect, uses one additional element, and provides a red foreground that will grow to a max of 500px wide--beyond that it is all black on both sides. If you want the red to always be 500px wide then just remove the max-width rule and change width to 500px.
If you want that black part was flexible and red part was fixed you could use something like this:
html{height:100%;}
.test_gradient {
background: #000000;
position:relative;
margin:0;
height:100%;
}
.test_gradient:after{
content:'';
position:absolute;
top:0;
height:100%;
width:500px;
left:50%;
margin-left:-250px;
background:#f00;
}
DEMO
I think that the best solution, without adding any html element, is to use an image as background:
.test_gradient {
background: url('http://s14.postimg.org/zf0kd84lt/redline.jpg') repeat-y #000 center top;
}
http://jsfiddle.net/Monteduro/jpftqc26/3/

css background repeat-x, strech-y

I have a striped background with a gradient which I want repeated in x and stretched in y. I thought this would work:
background: url(bg.jpg) repeat-x;
background-size: auto 100%;
But it either stretches in y or repeats in x, never both at same time:
http://codepen.io/anon/pen/JCjEb
Edit: Note that I cannot simply repeat in y since the striped background also have a gradient (dark in bottom, lighter at top).
Instead of giving it width auto, give it the width of the image (36px).
http://codepen.io/thgaskell/pen/Bjsix
CSS
.c {
background-size: 36px 100%;
}
You can just use background: url(bg.jpg) repeat; without background-size. Here is the example.
The problem is that when you set the background-size to auto 100%, it's going to stretch the whole image proportionally, thus making the stripes too wide and distorted. Set the x part of the background-size to the width of the original image, and it won't stretch anymore.
.b {
background: url(http://img.photobucket.com/albums/v63/promisedyouheaven/stripe2.gif) repeat;
background-size: 35px 100%;
}
http://jsfiddle.net/BsAcY/
Try background: url(bg.png) center repeat-x;
Not sure about IE8 and below though, if that's a problem.
.a { background:
url(http://img.photobucket.com/albums/v63/promisedyouheaven/stripe2.gif)
repeat; display:block; width:500px; }
Is that what you need?
Try this
** HTML **
<div class="b"></div>
** CSS for bg image & gradient **
.b { /* unprefixed gradient for example only*/
background:
linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(255,255,255,0) 100%),
url(http://img.photobucket.com/albums/v63/promisedyouheaven/stripe2.gif);
background-repeat:repeat;
}
div {
height: 300px;
width: 200px;
margin-right: 50px;
border:1px solid grey;
}
Codepen Example

Resources