Skip to content

Utilities

MediaQuery

Bit.BlazorUI

BitMediaQuery renders content by what the browser's matchMedia API reports, so a layout decision that CSS cannot express - rendering a different component, or none at all, rather than restyling one - is written once beside the markup it belongs to. It offers the predefined bit screen queries, built at runtime from the live theme breakpoints so a customized theme is honored, and accepts any custom media query, including the non-viewport features such as orientation, pointer or prefers-color-scheme.

Usage

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

Basic

The content of the component renders only while the screen matches the query it is given. ScreenQuery takes one of the predefined bit screen queries - here GtSm (everything above the Sm band) and LtMd (everything below the Md band), which between them cover every width - so a piece of markup is kept off the narrow screens, or off the wide ones, without a line of CSS. Resize the window to watch the two swap (zooming in and out works too).

Screen queries

The predefined screen queries come in four shapes: a single band (Xs to Xxl), everything below a breakpoint (Lt*), everything above one (Gt*), and a span between two of them (*To*). The bands never overlap, and each one ends two hundredths of a pixel below where the next one starts, which is close enough that one of the six is matched at any size in practice; the other three shapes are cut from the same breakpoints and do overlap, since each of them answers a different question about the same width. Resize the window to explore them all (zooming in and out works too).


Normal screen queries:

Range screen queries (less than):

Range screen queries (greater than):

Range screen queries (between):

Matched & NotMatched

Matched and NotMatched render different content for each state of the query, making an inline responsive if/else. Matched is an alias for ChildContent and takes precedence over it when both are provided, and either side may be left out: with only NotMatched the component renders nothing while the query matches, which is how a piece of markup is dropped above a breakpoint.

[BitScreenQuery.Md] NotMatched!.

Template

Template is the one fragment that spans both states, receiving the current matched state as its context. It is for the common case where the two states are the same markup told apart by a value - a size, a variant, a class, an attribute - and saves writing that markup twice.
Since it stays one fragment in one place of the render tree, the content is updated rather than torn down and built again when the query flips, so whatever the components inside it hold - a half filled in form, a scroll position - survives the change of the viewport. It takes precedence over Matched, ChildContent and NotMatched.

Theme breakpoints

The predefined screen queries are not baked into the component: they resolve from the live theme breakpoints, so overriding them - globally through BitThemeManager, or for one subtree through BitThemeProvider - changes what the same ScreenQuery matches. Here the very same BitScreenQuery.Md answers to a different width range inside a provider that re-values the Md and Lg breakpoints. Resize the window and watch the two flip at different widths.

Document breakpoints (Md: 960px to 1279.98px):
Md is not matched.
Customized breakpoints (Md: 700px to 899.98px):
Md is not matched.

Custom query

Query takes any valid CSS media query verbatim ( more info (opens in a new tab)), which is what covers the breakpoints that are not part of the theme scale, including the modern range syntax such as (400px <= width <= 700px). It takes precedence over ScreenQuery when both are set, and a query the browser cannot parse is reported as a warning in the developer console rather than silently never matching.

screen and (max-width: 999px):
Not matched yet!
(400px <= width <= 700px):
The width is outside the 400px to 700px range.

Media features

Media queries are not only about the viewport width, and neither is this component. Any media feature the browser understands works as a custom query and is watched the same way: the orientation of the screen, the color scheme the system prefers, how precise the pointing device is, or whether reduced motion is asked for. Each of these changes while the page is open, and the content follows it without a reload.

The screen is in portrait orientation.
The system prefers a light color scheme.
The primary pointing device is coarse or absent (e.g. a touchscreen).
Reduced motion is not requested by the system.

NoWrapper

By default the active content renders inside a root div. NoWrapper removes it and renders the content directly, which is what keeps the component out of the way where the extra element would change the layout - a flex or grid container that lays out its own children, a table row, a list. Nothing that describes an element (the class, the style, the id, the direction) applies then, since there is none; a scoped BitThemeProvider is still honored, because the breakpoints are read from the cascading theme rather than from the missing element. Inspect the output below to see that no wrapper is there.

[BitScreenQuery.GtSm] NotMatched! (still no wrapping element)

DefaultMatched

A media query can only be evaluated by the browser, so until the first answer arrives the component has to render something: by default the not-matched side. DefaultMatched flips that first guess so the matched content renders instead, which is what avoids a flash of the wrong content while a page is prerendered on the server or before the JavaScript runtime is up. The real result takes over as soon as it arrives, so pick the side the majority of the visitors will land on.

This is Matched (BitScreenQuery.GtSm), also rendered before the query gets evaluated.

Binding

IsMatched is two-way bindable, which is the shortest way to hand the state of a query to the rest of a page: a field kept in step by @bind-IsMatched can drive anything, and the component itself needs no content at all. It is an output rather than an input - the browser owns the state - so bind it rather than setting it one way, and use DefaultMatched to seed the value before the first answer arrives.

The screen is currently wide (BitScreenQuery.LtMd).

OnChange

OnChange reports every change of the matched state, and once more at the start with the initial result, right after the browser evaluates the query for the first time - so a handler always sees the real state and not only the changes after it. Use it where a change is an action to take (loading the data a wide layout needs, closing a drawer) rather than a value to hold; where it is a value, bind IsMatched instead, which is also readable at any time from a reference to the component.

