Skip to content

Surfaces

Callout

Bit.BlazorUIPopoverPopup

Callout is an anchored surface for any content - a tip, a form, a filter panel, a menu - placed next to an anchor of its own, any element on the page, or a point on the screen. It picks the side with room, follows its anchor while open, points at it with an optional arrow, opens on a click or on hover, closes on an outside click or Escape, and can trap the keyboard, dim the page, nest, and become a swipeable panel on small screens.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

The Anchor positions and toggles the callout; put a focusable trigger (a button) in it. Content is what it holds. NoOverlay leaves the page clickable while it is open, DefaultIsOpen sets the state it starts in, and Disabled turns it off entirely.

This is the callout content.
The page keeps its own clicks.
Open from the start.
Never shown.

External anchor

AnchorId or AnchorEl places the callout against any element on the page. Opening it is then up to you, through Toggle, Open and Close (or IsOpen); closing hands the focus back to what opened it.

October 2026
S
M
T
W
T
F
S
October 2026
S
M
T
W
T
F
S

Binding

IsOpen is two-way bindable, so anything can open the callout and its own content can close it.

Close it from inside.

IsOpen: False

Open on hover

OpenOnHover opens on pointer enter and closes once the pointer has left both the anchor and the callout. HoverOpenDelay ignores a pointer passing by; HoverCloseDelay (150ms) bridges the way into the callout. A click still toggles it, so keyboard and touch users get in too, and Escape closes it wherever the focus is.

Opened on hover.
Opening and closing both waited half a second.

Dismissal

An outside click, Escape, or the page scrolling away closes a callout. AutoClose adds a click inside it (for action lists); NoDismissOnScroll keeps it open, following its anchor, while the page scrolls; NoDismissOnEscape and NoDismissOnOutsideClick take ways out away, leaving the content to close it.

Scroll the page: this one follows its anchor.
Neither Escape nor an outside click closes this one.

Context menu

OpenAt opens the callout at a point (coordinates or a mouse event) instead of an anchor, and moves an open one to the new point. Pair it with NoOverlay so the next right-click reaches the page.

Right-click anywhere in here

Last action: none

Placement

Placement asks for a side and flips to the opposite one when there is no room, unless NoFlip; without a Placement, Direction picks among top and bottom (the default) or All sides. Alignment lines it up across that side, AlignmentOffset slides it inwards, Gap spaces it from the anchor and CollisionPadding from the screen edges.

It follows its anchor changing size (and moving, with NoDismissOnScroll); Reposition covers its own content changing. MaxWindowWidth lets it hang off a narrow screen instead of sliding back onto it.

Side
Alignment

Placed by the options above.

Callout content 1
Callout content 2
Callout content 3
Callout content 4
Callout content 5
Callout content 6
Callout content 7
Callout content 8
Callout content 9
Callout content 10
Callout content 11
Callout content 12
Callout content 13
Callout content 14
Callout content 15
Callout content 16
Callout content 17
Callout content 18
Callout content 19
Callout content 20
Callout content 21
Callout content 22
Callout content 1
Callout content 2
Callout content 3
Callout content 4
Callout content 5
Callout content 6
Callout content 7
Callout content 8
Callout content 9
Callout content 10
Callout content 11
Callout content 12
Callout content 13
Callout content 14
Callout content 15
Callout content 16
Callout content 17
Callout content 18
Callout content 19
Callout content 20
Callout content 21
Callout content 22
Callout content 23
Callout content 24
Callout content 1
Callout content 2

Surface

Background and Border take a color kind; NoShadow drops the elevation.

A secondary background.
A primary border.
No elevation, only a border.

Arrow

ShowArrow points a beak at the anchor from wherever the callout lands, painted like the surface; give it a Gap to stand in. ArrowSize (12px) sizes it and ArrowPadding (16px) keeps it off the corners.

Points at its anchor.
The beak takes the border too.
A bigger beak.
The beak is held 64px away from the corners of the callout.

Sizing

A callout is as wide as its content. Width, MinWidth and MaxWidth take CSS values and wrap the content; MaxHeight caps it and scrolls the rest. SetCalloutWidth makes it at least as wide as the anchor and FixedCalloutWidth no wider; both win over Width.

A callout of a fixed width.
A long line of text that wraps inside the callout instead of stretching it across the page.
Callout content 1
Callout content 2
Callout content 3
Callout content 4
Callout content 5
Callout content 6
Callout content 7
Callout content 8
Callout content 9
Callout content 10
Callout content 11
Callout content 12
Callout content 13
Callout content 14
Callout content 15
Callout content 16
Callout content 17
Callout content 18
Callout content 19
Callout content 20
Callout content 21
Callout content 22
Callout content 23
Callout content 24
Short content.
A long line of text that wraps rather than making the callout wider than its anchor.

