Delightful User Interfaces: Easter Eggs
By Cole Turner
The first easter egg appeared in the 1979 Atari release of Adventure the video game. Often hidden in the edges and corners of software, engineers have been leaving behind secret clues ever since. Those that hunt for clues and discover easter eggs are given the opportunity to share in delight something surprising, odd, or mysterious.
Sharing in delight is what drives us at Netflix. From building a great customer experience to delivering great original content around the world. We take great pride in making our members happy. And our guests too!
Something sinister awaits…
For the final season of Marvel’s Jessica Jones, we wanted to do something extraordinary for the fans. We planted an easter egg for members and non-members. Members were given the opportunity to search for clues that were planted through social media and discover a hidden trailer. For fans, we planted an easter egg in the title page that when activated would transport the user to another world in the cinematic universe.
In the background, a lightbulb would dangle from the ceiling and flicker. On the desktop, when hovered over, the light surges more brightly. Clicking the lightbulb would reveal The Dark Room of the season’s mysterious malefactor. A deep red casts upon the photos strung along a wire. Among these photos are our heroes, Jessica Jones, and friends. The scene sharpens to focus as the trailer, one of the photographs, develops to reveal a hidden message from the sinister Gregory Sallinger.
What you are seeing is not video or WebGL. There are no motion assets besides the trailer. We created the visual effects with the power of CSS animations and transitions. Using a video motion asset would have cost upwards of 10MB.
The static images and stylesheets only cost 10kb in CSS and 722kb in images. The background image was compressed, from 5mb to 108kb, without sacrificing detail or color. Using CSS gave us the ability to create a rich and stunning darkroom takeover which works on desktop browsers and mobile web.
Let’s take a look again a little more slowly:
Let’s focus on the three main elements: the lightbulb, the background image, and the trailer.
Turning on the lights
For the lightbulb animations, we worked with our partners in design, Kai Hung and Casey Kaliszewski, to create blinking and flickering animations that felt almost like a power surge. We used three images for the off, flicker, and on states. We could do this by layering the images over one another:
Then using the animation property, the frames control the opacity of the image in front to create the effect.
To create the swinging motion the parent container was animated using transform (rotateX, rotateX, and translate). This was quite a challenge using a static image because dangling light bulbs don’t just move left to right, rather they circle as such:
Over 30 frames were created to mimic the movement of a lightbulb and the surge of electricity through the filament.
Lighting: Flare and Flair
Dynamic lighting or performance: choose one. This was the choice we had to make when deciding on the lightbulb’s flare. We chose performance because our display pages render a number of videos and DOM elements.
In our first attempt to create flare we used a really neat CSS trick using filter: drop-shadow(…). This takes an image and creates a silhouette of the shape in any color. This made for a really nice area of effect around the shape of the image. However, that would also cast a shadow from the wire too, which is not what we wanted.
We tried another approach. Using a simple red div element with the border-radius maxed out, and filter: blur(80px) to create an area of effect. Using mix-blend-mode: color — the color of the red blended well with the background image. It looked stunning.
Bringing the background to focus
The darkroom experience explodes from the lightbulb which makes for incredible immersion as the scene sharpens to focus. A background image is layered over the background artwork. The image expands until it envelopes the whole page.
We used another neat property called clip-path that masks the image with a circle. Using transition, the circle could grow to expand to the shape of the container.
We ran into some trouble along the way. As the animation neared completion, the background image would flicker. In some cases, the image would disappear entirely. What was challenging was how it would work in some browser resolutions, but disappear in others.
We tried every trick in the book. These animations were already taking advantage of any property that would force the browser to use hardware acceleration:
StackOverflow to the rescue! This answer reaffirmed our suspicion that we were just doing too much animation with one element. Moving the opacity transition to the parent element resolved the issue.
“I encountered glitchy behaviour when applying hardware acceleration to parts of the page that were already accelerated”- Wesley Hales
More Than a Trailer
What’s great about working as a User Interface Engineer at Netflix is the collaboration. We collaborate with designers when building this experience to bring the best ideas to life. One of these ideas was to make the trailer part of the scene.
What if the trailer could be one of the antagonist’s photographs? Together we created this concept that really made the trailer more immersive as if you’re stepping into the dark room.
Using a gradient and a delayed animation, the trailer appears shortly after the transition which simulates the behavior of an instant photo developing. Pretty neat!
Orchestrating these animations creates an immersive takeover that transports us from one setting to another. The efforts of marketing, design, and engineering — meld together to make this experience feel all the more visceral.
Building an experience like this feels very rewarding because we get to be creative and share delight with our customers. The pleasure is ours to create this easter egg to excite fans and build anticipation. And with only 732kb of static images and CSS!
That’s what we call delightful engineering.