Layer

Description

The Layer component is a technical utility used to render content outside the main DOM tree, appending it at the end of the document. This approach bypasses layout restrictions such as CSS "overflow: hidden" and ensures that layered content (such as contextual menus or tooltips) always appears above the rest of the UI without relying on z-index manipulation.

Usage

Instantiate a Layer using the static helper method from Tesserae.UI. Use the Content method to set the inner content that should be rendered within the Layer. The visibility of the Layer can be controlled via the IsVisible property, and you may optionally provide a hosting container using the Host property to control where the Layer's content gets projected.

Blocking the page behind a layer

A layer that blocks the page overrides LocksPageScroll (a protected virtual bool, false by default) and the base class stops the page behind it scrolling for as long as it is shown:

protected override bool LocksPageScroll => !IsNonBlocking;   // what Modal and Panel do

false is the default because most layers are not blocking: a dropdown, a context menu, a toast or a picker's suggestion list must leave the page scrollable. Call UpdatePageScrollLock() when a property of yours changes the answer while the layer is already open.

Never write document.body.style.overflow from a component. Layers owns the lock: it remembers whatever the application had on the body and restores exactly that once the last locking layer has gone, and it reads which elements are holding the page off the DOM by marker class, so there is no counter to get out of step. Several overlays can therefore be open at once, closing in any order, and an app shell that declares "the body never scrolls" keeps that declaration.

API reference

class

Layer

public sealed class Layer : Layer<Layer>

A Layer is a technical component that does not have specific Design guidance. Layers are used to render content outside of a DOM tree, at the end of the document. This allows content to escape traditional boundaries caused by "overflow: hidden" css rules and keeps it on the top without using z-index rules. This is useful for example in ContextualMenu and Tooltip scenarios, where the content should always overlay everything else. This non-generic Layer class is appropriate when the core Layer functionality is all that you require and none of its behaviours need to be extended - should you need a Layer base class that CAN be derived from (such as the ContextMenu, for example), use the generic Layer class. The reason for the two classes is to avoid confusion as this can NOT be derived from and the generic version MUST be derived from. The generic version exists to maintain the type of component in chained calls made on the ComponentBase class that they both are derived from (when the OnClick method is called on a ContextMenu then you expect a ContextMenu to be returned and not simply a Layer instance).

Namespace
Tesserae
Inheritance
Layer<Layer> → Layer
class

Layer<T>

public abstract class Layer<T> : ComponentBase<T, HTMLDivElement> where T : Layer<T>

This generic version of Layer should only be used to create derived classes from (such as the ContextMenu, for example). If you require no additional functionality on top of a standard layer then use the non-generic Layer class. The reason for the two classes is to avoid confusion as this can NOT be derived from and the generic version MUST be derived from. The generic version exists to maintain the type of component in chained calls made on the ComponentBase class that they both are derived from (when the OnClick method is called on a ContextMenu then you expect a ContextMenu to be returned and not simply a Layer instance).

Namespace
Tesserae
Inheritance
ComponentBase<T, HTMLDivElement> → Layer<T>

Constructors

NameDescription
LayerInitializes a new instance of the Layer{T} class.
Constructor
Layer
protected Layer()

Initializes a new instance of the Layer{T} class.

Properties

NameDescription
HostGets or sets the host that will contain this layer. If null, the layer will be hosted in the document body.
ContentGets or sets the content to be displayed in the layer.
IsTopmostGets a value indicating whether this layer is currently the topmost layer.
IsVisibleGets or sets a value indicating whether the layer is visible.
IsTransparentGets or sets a value indicating whether the layer background should be transparent.
AnimateOnShowGets or sets a value indicating whether the layer should animate when it is shown.
LocksPageScrollWhether the page behind this layer must not scroll while it is shown. false by default, because most layers are not blocking: a dropdown, a context menu, a toast or a picker's suggestions must leave the page scrollable. A blocking overlay - Modal, Panel - overrides it, conditionally where it can be made non-blocking while open. The lock itself is Layers' to own: it remembers what the application had on the body and puts that back once the last locking layer has gone, so an app shell that declares "the body never scrolls" keeps it instead of having it cleared.
Property
Layer.Host
public LayerHost Host { get ; set ; }

Gets or sets the host that will contain this layer. If null, the layer will be hosted in the document body.

Property
Layer.Content
public virtual IComponent Content { get ; set ; }

Gets or sets the content to be displayed in the layer.

Property
Layer.IsTopmost
public bool IsTopmost

Gets a value indicating whether this layer is currently the topmost layer.

Property
Layer.IsVisible
public bool IsVisible { get ; set ; }

Gets or sets a value indicating whether the layer is visible.

Property
Layer.IsTransparent
public bool IsTransparent { get ; set ; }

Gets or sets a value indicating whether the layer background should be transparent.

Property
Layer.AnimateOnShow
public bool AnimateOnShow { get; set; }

Gets or sets a value indicating whether the layer should animate when it is shown.

Property
Layer.LocksPageScroll
protected virtual bool LocksPageScroll

Whether the page behind this layer must not scroll while it is shown. false by default, because most layers are not blocking: a dropdown, a context menu, a toast or a picker's suggestions must leave the page scrollable. A blocking overlay - Modal, Panel - overrides it, conditionally where it can be made non-blocking while open. The lock itself is Layers' to own: it remembers what the application had on the body and puts that back once the last locking layer has gone, so an app shell that declares "the body never scrolls" keeps it instead of having it cleared.

Methods

NameDescription
UpdatePageScrollLockRe-applies LocksPageScroll for a layer that is already shown - for a property that changes whether it blocks while it is open. A no-op while hidden.
RenderRenders the component.
ShowShows the layer.
HideHides the layer.
OnBackgroundClickSets the action to be executed when the layer background is clicked.
BuildRenderedContentBuilds the HTML element that represents the content of the layer.
Method
Layer.UpdatePageScrollLock
protected void UpdatePageScrollLock()

Re-applies LocksPageScroll for a layer that is already shown - for a property that changes whether it blocks while it is open. A no-op while hidden.

Method
Layer.Render
public override HTMLElement Render()

Renders the component.

Returns

The rendered HTML element.

Method
Layer.Show
public virtual T Show()

Shows the layer.

Returns

The component itself, for chaining.

Method
Layer.Hide
public virtual void Hide(Action onHidden = null)

Hides the layer.

Parameters

onHidden
An optional action to execute when the layer has been hidden.
Method
Layer.OnBackgroundClick
public void OnBackgroundClick(Action<MouseEvent> action)

Sets the action to be executed when the layer background is clicked.

Parameters

action
The action to execute.
Method
Layer.BuildRenderedContent
protected virtual HTMLElement BuildRenderedContent()

Builds the HTML element that represents the content of the layer.

Returns

The rendered content element.

Samples

Hosting a Layer in a LayerHost

Set a Layer's Host to a LayerHost to confine the overlay to that element's box instead of the whole document. The LayerHost stays in the normal page flow, so it reserves space like any other component.

See also

© 2026 Curiosity. All rights reserved.