Header & footer

Header and Footer stay put while the body between them scrolls, and the header names the callout for screen readers. For more parts, wire up your own elements with ScrollContainerId, HeaderId, FooterId and ScrollOffset.

A header that stays put
Callout content 1
Callout content 2
Callout content 3
Callout content 4
Callout content 5
Callout content 6
Callout content 7
Callout content 8
Callout content 9
Callout content 10
Callout content 11
Callout content 12
Callout content 13
Callout content 14
Callout content 15
Callout content 16
Callout content 17
Callout content 18
Callout content 19
Callout content 20
Callout content 21
Callout content 22
Callout content 23
Callout content 24
Callout content 25
Callout content 26
Callout content 27
Callout content 28
Callout content 29
Callout content 30
Callout content 31
Callout content 32
Callout content 33
Callout content 34
Callout content 35
Callout content 36
Callout content 37
Callout content 38
Callout content 39
Callout content 40
Callout content 41
Callout content 42
Callout content 43
Callout content 44
Callout content 45
Callout content 46
Callout content 47
Callout content 48
Callout content 49
Callout content 50
Callout content 51
Callout content 52
Callout content 53
Callout content 54
Callout content 55
Callout content 56
Callout content 57
Callout content 58
Callout content 59
Callout content 60
Callout content 61
Callout content 62
Callout content 63
Callout content 64
Callout content 65
Callout content 66
Callout content 67
Callout content 68
A header that stays put
Callout content 1
Callout content 2
Callout content 3
Callout content 4
Callout content 5
Callout content 6
Callout content 7
Callout content 8
Callout content 9
Callout content 10
Callout content 11
Callout content 12
Callout content 13
Callout content 14
Callout content 15
Callout content 16
Callout content 17
Callout content 18
Callout content 19
Callout content 20
Callout content 21
Callout content 22
Callout content 23
Callout content 24
Callout content 25
Callout content 26
Callout content 27
Callout content 28
Callout content 29
Callout content 30
Callout content 31
Callout content 32
Callout content 33
Callout content 34
Callout content 35
Callout content 36
Callout content 37
Callout content 38
Callout content 39
Callout content 40
Callout content 41
Callout content 42
Callout content 43
Callout content 44
Callout content 45
Callout content 46
Callout content 47
Callout content 48
Callout content 49
Callout content 50
Callout content 51
Callout content 52
Callout content 53
Callout content 54
Callout content 55
Callout content 56
Callout content 57
Callout content 58
Callout content 59
Callout content 60
Callout content 61
Callout content 62
Callout content 63
Callout content 64
Callout content 65
Callout content 66
Callout content 67
Callout content 68

Responsive

ResponsiveMode turns the callout into a swipeable panel under 600px: Panel slides in from the PanelPlacement edge, while Top and Bottom are sheets. Resize the window to see it.

Filters
Filters
Swipe up to dismiss it.
Swipe down to dismiss it.

Focus & modal

AutoFocus moves the focus in on opening, to a data-autofocus element if there is one. TrapFocus keeps Tab inside and makes the callout a modal dialog for screen readers. Modal dims the page, stops it scrolling and traps the focus too. Role, AriaLabel, AriaLabelledBy and AriaDescribedBy say what the callout is.

Without a trap, Tab on the trigger goes into the callout, and Tab past its end moves on in the page and closes it. Escape closes it from the trigger or from inside, and the focus goes back to the trigger. The trigger reports the callout through aria-controls and aria-expanded, and through aria-haspopup when it is a dialog, a menu, a listbox, a tree or a grid.

Everything is up to date.

Nesting

Opening a callout closes any other open one, except the one its anchor sits in: that one stays open beneath it. Dismissing the outer one closes the inner ones, and Escape peels off the innermost. Dropdowns, date pickers and menus nest the same way.

Filters
The panel behind is still open.
And so is this one.

Lazy rendering

The content is rendered even while the callout is closed, so its state survives a close. LazyRender defers it to the first opening, then keeps it.

October 2026
S
M
T
W
T
F
S

Events

OnToggle gets the new state on every change; OnOpen and OnDismiss split it in two. All three fire however the callout was closed.

This is the callout content.

Toggled: 0, Opened: 0, Dismissed: 0

Cascading parameters

BitParams with a BitCalloutParams sets defaults for every callout inside it. A callout's own parameters win; only the unset ones are filled in.

