This experiment uses a weather station API (Application Programing Interface) and connect it to your daily browsing experience. If there is wind outside the wind also blows on the element of any webpage.
This experiment uses a weather station API (Application Programing Interface) and connect it to your daily browsing experience. If there is wind outside the wind also blows on the element of any webpage. If there is humidity outside elements become more blurry. During the sunset, images turn sepia.
The weather extension is a poetic way of showing how websites are continuously changing, how they were never meant to be a fixed version of themselves. Designing for the web means embracing change, connectivity, and being surprised. We liked that a website you can look at inside of your room make you suddenly very aware of the outside weather, a symbolic way to make screen-space and outside-of-the-screen-space touch each other.
To blow
Before collectively connecting the script to an API, and adding a bunch of other CSS weather interpretation, the idea was to blow on webpage. The original code came from Martin Lemaire stating he wanted to also do action on webpage: to blow on them; and that in that sense it wasn't purely declarative. In his script (rewritten below from memory with some liberty) the blowing was dynamically added through javascript to accomodate for random rotation of every elements.
function blow( wind ) {
let all = document.querySelectorAll('body *');
for(let e in all){
e.style.transition = 'transform 1s ease';
e.style.transform = `rotate(${ Math.random() * wind * 2 - wind }deg)`;
}
}
blow(1);
//or
blow(10);
The function loops through all the element in the body and blow a random amount on each of them.
Functionnal wind
However declarativeness can be at the tip of your writting. In other word, declarativeness is a mode of thinking rather than an immutable characteristic of programming language. Many people argued over the internet how javascript allow for both declarative and imperative approach, using the following example.
function blooow(e, wind){
e.style.transition = 'transform 1s ease';
e.style.transform = `rotate(${ Math.random() * wind * 2 - wind }deg)`;
}
function blow( wind ) {
let all = document.querySelectorAll('body *');
Array.from(all).map(e => blooow(e, wind));
}
blow(1);
//or
blow(10);
While the code execution may be the same, it is declared differently, in a more declarative (or functionnal) style. There isn't any loop anymore, we just say that every element is mapped to a blooow function that make each of them move individually.
Declarative wind
We see we don't have a loop anymore, but still, it doesn't feel "as declarative as CSS". In CSS a simple selector followed by curly braces does the job of a loop. The thing that we are actually missing here is the per elements randomization.
Interestingly, 1 year and a half after the first version of the weather extension, randomness in CSS is being drafted in the new CSS Values and Units Module Level 5 - a working draft not implemented by any browser as of November 2025. It is also proposed to include a --per-element that reroll the dice for every element. A purely declarative wind on a webpage would like like the following.
:root{
--wind: 1deg;
--negative-wind: calc(-1 * var(--wind))
}
body * {
transform: rotate(random(--per-element, var(--negative-wind), var(--wind)));
transition: transform 1s ease;
}