State Layers

First Published On:
April 25, 2024
Last Updated:
May 4, 2024


Figure 1. Animation demonstrating state layer implementation.

No items found.

State Layers are an interesting solution to a common interactivity problem: you can’t do CSS transitions on non-solid backgrounds. Background gradients and images don’t work with CSS pseudo-classes like :hover and :active, which is a bit of a pain for web developers.

Google came along and came up with something called State Layers, and while I’m almost positive I’m misunderstanding what they meant by the term, I’ve designed LiftKit to have its own version of state layers, which solve this pseudo-class problem.


A state layer in LiftKit is an invisible <div> that sits inside another element and responds to user interactions on its parent. State layers have pointer-events: none; and they respond to :hover, :active, and :focused pseudo-classes.

When a user hovers, clicks, taps, or selects the button with their keyboard, the state layer’s opacity will change.


A great example of state-layer use is in buttons, where the state layer is nothing more than an empty div with the background color set to whatever the button text is. The visual aid below explains how it works. Note that when the cursor hovers over the button, it toggles opacity on the child state-layer element, not the parent itself.

A clarification about the word “state”

“State” is used a lot in modern programmming, but its meaning varies slightly depending on the context in which it’s used. In React, “State” refers to a very specific programming concept central to its component-based infrastructure. In DevOps workflows, State can refer to something else entirely, such as the state of a container.

LiftKit uses “state” in a general sense. The “state” of an element in LiftKit refers to how the user is currently interacting with it. Borrowing from material, an element’s state can be any of the following:

  • Enabled, which is how it looks when it’s just sitting there not being interacted with
  • Disabled, when the user’s not interacting with it and they couldn’t if they wanted to
  • Hovered, when the user’s pointer is hovering over it
  • Pressed, when the pseudo-class is set to “active,” i.e. when it’s being clicked on or pressed
  • Focused, when you’re selecting it with your keyboard or after pressing it and before doing anything else.

Recommended Usage


Resources that mention this topic

No items found.