Arrow, gap, border and side come from the cascade.
The same defaults.
Its own values win.
No defaults here.

Style & Class

Reach for the --bit-Callout-* CSS variables first (listed in the API section). The callout moves to the body while open, so set them on :root, on the callout's Style (copied onto the callout, its arrow and its overlay) or through BitParams. Style and Class land on the root around the anchor; Styles and Classes reach each part. The callout and its arrow carry data-bit-cal-pos (below, above, left or right) and data-bit-cal-align for styles that follow the placement.

CSS variables:

A dark surface, rounder corners and a bigger beak.
Outlined
A border instead of elevation; the padding goes inside the header, the body and the footer.

Style & Class:

This is the callout content.
This is the callout content.

Styles & Classes:

This is the callout content.
This is the callout content.

RTL

Use BitCallout in right-to-left (RTL); the direction travels with the callout and its placement mirrors.

این محتوای کال‌اوت است.
محتوای کال‌اوت 1
محتوای کال‌اوت 2
محتوای کال‌اوت 3
محتوای کال‌اوت 4
محتوای کال‌اوت 5
محتوای کال‌اوت 6
محتوای کال‌اوت 7
محتوای کال‌اوت 8
محتوای کال‌اوت 9
محتوای کال‌اوت 10
محتوای کال‌اوت 11
محتوای کال‌اوت 12

CSS variables

The public custom properties this component reads off its root, for what no parameter covers.

Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property: set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it, or on the Style of one instance to restyle that one alone. Leave a variable unset and the component falls back to the theme token beside it.

BitCallout CSS variables

Name Default value Description
--bit-Callout-background $clr-bg-pri Background of the callout and its arrow. The Background parameter wins over it.
--bit-Callout-color $clr-fg-pri Text color of the callout.
--bit-Callout-border-width 0 ($shp-border-width with Border) Border width of the callout and its arrow; setting it draws a border without the Border parameter.
--bit-Callout-border-color $clr-brd-pri Border color of the callout and its arrow. The Border parameter wins over it.
--bit-Callout-radius $shp-radius-popup Corner radius of the callout.
--bit-Callout-shadow $box-shadow-popup Elevation of the callout. NoShadow wins over it.
--bit-Callout-padding 0 Room inside the callout, or inside each of its header, body and footer when it has them.
--bit-Callout-arrow-size spacing(1.5) Side of the square the arrow is cut out of. ArrowSize wins over it.
--bit-Callout-divider-color $clr-brd-sec The hairline under the header and above the footer.
--bit-Callout-focus-color $clr-pri-focus Focus ring of the callout itself, shown when it takes the focus while holding nothing focusable.
--bit-Callout-overlay-background $clr-bg-overlay The dimmed backdrop of a Modal callout.

API

Every parameter, public member, sub-class and enum this component exposes.

BitCallout parameters

