I have been experimenting with layering radial gradients in CSS to create flower shapes, utilizing CSS trigonometric functions. If you’re unfamiliar with trigonometric functions and their relevance in our code, I have written a three-part series for Codrops that serves as an introduction.
To draw circles as background images using the radial-gradient() function in CSS, we can utilize the following code:
“`html
“`
“`css
.item {
background: radial-gradient(circle at 50% 50%, black 20%, transparent calc(20% + 1px));
}
“`
This code will produce a black circle at the center of the element with a radius equal to 20% of the element’s size. The calc() function is used to create smooth edges for the gradient, preventing jagged lines that may appear on certain screens.
To create different shapes, we can layer multiple gradients together using the following code:
“`css
.item {
background:
radial-gradient(circle at 50% 50%, black 20%, transparent calc(20% + 1px)),
radial-gradient(circle at 60% 70%, black 25%, transparent calc(25% + 1px)),
radial-gradient(circle at 35% 35%, black 15%, transparent calc(15% + 1px));
}
“`
For these flower shapes, we can utilize trigonometry to position the center of each circle. If we imagine placing each gradient circle on the circumference of a single circle, similar to a clock face, we need to determine the angle of each point on the main circle. This angle can be calculated by dividing 360 degrees by the number of circles in our flower shape. To enhance readability and reusability, we can employ custom properties:
“`css
.item {
–angle: 360deg / var(–numberOfCircles, 6);
}
“`
To calculate the x and y positions of each circle, we can utilize trigonometric functions. The x position is determined by multiplying the cosine of the angle (cos() function in CSS) by the radius, which represents the distance from the center. The y position is calculated using the sine function (sin() in CSS). Additionally, we need to shift our calculations to the center of the element to ensure the circles are centered:
“`css
.item {
–x: calc(50% + cos(var(–angle)) * var(–radius));
–y: calc(50% + sin(var(–angle)) * var(–radius));
}
“`
To allow for easy modification of the shape’s position, we can use custom properties:
“`css
.item {
–x: calc(var(–posX) + cos(var(–angle)) * var(–radius));
–y: calc(var(–posY) + sin(var(–angle)) * var(–radius));
}
“`
This code calculates the points for one circle, but we need to repeat this process for each circle in our shape. For example, if we have six circles, we need six sets of x and y variables:
“`css
.item {
–posX: 50%;
–posY: 50%;
–angle: 360deg / var(–numberOfCircles, 6);
–radius: 20%;
–a1: calc(var(–angle) * 1);
–x1: calc(var(–posX) + (cos(var(–a1)) * var(–radius)));
–y1: calc(var(–posY) + (sin(var(–a1)) * var(–radius)));
–a2: calc(var(–angle) * 2);
–x2: calc(var(–posX) + (cos(var(–a2)) * var(–radius)));
–y2: calc(var(–posY) + (sin(var(–a2)) * var(–radius)));
–a3: calc(var(–angle) * 3);
–x3: calc(var(–posX) + (cos(var(–a3)) * var(–radius)));
–y3: calc(var(–posY) + (sin(var(–a3)) * var(–radius)));
/* …and so on */
}
“`
If we were using Sass, we could utilize a loop to avoid repetitive code. However, for this demonstration, we are using vanilla CSS, which does not support loops.
Next, we can plug these values into the radial-gradient() functions. Custom properties are used to avoid repetition and facilitate easy modifications:
“`css
.item {
–size: 20%;
–color: black;
–grad: var(–color) var(–size), transparent calc(var(–size) + 1px);
–baseGradient:
radial-gradient(circle at var(–x1) var(–y1), var(–grad)),
radial-gradient(circle at var(–x2) var(–y2), var(–grad)),
radial-gradient(circle at var(–x3) var(–y3), var(–grad));
/* …and so on, up to 6 */
background: var(–baseGradient);
}
“`
In the final demo, I have added an additional circle at the center. If we want to add more circles or petals to our flower shape, we need to define the necessary additional variables (–x7, –y7, –x8, –y8, etc.) and add them to our background. Since we have already defined the –baseGradient variable for the background, we only need to append the new values and update the custom property for the number of circles:
“`css
.item:nth-child(2) {
–noOfCircles: 7;
background: var(–baseGradient), radial-gradient(circle at var(–x7) var(–y7), var(–grad));
}
“`
In the demos, I have also modified the size and radius variables to create different effects. There are numerous creative possibilities with these gradient effects, such as combining them with mix-blend-mode for image overlays or utilizing them as image masks. Please note that these demos rely on CSS nesting, which is a relatively new feature. Additionally, they can be animated using @property, although this feature may not work in Firefox yet.
Source link