Custom properties in Microsoft Edge

Custom properties are a very powerful tool for web developers to create amazing web experiences. If you don't know what custom properties are or how they work, we suggest reading our blog post CSS Custom Properties in Microsoft Edge which covers them in detail.

Deciding on the demo

When discussing the various demo ideas for custom properties we wanted to ensure it covered the major benefits of custom properties; cascade, dynamic update, animatable. One of the things we realized where custom properties are really powerful is color math within color functions. We decided to utilize this approach for changing the time of day because one of the most noticeable changes in your surrounding environment throughought the day is the change of colors from warm to cool (depending on the amount of sun of course).

Creating the feel of day to night

In order to do this, designer Stephanie Drescher, worked out the various levels that had similiar color values and could be adjusted together. These levels within the illustration and their percentage adjustment were provided to Greg Whitworth who applied these to rgb() modifiers of the custom properties. Here's an example of one of these levels and its associated rgb() custom property modifiers:

--building-r-mod: 0;
--building-g-mod: 0;
--building-b-mod: 0;

And then to utilize this on one of the buildings we do the following:

.distant-building__window
{
    fill: rgb(
    calc(111 + (111 * var(--building-r-mod))),
    calc(79 + (79 * var(--building-g-mod))),
    calc(85 + (85 * var(--building-b-mod)))
    );
}

Changing the time of day

In order for you to be able to click the button and have it switch we needed to utilize the setProperty() method. Since we have many custom properties, we created an array of name/value pairs and passed it to a function to update all of them. Here is the code to change from day to night:

var night = function() {
  vars = [
    {name: "--sky-start", value: "rgb(100, 75, 128)"},
    {name: "--sky-end", value: "rgb(45, 45, 81)"},
    {name: "--light-r-mod", value: "-17.5"},
    {name: "--light-g-mod", value: "25"},
    {name: "--light-b-mod", value: "110"},
    {name: "--show-stars", value: "block"},
    {name: "--building-r-mod", value: "-.25"},
    {name: "--building-g-mod", value: 0},
    {name: "--building-b-mod", value: ".15"},
    {name: "--park-r-mod", value: "-.30"},
    {name: "--park-g-mod", value: "-.20"},
    {name: "--park-b-mod", value: "-.08"},
    {name: "--light-source", value: "url(#moon)"}
  ];
  setVars(vars);
  getVars(vars);
}

function setVars(variables) {
  variables.forEach(function(prop) {
    rootStyle.setProperty(prop.name, prop.value);
  }, this);
}

Animating the dog's tail

Another aspect of custom properties we wanted our demo to highlight was that you can animate a custom property. However, since custom properties can't be interpolated we needed an animation that would look fine without interpolation. We discussed this, and decided to make the dog's tail wag because this occurs quickly in real life so your brain fills in the gaps even though it isn't interpolating. We did this for the twinkling stars and window lights turning on and off as well.

Here is the code for the dog's tail:

.tail
{
    transform: translateY(10px) rotate(var(--tail-rotate));
    transform-origin: 60% 84%;
    animation: wagTail 250ms infinite;
}

@keyframes wagTail
{
    from
    {
        --tail-rotate: 15deg;
    }
    to
    {
        --tail-rotate: 25deg;
    }
}