Z-Index Classes

View source on GitHub

FixedZIndex and CompositeZIndex are utility classes that generate z-indices for Gestalt components.

Figma:

Web:

iOS:

Android:

A11y:

Accessibility

FixedZIndex

FixedZIndex is used for setting fixed z-index values. Use this class when you want to create an initial z-index to stack others on top of. FixedZIndex must be instantiated with a number.

import { FixedZIndex } from 'gestalt';

const fixedZindex = new FixedZIndex(1);

CompositeZIndex

CompositeZIndex is used for dynamically composing z-index values. Use this class to layer components on top of an existing z-index in the stacking context.

CompositeZIndex must be instantiated with an array of FixedZIndex or CompositeZIndex instances. CompositeZIndex returns the highest z-index value in the array +1.

import { CompositeZIndex, FixedZIndex } from 'gestalt';

const fixedZIndex = new FixedZIndex(1); //z-index value: 1

const compositeZIndex = new CompositeZIndex([fixedZIndex]); //z-index value: 2

const highestCompositeZIndex = new CompositeZIndex([fixedZIndex, compositeZIndex]); //z-index value: 3

Best practices

Do

Export FixedZIndex and CompositeZIndex rather than the z-index values itself.

// exporting file
import { FixedZIndex } from 'gestalt';

export const BaseZIndex = = new FixedZIndex(1);

// importing file
import { BaseZIndex } from './path/to/your/zindex/file.js';

const BoxWithZIndex = <Box zIndex={BaseZIndex}/>
Don't

Export constant z-index values to create FixedZIndex and CompositeZIndex.

// exporting file
export const BaseZIndex = 1;

// importing file
import { BaseZIndex } from './path/to/your/zindex/file.js';
import { FixedZIndex } from 'gestalt';

const BoxZIndex = new FixedZIndex(BaseZIndex);

const BoxWithZIndex = <Box zIndex={BoxZIndex}/>
Do

Use CompositeZIndex to compose z-indices.

// exporting file
import { FixedZIndex } from 'gestalt';

export const BaseZIndex = = new FixedZIndex(1);

// importing file
import { CompositeZIndex } from 'gestalt';

import { BaseZIndex } from './path/to/your/zindex/file.js';

const composedZIndex = new CompositeZIndex([BaseZIndex]);

const BoxWithZIndex = <Box zIndex={composedZIndex}/>
Don't

Use FixedZIndex to manually compose z-indices.

// exporting file
export const BaseZIndex = 1;

// importing file
import { FixedZIndex } from 'gestalt';
import { BaseZIndex } from './path/to/your/zindex/file.js';

const composedZIndex = new FixedZIndex(BaseZIndex + 1);

const BoxWithZIndex = <Box zIndex={composedZIndex}/>
Do

Use the lowest possible z-index values and compose them.

import { CompositeZIndex, FixedZIndex } from 'gestalt';

const PageHeaderZindex = new FixedZIndex(1);

const ArticleZindex =new FixedZIndex(1);

const ArticleHeaderZindex = new CompositeZIndex([ArticleZindex]);

const SheetZindex = new CompositeZIndex([PageHeaderZindex, ArticleHeaderZindex]);

const modalZindex = new CompositeZIndex([SheetZindex]);

const ModalWithZIndex = <Layer zIndex={modalZindex}><Modal/></Layer>
Don't

Use unnecessarily high fixed z-index values.

import { FixedZIndex } from 'gestalt';

const HeaderZindex = new FixedZIndex(1);

const MenuZindex =new FixedZIndex(1000);

const SheetZindex = new FixedZIndex(9999);

const modalZindex = new FixedZIndex(100000);

const ModalWithZIndex = <Layer zIndex={modalZindex}><Modal/></Layer>
Do

Wrap non-Gestaltifiable HTML tags in Box and pass z-index classes.

import { FixedZIndex } from 'gestalt';

const fixedZindex = new FixedZIndex(1);