Name Type Default value Description
Alignment BitPlacement? null How the callout is lined up with its anchor along the axis it is not placed on. It defaults to Start. Start, Center and End work on either axis, following the reading direction on the horizontal one; Left and Right only mean something above or below the anchor, and Top and Bottom beside it. A physical value used off its own axis, like the two combined values, falls back to Start.
AlignmentOffset int 0 The distance in pixels the callout is slid along the axis it is aligned on, inwards from the edge of the anchor the Alignment lined it up with. A centered callout has no edge for it to run from.
Anchor RenderFragment? null The content of the anchor element of the callout. The anchor is rendered as a plain container, so the content given here should hold the focusable element the user activates.
AnchorEl Func<ElementReference>? null The setter function for element reference to the external anchor element.
AnchorId string? null The id of the external anchor element.
AriaDescribedBy string? null The id of an element that describes the callout, read by screen readers after its name.
AriaLabelledBy string? null The id of an element that names the callout, such as a heading in its content. It takes the place of the Header and of the AriaLabel as the name.
ArrowPadding int? null The distance in pixels the arrow drawn by ShowArrow is kept away from the corners of the callout, so that the rounding never cuts it. It defaults to 16, and never drops below the size of the arrow itself.
ArrowSize int? null The size in pixels of the arrow drawn by ShowArrow, which is the length of the side of the square the beak is cut out of. It defaults to 12.
AutoClose bool false Closes the callout as soon as a click lands anywhere inside it.
AutoFocus bool false Moves the focus into the callout as soon as it opens, to its first focusable element, or to the callout itself when it holds none.
Background BitColorKind? null The color kind of the background of the callout.
Border BitColorKind? null The color kind of the border of the callout.
ChildContent RenderFragment? null The content of the callout.
Classes BitCalloutClassStyles? null Custom CSS classes for different parts of the callout.
CollisionPadding int 0 The distance in pixels the callout keeps from the edges of the screen when it is placed and when it is slid back onto it.
Content RenderFragment? null Alias for ChildContent.
DefaultIsOpen bool? null The initial opening state of the callout in the uncontrolled mode, which is when the IsOpen parameter is not set.
Direction BitDropDirection? null Determines the allowed directions in which the callout should decide to be opened.
FixedCalloutWidth bool false Holds the callout to the width of its anchor, so that a content wider than the anchor wraps inside it instead of stretching it.
Footer RenderFragment? null The content of a footer that stays at the bottom of the callout while the rest of it scrolls.
FooterId string? null The id of the footer element that renders at the end of the scrolling container of the callout content. It wins over the Footer parameter.
Gap int 0 The distance in pixels between the anchor and the callout, on whichever side the callout ends up being placed.
Header RenderFragment? null The content of a header that stays at the top of the callout while the rest of it scrolls.
HeaderId string? null The id of the header element that renders at the top of the scrolling container of the callout content. It wins over the Header parameter.
HoverCloseDelay int 150 The delay in milliseconds before the callout closes once the pointer leaves the callout and its anchor in the OpenOnHover mode.
HoverOpenDelay int 0 The delay in milliseconds before the callout opens once the pointer enters the anchor in the OpenOnHover mode.
IsOpen bool false Determines the opening state of the callout.
LazyRender bool false Keeps the content of the callout out of the page until the callout is opened for the first time. Once rendered it stays, so whatever state the content holds survives the callout closing.
MaxHeight string? null The maximum height of the callout as a CSS value, beyond which its content scrolls.
MaxWidth string? null The maximum width of the callout as a CSS value, beyond which its content wraps.
MaxWindowWidth int? null The window width in pixels below which the callout is allowed to hang off the end of the screen rather than being slid back onto it.
MinWidth string? null The minimum width of the callout as a CSS value, so that a narrow content does not end up in a cramped callout.
Modal bool false Dims the page behind the callout and holds it still while the callout is open, so that the callout reads as the only thing in play. It implies TrapFocus.
NoDismissOnEscape bool false Keeps the Escape key from dismissing the callout.
NoDismissOnOutsideClick bool false Keeps the callout open when a click lands outside of it, and when the page is scrolled or resized under it.
NoDismissOnScroll bool false Keeps the callout open when the page is scrolled or resized under it: it follows its anchor instead, while an outside click still closes it.
NoFlip bool false Keeps the callout on the Placement it was asked for even when there is not enough room for it there, instead of flipping it to the opposite side.
NoOverlay bool false Leaves the page its own clicks while the callout is open, by not rendering the overlay that otherwise covers it. A Modal callout keeps its overlay.
NoShadow bool false Removes the box-shadow from the callout.
OnDismiss EventCallback The callback that is called when the callout is dismissed.
OnOpen EventCallback The callback that is called when the callout is opened.
OnToggle EventCallback<bool> The callback that is called when the callout opens or closes.
OpenOnHover bool false Opens the callout when the pointer enters the anchor and closes it when the pointer leaves both the anchor and the callout.
PanelPlacement BitPlacement? null The edge of the screen the responsive panel slides in from, for a ResponsiveMode of Panel. It defaults to End. Start and End follow the text direction, Left and Right stay where they are named in both; Center and the two combined values fall back to End.
ResponsiveMode BitResponsiveMode? null Configures the responsive mode of the callout for the small screens.
Role string? null The ARIA role of the callout. It defaults to dialog for a callout that traps the focus (TrapFocus or Modal), and to nothing for the others.
ScrollContainerId string? null The id of the element which needs to be scrollable in the content of the callout.
ScrollOffset int? null The vertical offset of the scroll container to consider in the positioning and height calculation of the callout.
SetCalloutWidth bool false Widens the callout to at least the width of its anchor, so that a callout with little in it still reads as belonging to what it was opened from.
ShowArrow bool false Draws an arrow on the edge of the callout that faces the anchor, pointing at it.
Placement BitPlacement? null The side of the anchor the callout is placed on when there is room for it there. It wins over Direction, falls back to the opposite side, and then to Direction. Top, Bottom, Left and Right are honoured as they are named, Start and End against the reading direction; Center and the two combined values leave the choice to Direction, exactly as leaving this unset does.
Styles BitCalloutClassStyles? null Custom CSS styles for different parts of the callout.
TrapFocus bool false Keeps the keyboard inside the callout while it is open and reports it as a modal dialog to the screen readers. It implies AutoFocus.
Width string? null The width of the callout as a CSS value. SetCalloutWidth and FixedCalloutWidth take precedence over it.