[BitScreenQuery.Md] IsMatched?: False
[BitScreenQuery.Md] via the IsMatched property: False
OnChange call count: 0

Style & Class

Style and Class apply to the wrapping root element like they do on every other component of the library, so the box a matched query renders can be styled without an extra element around it. They are ignored while NoWrapper is set, since there is then no element of the component's own to carry them.

Styled through the Style parameter, not matched (GtXs).
Classed through the Class parameter, not matched (GtXs).

RTL

Dir sets the text direction of the wrapping root element, writing the dir attribute and, for right-to-left, the bit-rtl class the rest of the library reads. Like the other parameters that describe an element, it has no effect while NoWrapper is set - the surrounding direction then applies to the content as it stands.

عرض صفحه کمتر از حد GtXs است.

API

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

BitMediaQuery parameters

Name Type Default value Description
CascadingTheme BitTheme? null The theme cascaded from an enclosing BitThemeProvider. Only its breakpoints are read, and only to resolve a ScreenQuery. They take precedence over the --bit-bp-* CSS variables of the rendered element, which is what keeps a scoped theme reachable when there is no element of the component's own to read them from (NoWrapper, or a usage with no content at all).
ChildContent RenderFragment? null The content of the element to render if the specified query is matched.
DefaultMatched bool false The initial matched state to render with until the actual result of the query arrives from the browser. Useful to avoid a flash of the wrong content during prerendering, where the query cannot be evaluated yet. Ignored when IsMatched is bound, since the value handed over is then the initial state already.
IsMatched bool false The current matched state of the provided query. This is an output of the component rather than an input: the browser owns the state, and the component writes the latest result it reports here. Set one way (without a Changed callback beside it) the value belongs to the page, which freezes the state; use DefaultMatched to seed it instead. (two-way bound)
Matched RenderFragment? null The content to be rendered if the provided query is matched (an alias for ChildContent).
NotMatched RenderFragment? null The content to be rendered if the provided query is not matched.
NoWrapper bool false Renders the active content directly, without the wrapping root element. Since no element is rendered, everything that describes one (class, style, id, dir, ...) is ignored.
OnChange EventCallback<bool> The event callback to be called when the state of the media query has been changed. It is also called once with the initial matched state, right after the query gets evaluated by the browser for the first time.
Query string? null Specifies the custom query to be matched. Any valid CSS media query is accepted, including non-viewport features such as orientation, pointer, or prefers-color-scheme. Takes precedence over ScreenQuery when both are provided.
ScreenQuery BitScreenQuery? null Defines the screen query to be matched, amongst the predefined Bit screen media queries. The actual query is built at runtime from the live theme breakpoints (the --bit-bp-* CSS variables), so customized theme breakpoints are honored.
Template RenderFragment<bool>? null The content to be rendered for both states of the query, receiving the current matched state. Since it stays one fragment in one place of the render tree, the content is updated rather than built again when the query flips, so the state the components inside it hold survives the change. Takes precedence over Matched, ChildContent and NotMatched.

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.
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.
IsEnabled bool true Gets or sets a value indicating whether the component is enabled and can respond to user interaction.
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.

BitScreenQuery enum

Name Value Description
Xs 0 Extra small query: [@media screen and (max-width: 599.98px)]
Sm 1 Small query: [@media screen and (min-width: 600px) and (max-width: 959.98px)]
Md 2 Medium query: [@media screen and (min-width: 960px) and (max-width: 1279.98px)]
Lg 3 Large query: [@media screen and (min-width: 1280px) and (max-width: 1919.98px)]
Xl 4 Extra large query: [@media screen and (min-width: 1920px) and (max-width: 2559.98px)]
Xxl 5 Extra extra large query: [@media screen and (min-width: 2560px)]
LtSm 6 Less than small query: [@media screen and (max-width: 599.98px)]
LtMd 7 Less than medium query: [@media screen and (max-width: 959.98px)]
LtLg 8 Less than large query: [@media screen and (max-width: 1279.98px)]
LtXl 9 Less than extra large query: [@media screen and (max-width: 1919.98px)]
LtXxl 10 Less than extra extra large query: [@media screen and (max-width: 2559.98px)]
GtXs 11 Greater than extra small query: [@media screen and (min-width: 600px)]
GtSm 12 Greater than small query: [@media screen and (min-width: 960px)]
GtMd 13 Greater than medium query: [@media screen and (min-width: 1280px)]
GtLg 14 Greater than large query: [@media screen and (min-width: 1920px)]
GtXl 15 Greater than extra large query: [@media screen and (min-width: 2560px)]
SmToMd 16 Small through medium query: [@media screen and (min-width: 600px) and (max-width: 1279.98px)]
SmToLg 17 Small through large query: [@media screen and (min-width: 600px) and (max-width: 1919.98px)]
SmToXl 18 Small through extra large query: [@media screen and (min-width: 600px) and (max-width: 2559.98px)]
MdToLg 19 Medium through large query: [@media screen and (min-width: 960px) and (max-width: 1919.98px)]
MdToXl 20 Medium through extra large query: [@media screen and (min-width: 960px) and (max-width: 2559.98px)]
LgToXl 21 Large through extra large query: [@media screen and (min-width: 1280px) and (max-width: 2559.98px)]

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.