const canvas = (
    <Box zIndex={fixedZindex}>
      <canvas
        id="myCanvas"
        width="200"
        height="100"
        style="border:1px solid #000000;"></canvas>
    </Box>
);
Don't

Extract z-index values from either z-index classes to use in non-Gestaltifiable HTML Tags. See z-index in non-Gestalt components to learn more.

import { FixedZIndex } from 'gestalt';

const fixedZindex = new FixedZIndex(1);

const canvas = (
  <canvas
    z-index={fixedZindex.index()}
    id="myCanvas"
    width="200"
    height="100"
    style="border:1px solid #000000;"></canvas>
);
Do

Use Layer instead of z-index when a component needs to visually break out of its parent container, for example, in the case of modals, sheets and tooltips. See z-Index in foundational components and ZIndex in Layer to learn more.

const modal = (
  <Layer>
    <Modal>
      <Text>Modal</Text>
    </Modal>
  </Layer>
);
Don't

Use Box with high fixed z-index values to position your components at the top of the stacking context or use them redundantly with Layer. See z-Index in foundational components and ZIndex in Layer to learn more.

import { FixedZIndex } from 'gestalt';

const MODAL_ZINDEX = new FixedZIndex(1000000);

const modalA = (
  <Box zIndex={MODAL_ZINDEX}>
    <Modal>
      <Text>Modal A</Text>
    </Modal>
  <Box>
);

const modalB = (
  <Layer>
    <Box zIndex={MODAL_ZINDEX}>
      <Modal>
        <Text>Modal B</Text>
      </Modal>
    <Box zIndex={MODAL_ZINDEX}>
  </Layer>
);

Variants

z-index in foundational components

Box, Sticky, and Layer are foundational components that have zIndex props. If any other components need to be positioned within their stacking context, wrap with one of these foundational components to set the z-index.

Layer creates a new stacking context. Unless there's a conflict with another z-index, don't pass unnecessary zIndex to Layer.

The following example sets a z-index in the Layer wrapping Sheet to position Sheet over the page header in the Docs. Set PAGE_HEADER_ZINDEX below 10 to see the importance of z-index in this example.

z-index in Layer

Modal and Sheet always require a parent Layer to position themselves outside the DOM hierarchy.

Components built on top of Popover, such as Tooltip, Dropdown and ComboBox, have a built-in Layer to be positioned outside the DOM hierarchy. To set the internal z-index value of Layer, these Popover-based components have zIndex props as well. This is used when placing the Popover-based components within another component wrapped in Layer that has a z-index set.

However, Modal and Sheet have a built-in ScrollBoundaryContainer wrapping their children, so you shouldn’t need to pass z-index values when using Popover-based children.

The following example sets a z-index in the Layer wrapping Modal to position Modal over the page header in the Docs. Thanks to ScrollBoundaryContainer, child Tooltips don't require z-index.

z-index in non-Gestalt components

FixedZIndex and CompositeZIndex work with Gestalt components. To stay consistent across the codebase using Gestalt’s zIndex classes, you can extract z-index values from both FixedZIndex and CompositeZIndex in cases where the component doesn’t accept Gestalt’s z-index classes.

import { FixedZIndex, CompositeZIndex } from 'gestalt';

const fixedZindex = new FixedZIndex(1);
const fixedZindexValue = fixedZindex.index(); // 1

const compositeZIndex = new CompositeZIndex([fixedZindex]);
const compositeZIndexValue = compositeZIndex.index(); // 2

However, this is an escape hatch that should only be used when the source code is not accessible, such as working with a third-party library. Otherwise, a better approach is to wrap the component or HTML element that needs a z-index in a Box. See Best Practices for more info.

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Component is not currently available in Figma.
Responsive Web
Ready
Component is available in code for web and mobile web.
iOS
Component is not currently available in code for iOS.
Android
Component is not currently available in code for Android.

Layer
Layer allows you to render children outside the DOM hierarchy of the parent. This is useful for places you might otherwise need to use z-index to overlay the screen, simplifying the stacking context complexity in the app. See z-Index in foundational components and ZIndex in Layer to learn more.