Overlay Overview

The overlay component creates a full-page overlay layer that sits on top of the main content. It's commonly used as a backdrop for modals, dialogs, and other overlaid content to focus user attention and prevent interaction with underlying elements.

When to Use

Use overlay when:

  • Creating modal dialogs that require user focus
  • Building custom popups or lightboxes
  • Implementing loading states that block interaction
  • Creating photo galleries or media viewers
  • Building custom dropdown menus or megamenus

Don't use overlay for:

  • Simple tooltips (use the tooltip component)
  • Inline notifications (use callout or snackbar)
  • Page-level loading indicators (consider a dedicated loading component)
Examples Basic Usage

The overlay is hidden by default. Set the open property to true to display it. Click the overlay to close it in this example.

<>
<dap-ds-button onClick={
  () => {
    const overlay = document.querySelector('#overlay-basic');
    overlay.open = !overlay.open;
  }
}>Toggle Overlay</dap-ds-button>
<dap-ds-overlay id="overlay-basic" onClick={
  () => {
    const overlay = document.querySelector('#overlay-basic');
    overlay.open = false;
  }
}>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white',
    textAlign: 'center'
  }}>
    <div>
      <h2>Overlay Content</h2>
      <p>Click anywhere to close</p>
    </div>
  </div>
</dap-ds-overlay>
</>
Custom Background Colors

Use CSS custom properties to customize the overlay's appearance. The --dds-overlay-background property controls the background color and opacity.

<>
<dap-ds-stack direction="row">
  <dap-ds-button onClick={() => document.querySelector('#overlay-dark').open = true}>
    Dark Overlay
  </dap-ds-button>
  <dap-ds-button onClick={() => document.querySelector('#overlay-blue').open = true}>
    Blue Overlay
  </dap-ds-button>
  <dap-ds-button onClick={() => document.querySelector('#overlay-light').open = true}>
    Light Overlay
  </dap-ds-button>
</dap-ds-stack>

<dap-ds-overlay
  id="overlay-dark"
  style={{'--dds-overlay-background': 'rgba(0, 0, 0, 0.8)'}}
  onClick={() => document.querySelector('#overlay-dark').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white'
  }}>
    <h3>Dark Overlay (rgba(0, 0, 0, 0.8))</h3>
  </div>
</dap-ds-overlay>

<dap-ds-overlay
  id="overlay-blue"
  style={{'--dds-overlay-background': 'rgba(0, 100, 200, 0.5)'}}
  onClick={() => document.querySelector('#overlay-blue').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white'
  }}>
    <h3>Blue Overlay (rgba(0, 100, 200, 0.5))</h3>
  </div>
</dap-ds-overlay>

<dap-ds-overlay
  id="overlay-light"
  style={{'--dds-overlay-background': 'rgba(255, 255, 255, 0.9)'}}
  onClick={() => document.querySelector('#overlay-light').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'black'
  }}>
    <h3>Light Overlay (rgba(255, 255, 255, 0.9))</h3>
  </div>
</dap-ds-overlay>
</>
Custom Transitions

Control the overlay's animation with transition duration and timing function properties.

<>
<dap-ds-stack direction="row">
  <dap-ds-button onClick={() => document.querySelector('#overlay-slow').open = true}>
    Slow Transition (2s)
  </dap-ds-button>
  <dap-ds-button onClick={() => document.querySelector('#overlay-bounce').open = true}>
    Bounce Effect
  </dap-ds-button>
</dap-ds-stack>

<dap-ds-overlay
  id="overlay-slow"
  style={{
    '--dds-overlay-transition-duration': '2s',
    '--dds-overlay-background': 'rgba(100, 50, 150, 0.6)'
  }}
  onClick={() => document.querySelector('#overlay-slow').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white'
  }}>
    <div>
      <h3>Slow Transition</h3>
      <p>Watch the 2-second fade animation</p>
    </div>
  </div>
</dap-ds-overlay>

<dap-ds-overlay
  id="overlay-bounce"
  style={{
    '--dds-overlay-transition-duration': '0.8s',
    '--dds-overlay-transition-timing': 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
    '--dds-overlay-background': 'rgba(200, 100, 0, 0.6)'
  }}
  onClick={() => document.querySelector('#overlay-bounce').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white'
  }}>
    <div>
      <h3>Bounce Effect</h3>
      <p>Custom cubic-bezier timing</p>
    </div>
  </div>
</dap-ds-overlay>
</>
Layered Overlays

Multiple overlays can be stacked using different z-index values. This is useful for nested modals or complex UI patterns.

