Skip to content

CdsOverlay

An overlay shows content on top of the page: it dims the page with a scrim, computes the position relative to an activator and manages the stacking order of the open layers. It is the base mechanism behind CdsModal, CdsMenu and CdsTooltip — take it when you need a popup of your own that is not among the ready-made ones.

Storybook GitLab Figma
Test coverage: 84% — partial coverage
API in specs
57 / 57 props, events, slots and exposed members with a test
Test cases
96 unit · 10 browser · 3 planned
Known bugs
4 pinned by an it.fails test
Code coverage
83.5% lines · 80% branches measured in v4.0.0-alpha.13
A11y (axe)
4 recommendations in 13 stories measured in v4.0.0-alpha.11

For common tasks there are ready-made components built on the overlay: a dialog — CdsModal, a list of actions next to an activator — CdsMenu, a hint on hover — CdsTooltip, notifications — CdsToast. CdsOverlay is for when none of them fits.

Anatomy ​

An overlay consists of two parts: the scrim, which dims the page and intercepts clicks, and the content — the contents of the default slot. The content is moved to the end of body, so the overlay does not depend on the overflow and z-index of the parent blocks.

Variations ​

Opening and closing ​

v-model controls the visibility. An open overlay closes on a click outside the content and on the Esc key.

The persistent prop turns both ways off: the overlay closes only through v-model — for example, by a button inside the content. On a click outside, the content answers with a light "shake"; remove it with the no-click-animation prop if you do not need the animation.

Activator ​

The activator slot saves you from a manual v-model: pass the slot props (v-bind="props") to an element — and a click on it will open the overlay. The open-on-hover and open-on-focus props switch the opening to hover or focus, and activator="parent" makes the parent element the activator.

Scrim ​

The scrim is on by default: it dims the page and shows that the interface under the overlay is unavailable. The :scrim="false" prop removes it — a click outside still closes the overlay. The opacity prop tunes the dimming density, and a string in scrim sets a custom color for the scrim.

Limiting to a container ​

The contained prop locks the overlay inside the parent block: the scrim and the content do not leave its bounds, and the rest of the page keeps working. The parent must have position: relative. To center the content inside the block rather than relative to the screen, pass the container to target and turn on location-strategy="connected".

Positioning ​

By default the content is centered relative to the screen — this is what the static strategy and the location prop are responsible for. The location-strategy="connected" strategy attaches the content to the activator: location sets the side, offset — the distance to it. If there is not enough room near the screen edge, the content flips to the opposite side — that is how CdsMenu works.

Behavior on scroll ​

The scroll-strategy prop decides what happens to the page and the overlay on scroll: block (the default) blocks the page scroll, close closes the overlay, reposition recomputes the position of the content following the target, none does nothing.

Animation ​

The transition prop changes the animation of showing and hiding the content.

Slots ​

SlotDescription
activatorThe element that opens the overlay. Bind the slot props (props) to it
defaultThe overlay content. Receives isActive — use it to close the overlay from inside

Guidelines ​

Scenarios ​

Loading on top of a block ​

While the data of a block is being updated, a contained overlay with CdsProgressCircle covers only that block: the user sees that loading is in progress and keeps working with the rest of the page. persistent prevents closing the overlay by an accidental click, and scroll-strategy="none" does not block the page scroll.

Image preview ​

A click on a thumbnail opens the image at full size on top of the dimmed page. A dense scrim (opacity="0.85") removes the visual noise, and the preview closes the usual way — by a click outside or the Esc key, no separate button needed.

Onboarding hint ​

A hint about a new feature is a panel attached to an element by the connected strategy; in a real interface you open it programmatically, for example by a first-visit flag, here — by a click on a button. Without a scrim (:scrim="false") the hint does not get in the way of working with the page, persistent protects it from an accidental close — it disappears only by the "Понятно" button, and scroll-strategy="reposition" keeps it next to the activator on scroll.

API ​

Props

