openedx / openedx/paragon

z-index revamp (z-index hooks)

Open
#2,990 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

best addressed by breaking change
Dominant language
JavaScript
Stars
140
Forks
100
Avg merge
1h 3m
Merged PRs (30d)
30

Description

from @bradenmacdonald on slack

Hey folks, does Paragon have a philosophy for handling z-index conflicts? For example, we are trying to use a Form.Autosuggest inside a modal, and the autosuggest dropdown is appearing behind parts of the modal (screenshot). I couldn't see any docs about this, and could only find these pre-defined z-index classes. If that's all that Paragon has right now, it's too simplistic. Because obviously a modal should normally be higher than a dropdown, but a dropdown in a modal should be higher than a modal. I would also argue that if you had a proper layer system, you could put popover and tooltip lower than modal as well.

One approach I know of for solving this is using utility classes (Tailwind style). Currently, the Form.Autosuggest has some code like .pgn__form-autosuggest__dropdown { ... z-index: $zindex-dropdown; ... } . Adding CSS rules to give such components a higher z-index conditionally (when they're in a modal) is problematic, because either the Autosuggest component has to be aware of all the possible layers like modals and account for them (.modal-layer & { z-index: $zindex-modal + $zindex-dropdown }) or the Modal component has to be aware of all the possible components and account for them (& .dropdown { z-index: $zindex-modal + $zindex-dropdown).
=> But if you use a small set of predefined classes like .zindex-dropdown so that the autosuggest has that extra utility class, then it's a bit easier to plan for the interactions like .zindex-modal .zindex-dropdown .zindex-tooltip { z-index: $zindex-modal + $zindex-dropdown + $zindex-tooltip } (a tooltip over a dropdown in a modal), and your components don't have to otherwise be aware of each other.

But as you can see from the example of "a tooltip in a dropdown in a modal", managing those rules can still get complex. So I have found that a simple zindex hook provides the cleanest solution for this problem, by using the React tree to determine the z-index of each component by using the z-index of its parent (from context) and adding some fixed amount based on the type of component. (example of use in a Modal)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the predefined z-index values in scss/core/_variables.scss and the Form.Autosuggest dropdown styles described in the issue. Read the linked useZIndex.ts implementation and its Modal example to compare the proposed approach with Paragon's current components. Done would require an agreed z-index strategy and its implementation across the affected components, with behavior for nested layers such as a dropdown or tooltip inside a modal.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.