BitCallout public members

Name Type Default value Description
Open Task Opens the callout programmatically, unless it is disabled.
OpenAt Task Opens the callout at a point on the screen rather than against an anchor, which is what a context menu needs. It takes the coordinates (double x, double y) or the MouseEventArgs they came from, and moves an already open callout to the new point.
Close Task Closes the callout programmatically.
Toggle Task Toggles the callout to open/close it.
Reposition Task Lays the open callout out again against what it is placed on, without reopening it or replaying its entry animation. It is for what the callout cannot see on its own: a content that has grown or shrunk, or an anchor moved by something other than a resize of it.

BitComponentBase parameters

Name Type Default value Description
AriaLabel string? null Gets or sets the accessible label for the component, used by assistive technologies.
Class string? null Gets or sets the CSS class name(s) to apply to the rendered element.
Dir BitDir? null Gets or sets the text directionality for the component's content.
Disabled bool false Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction.
ForceAnimation bool false Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested.
HtmlAttributes Dictionary<string, object> new Dictionary<string, object>() Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters.
Id string? null Gets or sets the unique identifier for the component's root element.
Style string? null Gets or sets the CSS style string to apply to the rendered element.
TabIndex string? null Gets or sets the tab order index for the component when navigating with the keyboard.
Visibility BitVisibility BitVisibility.Visible Gets or sets the visibility state (visible, hidden, or collapsed) of the component.

BitComponentBase public members

Name Type Default value Description
UniqueId Guid Guid.NewGuid() Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed.
RootElement ElementReference Gets the reference to the root HTML element associated with this component.

BitCalloutClassStyles properties

Name Type Default value Description
Root string? null Custom CSS classes/styles for the root element of the BitCallout.
AnchorContainer string? null Custom CSS classes/styles for the anchor container element of the BitCallout.
Arrow string? null Custom CSS classes/styles for the arrow (beak) element of the BitCallout.
Opened string? null Custom CSS classes/styles for the opened callout state of the BitCallout.
Content string? null Custom CSS classes/styles for the content of the BitCallout.
Header string? null Custom CSS classes/styles for the header element of the BitCallout, which is rendered when the Header parameter is set.
Body string? null Custom CSS classes/styles for the scrolling body element of the BitCallout, which is rendered when the Header or the Footer parameter is set.
Footer string? null Custom CSS classes/styles for the footer element of the BitCallout, which is rendered when the Footer parameter is set.
Overlay string? null Custom CSS classes/styles for the overlay of the BitCallout.

BitDropDirection enum

Name Value Description
All 0 The direction determined automatically based on the available spaces in all directions.
TopAndBottom 1 The direction determined automatically based on the available spaces in only top and bottom directions.

BitResponsiveMode enum

Name Value Description
None 0 Disables the responsive mode.
Panel 1 Enables the panel responsive mode, whose edge comes from the PanelPlacement parameter.
Top 2 Enables the responsive mode as a sheet that comes down from the top of the screen.
Bottom 3 Enables the responsive mode as a sheet that comes up from the bottom of the screen.

BitPlacement enum

Name Value Description
Top 0 The top edge.
Bottom 1 The bottom edge.
Start 2 The edge the reading direction starts from - the left in LTR, the right in RTL. On the vertical axis, which does not turn around, it is the top.
End 3 The edge the reading direction ends at - the right in LTR, the left in RTL. On the vertical axis, which does not turn around, it is the bottom.
Left 4 The left edge, in both reading directions.
Right 5 The right edge, in both reading directions.
Center 6 The middle of the axis, against neither edge.
TopAndBottom 7 Both edges of the block axis at once.
StartAndEnd 8 Both edges of the inline axis at once, following the reading direction the way Start and End do.

BitColorKind enum

Name Value Description
Primary 0 The primary color kind.
Secondary 1 The secondary color kind.
Tertiary 2 The tertiary color kind.
Transparent 3 The transparent color kind.

BitVisibility enum

Name Value Description
Visible 0 The content of the component is visible.
Hidden 1 The content of the component is hidden, but the space it takes on the page remains (visibility:hidden).
Collapsed 2 The component is hidden (display:none).

BitDir enum

Name Value Description
Ltr 0 Ltr (left to right) is to be used for languages that are written from the left to the right (like English).
Rtl 1 Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic).
Auto 2 Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.