RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconShows IconOpen Source Software IconSpeaking IconTools IconShuffle IconNext IconPrevious IconCalendar IconCalendar Edit IconNotebook IconObservable Notebooks Icon
Text emphasized alt text example
A series of images of an avatar doing a bunch of skateboard tricks.3 min read

Make some hacky noise with CSS gradients

css

Here's an effect I stumbled on and thought was kinda cool. I found it by animating the size of the ring in a repeating radial gradient to 0px with @property, really slowly, and notice that when it got near 0, it started to freak out.

Then I started to wonder.

The Setup #

Here's the mask I was working with at first, a nice reasonale 5px and 5px gap radial repeating mask:

.noise {
  --lines: 4px;
  
  mask: repeating-radial-gradient(
    circle at center,
    #000,
    var(--lines),
    #000,
    0, /* transition hints make code easier to manage */
    #0000,
    calc(var(--lines) * 2),
    #0000 0 /* trailing 0 is part of the hard stop logic */
  );
}

Still a pretty sweet effect over some text I think!

The Trick #

BUT, when you change that --lines value to something super small, it starts to distort and go into subpixel rounding stuff?

.noise {
  --lines: 0.0003px;
}

And boom, noise. At certain times it looks like radial noise too. Trails of its origins.

Animating it #

I already knew that @property could animate the noise because of how I stumbled upon the effect. What I didn't know yet, was what were the fun knobs I could turn?!

Kick off the gradient animation fun with an @property:

@property --lines {
  syntax: "<length>";
  inherits: false;
  initial-value: 0.00010px;
}

And some keyframes, subtly animating from one tiny little subpixel value to another.

@keyframes liner {
  50% {
    --lines: 0.00012px;
  }
}

Link these things up for animation on our element:

@import "https://unpkg.com/open-props/durations.min.css";

.noise {
  animation: liner var(--hour) linear infinite;
}

and watch the noise!

Also, observe the absolute chaos while the power of CSS handles it like a 60fps game engine.

Outro #

The levers / what you should toy with:

  1. the delta in values
  2. values themselves
  3. duration

Even try adding reasonable values, like 10px lines with a reasonable duration like .5s or var(--atom).

Mentions #

Join the conversation on

27 likes
8 reposts
  • Brett Peary
  • GENKI
  • Tamas
  • Phil Picton ????
  • Aleš Roubíček
  • Fil Duarte
  • Jack Iakovenko
  • Tyler Sticka
3 pingbacks

@argyleink Great post! Also had to look into how you made the pretty headlines of your posts and noticed that `background-clip: text` can now be used everywhere, and even unprefixed since Chrome 120 – so one thing led to another and I filed an issue to update the browser compat data ???? https://github.com/mdn/browser-compat-data/pull/21968

`background-clip: text` supported in Chrome 120 by voxpelli · Pull Request #21968 · mdn/browser-compat-data
Pelle WessmanPelle Wessman

@argyleink Oh that reminds me of @css's article: https://css-tricks.com/making-static-noise-from-a-weird-css-gradient-bug/

You could do some cool risograph effect with these by replacing the mask with a noise gradient on top of a standard one — results depend on the colour of course. ????

https://codepen.io/chriskirknielsen/pen/JjzJqmp

Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks
Christopher Kirk-NielsenChristopher Kirk-Nielsen

Crawl the CSS Webring