<>
<dap-ds-stack direction="row">
  <dap-ds-button onClick={() => document.querySelector('#overlay-layer1').open = true}>
    Layer 1 (z-index: 1)
  </dap-ds-button>
  <dap-ds-button onClick={() => document.querySelector('#overlay-layer2').open = true}>
    Layer 2 (z-index: 10)
  </dap-ds-button>
  <dap-ds-button onClick={() => document.querySelector('#overlay-layer3').open = true}>
    Layer 3 (z-index: 100)
  </dap-ds-button>
</dap-ds-stack>

<dap-ds-overlay
  id="overlay-layer1"
  style={{
    '--dds-overlay-z-index': '1',
    '--dds-overlay-background': 'rgba(255, 0, 0, 0.3)'
  }}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%'
  }}>
    <div>
      <h3>Layer 1 (Red)</h3>
      <dap-ds-button onClick={() => document.querySelector('#overlay-layer1').open = false}>
        Close
      </dap-ds-button>
    </div>
  </div>
</dap-ds-overlay>

<dap-ds-overlay
  id="overlay-layer2"
  style={{
    '--dds-overlay-z-index': '10',
    '--dds-overlay-background': 'rgba(0, 255, 0, 0.3)'
  }}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%'
  }}>
    <div>
      <h3>Layer 2 (Green)</h3>
      <dap-ds-button onClick={() => document.querySelector('#overlay-layer2').open = false}>
        Close
      </dap-ds-button>
    </div>
  </div>
</dap-ds-overlay>

<dap-ds-overlay
  id="overlay-layer3"
  style={{
    '--dds-overlay-z-index': '100',
    '--dds-overlay-background': 'rgba(0, 0, 255, 0.3)'
  }}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%'
  }}>
    <div>
      <h3>Layer 3 (Blue)</h3>
      <dap-ds-button onClick={() => document.querySelector('#overlay-layer3').open = false}>
        Close
      </dap-ds-button>
    </div>
  </div>
</dap-ds-overlay>
</>
Modal Dialog with Overlay

Combining overlay with other components to create a centered modal dialog.

<>
<dap-ds-button onClick={() => document.querySelector('#overlay-modal').open = true}>
  Open Modal Dialog
</dap-ds-button>
<dap-ds-overlay id="overlay-modal">
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    padding: '2rem'
  }}>
    <dap-ds-card style={{maxWidth: '500px', width: '100%'}}>
      <dap-ds-stack>
        <dap-ds-typography variant="h2">Confirm Action</dap-ds-typography>
        <dap-ds-typography variant="body">
          Are you sure you want to proceed with this action? This operation cannot be undone.
        </dap-ds-typography>
        <dap-ds-stack direction="row" justify="end">
          <dap-ds-button
            variant="outline"
            onClick={() => document.querySelector('#overlay-modal').open = false}
          >
            Cancel
          </dap-ds-button>
          <dap-ds-button
            danger
            onClick={() => {
              alert('Action confirmed!');
              document.querySelector('#overlay-modal').open = false;
            }}
          >
            Confirm
          </dap-ds-button>
        </dap-ds-stack>
      </dap-ds-stack>
    </dap-ds-card>
  </div>
</dap-ds-overlay>
</>
Image Lightbox

Using overlay to create a simple image lightbox viewer.

<>
<dap-ds-button onClick={() => document.querySelector('#overlay-lightbox').open = true}>
  View Image
</dap-ds-button>
<dap-ds-overlay
  id="overlay-lightbox"
  style={{'--dds-overlay-background': 'rgba(0, 0, 0, 0.9)'}}
  onClick={() => document.querySelector('#overlay-lightbox').open = false}
>
  <div style={{
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    padding: '2rem'
  }}>
    <img
      src="https://via.placeholder.com/800x600/667eea/ffffff?text=Sample+Image"
      alt="Sample"
      style={{
        maxWidth: '100%',
        maxHeight: '80vh',
        borderRadius: 'var(--dds-radius-large)',
        boxShadow: '0 20px 40px rgba(0,0,0,0.3)'
      }}
    />
    <dap-ds-typography
      variant="body"
      style={{color: 'white', marginTop: '1rem'}}
    >
      Click anywhere to close
    </dap-ds-typography>
  </div>
</dap-ds-overlay>
</>
Loading State

Creating a full-page loading indicator with overlay.

<>
<dap-ds-button onClick={() => {
  const overlay = document.querySelector('#overlay-loading');
  overlay.open = true;
  setTimeout(() => {
    overlay.open = false;
  }, 3000);
}}>
  Simulate Loading (3s)
</dap-ds-button>
<dap-ds-overlay
  id="overlay-loading"
  style={{'--dds-overlay-background': 'rgba(255, 255, 255, 0.95)'}}
>
  <div style={{
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    gap: '1rem'
  }}>
    <dap-ds-spinner size="lg"></dap-ds-spinner>
    <dap-ds-typography variant="h3">Loading...</dap-ds-typography>
    <dap-ds-typography variant="body" style={{color: 'var(--dds-text-neutral-subtle)'}}>
      Please wait while we process your request
    </dap-ds-typography>
  </div>
