Skip to content
# Callout **Also known as:** Popover, Popup ## Description 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. ## 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. | | 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. An attribute written on the component wins over an entry of the same name. | | 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. | ## 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. | | 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. | ## Enums ### 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. | ## Sub Classes ### 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. | ## CSS Variables Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves. | 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. | ## Examples \n**Basic**: ```razor Show callout
This is the callout content.
NoOverlay
The page keeps its own clicks.
DefaultIsOpen
Open from the start.
Disabled
Never shown.
``` \n**External anchor**: ```razor AnchorId
``` ```csharp private ElementReference anchorEl; private BitCallout callout1; private BitCallout callout2; ``` \n**Binding**: ```razor Show callout Anchor
Close it from inside.
Done Cancel
IsOpen: @isOpen
``` ```csharp private bool isOpen; ``` \n**Open on hover**: ```razor Hover me
Opened on hover.
Delayed (500ms)
Opening and closing both waited half a second.
``` \n**Dismissal**: ```razor AutoClose (@autoCloseAction)
Rename Duplicate Delete
NoDismissOnScroll
Scroll the page: this one follows its anchor.
No auto dismiss
Neither Escape nor an outside click closes this one.
Close
``` ```csharp private BitCallout callout3; private string autoCloseAction = "none"; ``` \n**Context menu**: ```razor
Right-click anywhere in here
Cut Copy Paste
Last action: @contextAction
``` ```csharp private BitCallout contextCallout; private string contextAction = "none"; ``` \n**Placement**: ```razor A wide anchor to place against
Placed by the options above.
Direction: All
@for (int i = 1; i < 23; i++) {
Callout content @i
}
CollisionPadding of 24px
@for (int i = 1; i < 25; i++) {
Callout content @i
}
Reposition
@for (int i = 1; i <= repositionRows; i++) {
Callout content @i
} Add a row
``` ```csharp private string placementSide = "Auto"; private BitPlacement placementAlignment = BitPlacement.Start; private int placementGap = 8; private int placementOffset; private bool placementNoFlip; private BitPlacement? PlacementSide => Enum.TryParse(placementSide, out var side) ? side : null; private BitCallout callout4 = default!; private int repositionRows = 2; private bool repositionAfterRender; private void AddRepositionRow() { repositionRows++; // The callout is laid out against what is actually in it, so the reposition waits for the render // that puts the new row there rather than measuring the content the callout still holds. repositionAfterRender = true; } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (repositionAfterRender) { repositionAfterRender = false; await callout4.Reposition(); } } ``` \n**Surface**: ```razor Background
A secondary background.
Border
A primary border.
NoShadow
No elevation, only a border.
``` \n**Arrow**: ```razor With an arrow
Points at its anchor.
Beside, with a border
The beak takes the border too.
ArrowSize of 20px
A bigger beak.
ArrowPadding of 64px
The beak is held 64px away from the corners of the callout.
``` \n**Sizing**: ```razor Width
A callout of a fixed width.
MaxWidth
A long line of text that wraps inside the callout instead of stretching it across the page.
MaxHeight & MinWidth
@for (int i = 1; i < 25; i++) {
Callout content @i
}
A wide anchor with SetCalloutWidth
Short content.
A wide anchor with FixedCalloutWidth
A long line of text that wraps rather than making the callout wider than its anchor.
``` \n**Header & footer**: ```razor Header & Footer
A header that stays put
@for (int i = 1; i < 69; i++) {
Callout content @i
}
A footer that stays put
Wired up by hand
A header that stays put
@for (int i = 1; i < 69; i++) {
Callout content @i
}
``` \n**Responsive**: ```razor End panel
Filters
Start panel
Filters
Top sheet
Swipe up to dismiss it.
Bottom sheet
Swipe down to dismiss it.
``` \n**Focus & modal**: ```razor AutoFocus
Dismiss
TrapFocus
Contact
Submit
Modal
Heads up OK
Role & AriaLabel
Everything is up to date.
``` ```csharp private BitCallout modalCallout; ``` \n**Nesting**: ```razor Filters
Filters More options
The panel behind is still open. One more level
And so is this one.
``` \n**Lazy rendering**: ```razor LazyRender
Rendered up front
``` ```csharp private DateTimeOffset? lazyDate; private DateTimeOffset? eagerDate; ``` \n**Events**: ```razor Show callout
This is the callout content.
Toggled: @toggleCount, Opened: @openCount, Dismissed: @dismissCount
``` ```csharp private int openCount; private int toggleCount; private int dismissCount; ``` \n**Cascading parameters**: ```razor Cascaded
Arrow, gap, border and side come from the cascade.
Cascaded too
The same defaults.
Own Placement, no arrow
Its own values win.
Outside the cascade
No defaults here.
``` ```csharp private readonly BitCalloutParams[] calloutParams = [ new() { ShowArrow = true, Gap = 8, Placement = BitPlacement.End, Border = BitColorKind.Secondary, NoShadow = true, } ]; ``` \n**Style & Class**: ```razor Inverted A dark surface, rounder corners and a bigger beak. Outlined
Outlined
A border instead of elevation; the padding goes inside the header, the body and the footer.
Got it
Component's Style
This is the callout content.
Component's Class
This is the callout content.
Styles
This is the callout content.
Classes
This is the callout content.
``` \n**RTL**: ```razor نمایش کال‌اوت
این محتوای کال‌اوت است.
همه جهت‌ها
@for (int i = 1; i < 13; i++) {
محتوای کال‌اوت @i
}
```