Skip to main content

Backdrop

Full-screen layer behind an overlay, transparent by default, that catches the click meant to close it. It dims the page only when you ask, or on a phone.

BackdropBackdrop

Use this when / not when​

  • Use behind an overlay of your own — an Aside, a panel, a popover — that has to close when the user clicks away from it.
  • Not behind a ModalDialog or a DropDown: both render one themselves, and a second one is suppressed.
  • Not as a loading veil over a region. It is position: fixed and covers the whole viewport, never a part of it.
  • Not to block interaction: it stops pointer events under itself but nothing else. Focus still moves into the page behind, and there is no Escape handling.

Import​

import { Backdrop } from "@onlyoffice/apps-ui-kit/components/backdrop";

Also exported from the root barrel @onlyoffice/apps-ui-kit.

BackdropProps is not exported — type a wrapper's props yourself, or import the type from its file path.

Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme above it in the tree for the dimming colour, which differs between the light and the dark theme.

Stories​

Default​

The common case: a dimmed layer behind a dialog that closes it on a click (withBackground). Press the button to open it, then click anywhere to close it; change any other prop live in the Controls panel below.

DefaultDefault

Without Background​

For a menu or dropdown that must close on an outside click without darkening the page: the layer stays transparent and still catches the click (withoutBackground).

Without BackgroundWithout Background

Multiple Backdrops​

For a side panel opened over another one: each panel's layer renders even though a backdrop is already on screen, and the second darkens the page further (isAside). Open the first backdrop, then the second from the button above it; a click closes the top layer first.

Multiple BackdropsMultiple Backdrops

For a modal dialog on a touch screen: the layer keeps catching taps that close the dialog, but no longer blocks touch scrolling (isModalDialog).

Modal Dialog BackdropModal Dialog Backdrop

With Custom Z Index​

When the covered content has to sit above other high layers of the page, raise the backdrop's stacking order and place the content one step above it — here 500 and 501 instead of the default 203 (zIndex).

With Custom Z IndexWith Custom Z Index

Css Customization​

The dimming colour overridden on a wrapper -- the variables are listed under CSS variables on this page. The stacking order is the zIndex prop.

Css CustomizationCss Customization

Minimal example​

zIndex has to be below the thing it sits behind — the default is 203.

import { useState } from "react";
import { Backdrop } from "@onlyoffice/apps-ui-kit/components/backdrop";
import { Button } from "@onlyoffice/apps-ui-kit/components/button";

export function Popover() {
const [open, setOpen] = useState(false);

return (
<>
<Button label="Open" onClick={() => setOpen(true)} />
{open ? (
<>
<Backdrop visible zIndex={199} onClick={() => setOpen(false)} />
<div
style={{
position: "fixed",
inset: "40% auto auto 40%",
zIndex: 200,
}}
>
<Button label="Close" onClick={() => setOpen(false)} />
</div>
</>
) : null}
</>
);
}

Props​

PropertyTypeDescription
visiblebooleanWhether the layer is rendered at all. It is not a CSS switch: a backdrop that is not visible renders nothing. Default: false.
className?string | string[]Custom CSS class name(s) to apply to the backdrop Can be a single string or an array of strings
id?stringHTML id attribute for the backdrop element
isAside?booleanMarks the backdrop as belonging to a side panel: it then dims the page, and it is allowed to render even when two backdrops are already on screen. Default: false.
isModalDialog?booleanLets touch scrolling through the backdrop go on as usual. Without it a touch move over the layer has its default action prevented. Default: false.
onClick?(e: React.MouseEvent) => voidCalled on a click, and on a touch move or touch end, which pass a touch event cast to a mouse event.
shouldShowBackdrop?booleanRenders the layer even when another backdrop is already on screen, which would otherwise suppress it. Default: false.
style?React.CSSPropertiesCustom inline styles to apply to the backdrop. zIndex is merged in first.
withBackground?booleanDims the page. Without it the layer is transparent and only catches clicks — except on a viewport of 600px or less, where it dims anyway. Default: false.
withoutBackground?booleanForces the backdrop to render without a background Takes precedence over withBackground. Default: false.
zIndex?numberStacking order of the layer. The component it covers needs a higher one. Default: 203.

Recipes​

Open and close, controlled​

visible is the whole of it: false renders nothing, so the layer needs no conditional rendering of its own.

import { useState } from "react";
import { Aside } from "@onlyoffice/apps-ui-kit/components/aside";
import { Backdrop } from "@onlyoffice/apps-ui-kit/components/backdrop";
import { Button } from "@onlyoffice/apps-ui-kit/components/button";

export function MembersPanel() {
const [open, setOpen] = useState(false);
const close = () => setOpen(false);

return (
<>
<Button label="Members" onClick={() => setOpen(true)} />
<Backdrop visible={open} isAside zIndex={399} onClick={close} />
{open ? (
<Aside visible header="Members" onClose={close}>
<p style={{ padding: 16 }}>Nobody has joined this room yet.</p>
</Aside>
) : null}
</>
);
}

Behaviour the types don't state​

  • A second backdrop renders nothing. On every change the component counts the elements carrying the backdrop-active class already in the document and bails out if there is one — unless shouldShowBackdrop is set, which ignores the count, or isAside, which renders the layer whatever the count. This is how a dialog opened from a panel avoids stacking two veils, and it is also why your own backdrop may silently fail to appear behind someone else's overlay.
  • It is transparent unless you ask for the dimming. withBackground turns it on, isAside turns it on, and a viewport of 600px or less turns it on whether you asked or not; withoutBackground wins over all three.
  • The viewport is measured during render and never again. There is no resize listener, so a window resized across 600px keeps whatever the backdrop decided when it opened.
  • Touch moves over it are cancelled unless isModalDialog is set, which is what stops the page behind a panel scrolling under the user's finger. onClick receives those touch moves, and every touch end, too, cast to a mouse event — so a touch that merely passes over the layer closes what it covers.
  • It is position: fixed at 100vw × 100vh, so it ignores the scroll position and any transformed ancestor.
  • className accepts an array as well as a string, unlike the rest of the kit.

CSS variables​

VariableDefaultEffect
--backdrop-bgrgba(6, 22, 38, 0.2); rgba(27, 27, 27, 0.6) in darkColour of the dimming, shown only when the layer dims: withBackground, isAside or a narrow screen

The stacking order is the zIndex prop, not a variable. The stylesheet does read --backdrop-z-index, but the component always writes zIndex (203 by default) inline, which wins, so setting the variable has no effect; a zIndex in style overrides the prop.

Accessibility​

  • The layer is an empty <div> with no role and no name, which is right: it is not an object the user interacts with deliberately.
  • It does not trap focus, does not mark the page behind as inert and does not handle Escape. An overlay that must be modal has to do those itself — or be a ModalDialog.
  • Clicking it is a mouse-only way out, so give the overlay a close button as well.

Test ids​

Elementdata-testid
The layerbackdrop

It cannot be overridden by a prop.

  • ModalDialog — renders its own, so you do not add one.
  • Aside — renders none, so you do.
  • DropDown — renders one unless withBackdrop is false.