</dap-ds-overlay>
</>
Custom Styling

The overlay component provides extensive customization options through CSS custom properties and parts.

CSS Custom Properties
<>
<dap-ds-button onClick={() => document.querySelector('#overlay-custom').open = true}>
  Custom Styled Overlay
</dap-ds-button>
<dap-ds-overlay
  id="overlay-custom"
  style={{
    '--dds-overlay-background': 'linear-gradient(135deg, rgba(102, 126, 234, 0.8) 0%, rgba(118, 75, 162, 0.8) 100%)',
    '--dds-overlay-transition-duration': '0.5s',
    '--dds-overlay-transition-timing': 'cubic-bezier(0.4, 0, 0.2, 1)',
    '--dds-overlay-z-index': '999'
  }}
  onClick={() => document.querySelector('#overlay-custom').open = false}
>
  <div style={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    color: 'white',
    textAlign: 'center'
  }}>
    <div>
      <h2>Gradient Overlay</h2>
      <p>Custom background with smooth transitions</p>
    </div>
  </div>
</dap-ds-overlay>
</>
Advanced Styling with CSS Parts

Use the CSS ::part() selector to apply advanced styling to the overlay element. Try editing the CSS below:

Blur EffectRadial GradientStriped PatternGlass Morphism
☀️ Light🌙 Dark
CopyFormatReset
CSS Editor
Live Preview
Background ContentThis content will be overlaid

Overlay Content

Accessibility Requirements
  • Focus management: When overlay opens, focus should move to overlay content
  • Keyboard support: ESC key should close the overlay (implement in parent component)
  • ARIA attributes: The overlay automatically sets aria-hidden based on open state
  • Screen reader announcements: Announce when overlay opens/closes
Best Practices
  • Ensure sufficient color contrast for overlay content
  • Provide a clear way to close the overlay
  • Consider users with motion sensitivity when using transitions
  • Test with keyboard-only navigation
Importing
import { DapDSOverlay } from 'dap-design-system'
Importing React
import { DapDSOverlayReact } from 'dap-design-system/react'
Tree-Shakeable Imports

For optimal bundle sizes, use the tree-shakeable import syntax:

import { DapDSOverlay } from 'dap-design-system/components'
Attributes
PropertyTypeDefaultDescription
openbooleanfalseThe open state of the overlay.
Slots
NameDescription
(default)The content of the overlay.
Events
Event NameDescriptionType
dds-before-openFires before the overlay opens.CustomEvent
dds-openedFires after the overlay opens.CustomEvent
dds-before-closeFires before the overlay closes.CustomEvent
dds-closedFires after the overlay closes.CustomEvent
CSS Parts
Part NameDescription
overlayThe overlay element
How to Use CSS Parts

You can style CSS parts using the ::part() pseudo-element selector:

/* Target a specific part */
.my-custom-dap-ds-overlay::part(overlay) {
  /* Your custom styles */
}

Example usage:

<dap-ds-overlay class="my-custom-dap-ds-overlay">
  Overlay
</dap-ds-overlay>
.my-custom-dap-ds-overlay::part(overlay) {
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

CSS parts allow you to style internal elements of the component while maintaining encapsulation. Learn more in our styling guide.

CSS Custom Properties
Property NameDescription
--dds-overlay-z-indexControls the z-index of the overlay (default: 1)
--dds-overlay-background-colorControls the background color of the overlay (default: var(--dds-black-10))
--dds-overlay-opacity-closedControls the opacity when overlay is closed (default: 0)
--dds-overlay-opacity-openControls the opacity when overlay is open (default: 1)
--dds-overlay-transition-durationControls the transition duration (default: var(--dds-transition-fast))
--dds-overlay-transition-timingControls the transition timing function (default: var(--dds-easing-ease-in-out))
How to Use CSS Custom Properties

CSS custom properties (CSS variables) can be set directly on the component or in your stylesheet:

Method 1: Inline styles (Quick customization)

<dap-ds-overlay
  style="--dds-overlay-z-index: value; --dds-overlay-background-color: value;">
  Overlay
</dap-ds-overlay>

Method 2: CSS classes (Reusable styles)

.my-custom-dap-ds-overlay {
  --dds-overlay-z-index: value;
  --dds-overlay-background-color: value;
  --dds-overlay-opacity-closed: value;
}
<dap-ds-overlay class="my-custom-dap-ds-overlay">
  Overlay
</dap-ds-overlay>

Method 3: Global theme customization

/* Apply to all instances */
dap-ds-overlay {
  --dds-overlay-z-index: value;
  --dds-overlay-background-color: value;
}

CSS custom properties inherit through the Shadow DOM, making them perfect for theming. Changes apply immediately without rebuilding.