Rainbow Squares
There are some pretty interesting/absurd things that can be done with CSS these days. Between the range of properties afforded by CSS3, precision animations with keyframes, or the sheer power of a metalanguage like SASS, there's a huge world of possibilities to explore. I've recently been having some fun with CSS-driven rainbows and shapes, and stumbled across some interesting results and tidbits of CSS to share. Whether or not any of this *should* be done, I'll leave to the reader to decide.
Rainbow Power
My first target was to be able to make a simple shape with a continuous rainbow gradient as the border. To start, we need some colors and a way to use them. Once you get a set of colors, it's easy enough to slap them in a linear-gradient, giving us the basic building block of a "rainbow shape" -
That's all peachy, but we need much more power to craft shapes with a continuous gradient around the border. If we create for sides of a square and apply the above gradient to them, each side would have the complete gradient on it and it would clash with the following edge. So, there needs to be a way to intelligently stagger the gradient.
For this, I turned to SASS mixins with color stops. The colors that comprise a linear gradient can have their positions specified within a color stop, so the key is figuring out what colors are needed where for a given side. (Similar effects can be done by manipulating background sizes and positions; more on this later.)
To start, we have to make sure that our list of colors ends with the same one it starts with, so the transition is smooth around the entire border. Colors are blended using the mix function to start and end the gradient, and any color that "peaks" on the given side is placed at the right position with a color stop. Here's the complete mixin:
Now, we can put this to work in creating shapes. To start, we can create squares by sampling the gradient at 25% intervals:
This is a little boring by itself, and can use some animation to jazz it up. Maybe a little rotation, paired with some spline-driven motion and some carefully selected animation delay values (click the image for animation) -
Gradient Motion
Next, I decided to have a go at animating the gradient. Browsers don't currently have much by ways of direct gradient animation support, but there are a few ways to get around it. By playing with background position and sizing, we can get the desired effect. The size can be used to expand the gradient beyond what's visible, and the position can be used to gradually manipulate which part is showing.
To animate a simple square, the right amount of background can be shown by setting the background size to 50%, and the background width to 800%. The math motivating this is a bit tricky, but it comes down to two things. One, you want 100% for each side, and 50% x 800% -> 100%. The other is that this arrangement greatly simplifies the keyframe animation. Setting the background size at 50% means a looping animation can be consistently done by moving the background position from 0% to 100%.
This does come with some inconvenience - putting the width to 800% requires a wrapper element to truncate the extra part. Still, it's mostly functional, and easy enough to get shapes with looping gradient changes -