NameTypeDefaultDescription
absoluteboolean | undefined—Positions the element absolutely instead of fixed. This is useful for overlays that must stay inside a certain area, for example inside a container with position: relative.
activator(string & {}) | Element | "parent" | ComponentPublicInstance | undefined—The element that activates the component
activatorPropsRecord<string, any> | undefined{}Props for the activator element
attachstring | boolean | Element | undefined—Sets the DOM element the overlay content is moved to. It accepts a direct element reference, a querySelector string, or true to disable moving. By default the body element is used. Changing this prop is usually not recommended except for edge cases: the default positioning algorithm handles most scenarios better than it can without moving, and unexpected behavior may appear if the menu ends up being a child of its activator.
captureFocusboolean | undefined—Returns the focus back into the content if it has left it — for example on Tab from the end of the page. A mouse click does not steal the focus.
closeDelaystring | number | undefined—Delay in milliseconds before the component closes. Works only together with open-on-hover.
closeOnBackboolean | undefinedtrueCloses the overlay content when the browser Back button is pressed or $router.back() is called, cancelling the original navigation. persistent overlays cancel the navigation and animate as if they were clicked outside instead of closing.
closeOnContentClickboolean | undefined—Hide the component on a click on the content
containedboolean | undefined—Limits the size of the component and of its grid to the offset parent. Implies the absolute and attach props. (Note: the parent element must have position: relative.)
contentClassany—Applies a custom class to the content element. This is handy because the content is moved to the beginning of the cds-app component (unless attach is set) and cannot be selected with classes passed to the component directly.
contentPropsany—Applies custom props to the moved content
disabledboolean | null | undefinednullDisabled state
eagerboolean | undefined—Renders the content of the component right away. Useful when you have content that is not in the DOM but has to be indexed for SEO.
heightstring | number | undefined—Component height
locationAnchor | undefined'bottom'Sets the anchor point used to position the component, aligning it horizontally, vertically or in both directions
locationStrategy"static" | "connected" | LocationStrategyFunction | undefined'static'Sets the way the overlay content is positioned. By default static is used, which centers the content in its container. Use connected to attach the content to the activator element.
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
modelValueboolean | undefined—The v-model value of the component. If the component supports the multiple prop, an empty array is used by default.
noClickAnimationboolean | undefined—Disables the bounce effect on a click outside the content element when persistent is set.
offsetstring | number | number[] | undefined—Increases the distance to the target. If two numbers are passed, the second one shifts the anchor sideways, away from the target.
opacitystring | number | undefined—Opacity of the scrim element. Applies only when scrim=true.
openDelaystring | number | undefined—Delay in milliseconds before the component opens. Works only together with open-on-hover.
openOnClickboolean | undefined—Show the component on a click on the activator
openOnFocusboolean | undefined—Show the component when the activator gets focus
openOnHoverboolean | undefined—Show the component on hover over the activator
originAnchor | "auto" | "overlap" | undefined'auto'Sets the anchor point of the overlay content that is aligned with the location anchor of the target. With "auto" the opposite side of the location point is used. With "overlap" the same anchor point is used, so the overlay overlaps the target. It also sets the CSS transform-origin property for the enter/leave transitions.
persistentboolean | undefined—A click outside the element or the Esc key does not close it.
retainFocusboolean | undefined—Traps Tab navigation inside the content: from the last focusable element the focus moves to the first one and back.
scrimstring | boolean | undefinedtrueBackdrop shown while the overlay is active. Accepts true/false to toggle the backdrop and a string to set its color.
scrollStrategy"none" | "close" | "block" | "reposition" | ScrollStrategyFunction | undefined'block'Strategy applied when the component is active and the user scrolls the page.
stickToTargetboolean | undefined—Lets the overlay content go off screen while scrolling.
target(string & {}) | Element | "parent" | ComponentPublicInstance | "cursor" | [x: number, y: number] | undefined—When locationStrategy is set to "connected", specify the element or the array of x, y coordinates the overlay is positioned against. By default the activator element is used.
themestring | undefined—Component theme
transitionstring | boolean | (TransitionProps & { component?: Component | undefined; }) | null | undefined'fade-transition'Transition animation
viewportMarginstring | number | undefined12Sets a custom viewport margin for the overlay content
widthstring | number | undefined—Component width
zIndexstring | number | undefined2000The z-index value of the component.

Events

NameTypeDescription
afterEnter[]Fires after the opening animation has finished.
afterLeave[]Fires after the closing animation has finished.
click:outside[value: MouseEvent]Fires on a click outside the overlay.
keydown[value: KeyboardEvent]Fires on a key press while the overlay is open.
update:modelValue[value: boolean]Fires when the overlay opens or closes. Passes the new visibility state.

Slots

NameTypeDescription
activator{ isActive: boolean; props: Record<string, any>; targetRef: TemplateRef; }Slot for the element that acts as the activator of the overlay.
default{ isActive: Ref<boolean, boolean>; }Slot for the overlay content.

Exposed

NameTypeDescription
activatorElHTMLElement | undefinedThe DOM element of the activator.
activatorRefTemplateRefTemplate ref for assigning the activator manually.
animateClick() => voidRuns the bounce animation of the content — the same as on a click outside a persistent overlay.
contentElHTMLElement | undefinedThe DOM element of the overlay content.
globalTopbooleanWhether the overlay is the top one in the global stack of open overlays.
rootElHTMLElement | undefinedThe root DOM element of the overlay.
scrimElHTMLElement | undefinedThe DOM element of the scrim that dims the page.
targetElHTMLElement | undefinedThe DOM element of the positioning target.
targetRefTemplateRefTemplate ref for assigning the positioning target manually.
updateLocation((e: Event) => void) | undefinedRecalculates the position of the content relative to the target.