Skip to content

Revisit use of button-groupz-index stacking, consider using CSS specificity instead #7732

@mm-wang

Description

@mm-wang

The $control-group-stack list in forms/_common.scss uses z-index values to control which button's border is visible when buttons overlap in a button-group. This is necessary because adjacent buttons use negative margins (margin-right: -1px) to collapse borders.

The current implementation:

  • Defines a 16-item Sass list with state names in a specific order
  • Uses list.index($control-group-stack, "state-name") to get z-index values (1-16)
  • Requires careful ordering to ensure disabled buttons don't get visually "overridden" by hover/active states on adjacent buttons

Issues with this approach:

  • Relies on sass:list module, making it harder to migrate to pure CSS
  • The z-index ordering is non-obvious and fragile - adding new states requires careful consideration of the entire list
  • z-index is being used to solve a CSS specificity problem, not an actual stacking context problem
  • The list is duplicated/referenced across multiple files (_button-group.scss, _control-group.scss)

Proposed Solution

Use :not(:disabled) guards on interactive states instead of z-index manipulation:

.#{$ns}-button {
  &:hover:not(:disabled):not(.#{$ns}-disabled) {
    // hover styles
  }
  
  &:active:not(:disabled):not(.#{$ns}-disabled) {
    // active styles  
  }
  
  &:disabled,
  &.#{$ns}-disabled {
    // disabled styles always apply
  }
}

This eliminates the need for z-index stacking entirely, as disabled buttons will never have hover/active styles applied.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions