Skip to content

[selectors-5] “initial state” selector #14360

Description

@bramus

I recently had a chat with @jantimon about not being able to set the background-color of a button but only if that button is in initial state.

Effectively, the code they have is this:

@layer base-ui {
  button {
    background: red;
    &:disabled {
      background: purple;
    }
  }
}

@layer shop {
  .primary {
    background: orange;
  }
}

The problem for them is that the background-color of the .primary:disabled also becomes orange, due to the declaration in the shop layer. Ideally, they want to overwrite the background-color only for the .primary in its initial state (no :hover, no :active, no …).


As for some workarounds I suggested them to either:

  1. Use Custom Properties:

    @layer base-ui {
      button {
        background: var(--bg, red);
        &:disabled {
          background: purple;
        }
      }
    }
    
    @layer shop {
      .primary {
        --bg: orange;
      }
    }
  2. Target all non-states

    .primary:where(:not(:disabled, :hover, :active, :focus, :focus-visible)) {
      background: orange;
    }

    You can see this one in action at https://codepen.io/editor/bramus/pen/019fb84d-6030-7a93-85c5-41231540f5b8/1b5c8b2345114c13a70d48674240c349

  3. Carefully curate the layers

While these workarounds do work, each one has issues or complexity involved:

  1. Not everyone can just rewrite their code to use custom props
  2. The non-state selector would require you to list all states … and then also update that selector should more states become available over time.
  3. Carefully curating the layers seems tedious, especially in larger codebases. As Jan told me: “we have a medium sized app with 8.000+ files - we can't sort all of these into layers and keep track which wins or loses in which scenario”

Maybe we could offer authors a “initial state” type of selector, so that they can target an element in its initial state?

Something like this:

@layer shop {
  .primary:initial-state {
    background: orange;
  }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions