Skip to content

Extras

AppShell

Bit.BlazorUI.ExtrasAppLayoutAppContainerSafeArea

BitAppShell is the outermost element of an application. It insets the four edges of the screen by the safe areas the device reports - the notch, the rounded corners, the home indicator - so the content never lands underneath any of them, paints those four bars in the background color of the theme, and gives any one of those edges back to a layout that insets it itself. Inside them it owns the one region the application scrolls in, which is what makes a Blazor app scroll like an app rather than like a page: the header and the footer stay put, only the middle moves, and the scroller is cascaded to every surface declared inside the shell, so a Modal, a Panel, a Dialog or an Overlay holds the right region without being told which one it is. That scroller is a full one - overflow per axis, a reserved scrollbar gutter, scroll padding for a sticky header, pinning to the end as content arrives and keeping the reader's place as content lands above them - and it takes the height of the on-screen keyboard off itself while one is open. On top of that the shell can send the reader to the top of each page they navigate to, or put them back exactly where they left each page off; report where it stands as it is scrolled and call back as it reaches an edge; be scrolled from code with GoToTop, GoToBottom, ScrollTo, ScrollBy and ScrollToElement; and hand a list of cascading values down to everything it contains.

Notes

To use this component, you need to install the Bit.BlazorUI.Extras(opens in a new tab) nuget package, as described in the Optional steps of the Getting started page.

The app shell belongs in MainLayout, wrapped around everything the application renders, and it fills whatever room it is given - so the html and body of the host page need a height of their own for it to have any, unless FullScreen is set, which pins the shell to the four edges of the window instead and takes the host page out of the question. The examples below can do neither: they put a shell inside a box of a fixed height, which is the only way to show a full-screen container on a page that is already inside one. Each also carries an Id, since the id of the shell's scrolling container is derived from it and only one element of a page can carry a given id.

A component that has to work on the region the application scrolls in, rather than on one of its own, is pointed at the shell's container: BitPullToRefresh and BitInfiniteScrolling take a ScrollerSelector of #BitAppShell-container - or, for a shell with an Id, the MainContainerId of that shell. A BitModal, BitPanel, BitDialog or BitOverlay needs none of that: the shell cascades its container and they read it.

The scrolling middle of the shell is a flex row, so a page put inside it is laid out as one flex item: give the element that holds the page a width of 100% - or make it the flex column the page is - and it fills the shell rather than shrinking to fit its own content.

The four insets come from the CSS env(safe-area-inset-*) variables, which a browser only reports as anything other than zero on a page whose viewport meta tag carries viewport-fit=cover. Without it - and on every desktop browser - all four are 0 and the bars take up no room at all, which is why the example below sizes them by hand to show them.

Usage

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

Basic

A shell is a container with four inset bars around one scrolling middle. Everything put inside it lands in that middle - bit-ash-main - which is the only part that scrolls, so a header and a footer declared inside the shell's content stay where they are put while the content between them moves.


Header
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12

Safe area insets

The four bars are sized from the safe areas of the device and painted in the theme's background color, so the notch and the home indicator of a phone sit over the shell's own color instead of over the content. They are 0 on a desktop browser, so the example stands in for a phone through Styles: its root is handed the safe areas a device would report - the --bit-env-inset-* variables the bars are sized from - and each bar is given a color of its own to make it visible.

NoInsets takes all four back to zero for an edge-to-edge layout - the one where the application insets its own chrome instead, so a header's background paints behind the status bar rather than below it. NoTopInset, NoBottomInset, NoStartInset and NoEndInset do the same to one edge at a time, which is what a layout that goes edge to edge at the top while still keeping the home indicator clear asks for. The two side ones are the logical edges, so each stays with the reading direction the bars are laid out in.

Each bar is sized from a CSS variable of its own - --bit-ash-inset-top, --bit-ash-inset-bottom, --bit-ash-inset-start and --bit-ash-inset-end - which the page can read to inset chrome of its own by the same amount, or override to give one edge a bigger inset than the device asked for.

The insets a browser reports are not constants: an edge-to-edge Chrome on Android retracts its bottom bar as the reader scrolls down and brings it back on the way up, and the inset follows it the whole way - so everything laid out against it moves on every frame of that slide. StableInsets sizes the bars from the static maximums instead, which lays the shell out once for the room left when nothing is retracted and lets the browser slide its own chrome over the background of a bar rather than over the content. A browser that does not report those maximums is left reading the insets it does report.



Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12

Keyboard inset

Opening the on-screen keyboard leaves the layout viewport - and with it every percentage height on the page - exactly as it was on the platforms where this matters, so a shell that is not told about it goes on believing it owns a screen whose bottom is now behind the keyboard, and a bottom bar declared inside it disappears under one.

AvoidKeyboard measures how much is covered, publishes it on the root of the shell as the --bit-ash-keyboard-inset CSS variable, and takes that much off the height of the scrolling middle - so the bar comes back up above the keyboard and the content is laid out in the room that is actually left. A page can read the same variable to place chrome of its own against it. It measures 0, and so does nothing at all, wherever the browser shrinks the layout viewport itself: every desktop browser, and any page asking for interactive-widget=resizes-content. What the bottom safe area inset was keeping clear is covered by the keyboard as well, so that inset is given up for as long as the keyboard is open rather than left as a band of background above it.

The shell also marks itself with the data-bit-ash-keyboard attribute while the keyboard is up, which is what a bottom bar that hides itself while the reader is typing can be styled against, and reports the same measurement to C# through OnKeyboardInsetChanged for the chrome that cannot be placed in CSS alone.


Focus the field below on a phone to see the bar ride up with the keyboard. On a desktop browser there is no keyboard to make room for, so nothing moves.

Keyboard inset: 0 px

Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10

Scrolling from code

A reference to the shell scrolls its main container from anywhere in the application. GoToTop and GoToBottom go to either end, ScrollTo to a position - a null axis is left where it stands - ScrollBy by an amount from wherever it currently is, and ScrollToElement brings a descendant into view by scrolling the shell itself rather than every scroller the page sits in.

GetScrollOffset reads where it stands at the moment it is asked, which needs none of the scroll callbacks to be handled. Each of the moves takes an optional BitScrollBehavior; left out, the shell's own ScrollBehavior decides, and that one honors the reduced motion preference on its own.



-

Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15
Row 16
Row 17
Row 18
Row 19
Row 20 (the ScrollToElement target)
Row 21
Row 22
Row 23
Row 24
Row 25
Row 26
Row 27
Row 28
Row 29
Row 30

Scroll events

OnScroll reports where the shell stands as it moves, and the position it carries also says which way it went since the last report - which is what a header that folds away on the way down and comes back on the way up reads. OnScrollStart and OnScrollEnd bracket a whole gesture, and OnReachedTop / OnReachedBottom fire once per arrival at either end rather than on every frame that stays there - ReachOffset decides how near counts as arrived, which is what loading the next page of an endless list a little before the reader gets there is built on. OnReachedLeft and OnReachedRight are the same two for the horizontal axis, and they are the edges on the screen rather than in reading order, so they mean the same thing in a right-to-left shell.

None of this costs anything until one of the callbacks is handled: a shell with no handler has no scroll listener at all. ScrollThrottle caps how often OnScroll reports; the default of 0 is once per animation frame.


Top: 0 px (0%)
Direction: -
Phase: idle
Reached: -

Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15
Row 16
Row 17
Row 18
Row 19
Row 20
Row 21
Row 22
Row 23
Row 24
Row 25
Row 26
Row 27
Row 28
Row 29
Row 30
Row 31
Row 32
Row 33
Row 34
Row 35
Row 36
Row 37
Row 38
Row 39
Row 40

Scroll behavior

ScrollBehavior decides how every move the reader does not make by hand is animated: the methods above, a fragment navigation into the shell, and the browser bringing a focused element into view. It defaults to Smooth, which is taken back off on its own when the system asks for reduced motion - use the ForceAnimation toggle at the top of this page to see it animate anyway. Instant makes every one of those moves a single jump.




Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15
Row 16
Row 17
Row 18
Row 19
Row 20
Row 21
Row 22
Row 23
Row 24
Row 25
Row 26
Row 27
Row 28
Row 29
Row 30

Overscroll & NoScroll

Overscroll is what the browser does with a scroll that has already reached the edge of the shell. It defaults to None, which is what an app-like layout wants: the scroll does not carry on into whatever is behind the shell, and the platform's own overscroll affordances - the rubber band, the pull-to-refresh, the navigation swipe - are suppressed. Contain stops the chaining and keeps those affordances; Auto gives both back to a shell that is really a web page.

NoScroll stops the reader from moving the shell at all - the content that overflows is clipped instead. The scrolling methods above still move it, since it is only the reader's own gestures that are taken away, which is what a page that drives its own position wants.




Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15
Row 16
Row 17
Row 18
Row 19
Row 20
Row 21
Row 22
Row 23
Row 24
Row 25
Row 26
Row 27
Row 28
Row 29
Row 30

Navigation

A page navigated to in an app that scrolls a region of its own opens wherever the previous page was left, since the region never moved. AutoGoToTop sends the reader to the top of each page they arrive at, which is what a browser does on its own for a page that scrolls the document.

PersistScroll is the other half of it: it remembers where each url was left and puts the reader back there, so going back to a long list lands on the row they came from rather than at its top. The positions are kept per url in session storage, so they survive a reload and are gone when the tab is; it takes precedence over AutoGoToTop, and ClearPersistedScroll forgets all of them - which is what an application calls when it signs a user out - or, given a url, just that one page, for a list that has been filtered or a search that has been run again under the reader, where the position it was left at no longer points at anything. Neither of them reacts to a navigation that only changes the fragment of the url, so an in-page anchor still works.

A position is put back the moment the page renders, and kept being put back over the next couple of seconds as the content of that page arrives - a fetch still in flight, an image without a size in its markup, a list that has only rendered its first screen - since a container that is not tall enough yet can only be scrolled as far as it goes. The first thing the reader does gives up on it: being put back where they left off is worth nothing against where they are going now.


Both features are about moving between pages, which a shell inside this page cannot show - the markup opposite is what they look like where they belong.

Cascading values

The shell wraps everything it contains in cascading values, so an application does not need a chain of CascadingValue components around its layout to hand the same few things - the signed-in user, a culture, a feature switch - to every page. Values takes a list of BitCascadingValue and ValueList a builder for the same thing; the ones in Values are provided last, so they win over a value of the same type or name in ValueList.

A value can be named, fixed, or left changeable - changing one refreshes the components that read it without the shell having to be re-rendered by hand.


Cascaded by type: Saleh Yusefnejad (Developer)
Cascaded by name: bit platform

Overflow & gutter

The scrolling middle takes whatever overflows it along both axes, which is what an application that lays a page out wider than the screen needs. OverflowX and OverflowY decide that per axis: Hidden clips the overflow instead of offering it, which is how the one element a few pixels too wide is kept from leaving the whole application scrollable sideways - the commonest layout bug of a mobile web app. NoScroll takes both axes away at once and wins over either of them.

Gutter reserves the room the scrollbar takes whether or not there is anything left to scroll. On the one scroller of an application that is worth having: without it, every navigation between a page long enough to scroll and a page that is not moves the whole layout sideways by the width of a scrollbar. It costs nothing where the platform draws its scrollbars over the content, which is every mobile browser - turn the short page on and off below to see the difference on a desktop one.



A row wider than the shell
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15
Row 16
Row 17
Row 18
Row 19
Row 20

Scroll padding

A header stuck to the top of the shell covers whatever is scrolled to underneath it - by a fragment navigation, by the browser bringing a focused field into view, or by ScrollToElement. ScrollPadding is the room the shell keeps between its edges and anything scrolled into view inside it, so the move stops that much short and what was scrolled to lands below the header rather than behind it.

It takes any CSS length, and the insets of the shell can be part of it: a padding of calc(var(--bit-ash-inset-top) + 3rem) is a header as tall as the status bar and a bar of its own. The moves that take an absolute position or a distance - ScrollTo, ScrollBy, GoToTop - are left alone by it.




A header stuck to the top of the shell
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Row 13
Row 14
Row 15 (the target)
Row 16
Row 17
Row 18
Row 19
Row 20
Row 21
Row 22
Row 23
Row 24
Row 25
Row 26
Row 27
Row 28
Row 29
Row 30

Endless content

AutoScroll keeps the shell pinned to the end of its content as the content grows, which is what a chat, a log or a console wants. It only keeps pinning while the reader left it standing at the end, so someone who scrolled up to read something is not dragged back down by the next arrival, and scrolling back to the end takes the pinning up again; AutoScrollThreshold says how near the end still counts as being at it.

PreserveScroll is the other half of an endless list: a page of older content arriving above what the reader is looking at would otherwise push it that far down the screen, and with this the shell is moved by exactly what arrived, so nothing appears to move at all. It is worth pairing with OnReachedTop and a ReachOffset of about a screenful. Refresh re-measures the shell for the changes neither its own size nor its content announce - a web font that has finished loading, an image that settled at a size its markup never named.




Message 1
Message 2
Message 3
Message 4
Message 5
Message 6
Message 7
Message 8
Message 9
Message 10
Message 11
Message 12

Style & Class

Style and Class reach the root of the shell, and Styles and Classes reach each of its seven parts by name: Root, Top, Center, Left, Main, Right and Bottom - which is how the inset bars are given a color of their own, and how the scrolling middle is given padding without a wrapper element inside it.


Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12

RTL

Set Dir to Rtl to lay the shell out right to left. The two side bars follow the reading direction while staying tied to the physical edge each safe area belongs to, so the inset of the left of the screen is still the one that keeps content off the left of the screen whichever way the app reads.


سطر 1
سطر 2
سطر 3
سطر 4
سطر 5
سطر 6
سطر 7
سطر 8
سطر 9
سطر 10
سطر 11
سطر 12

API

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

BitAppShell parameters

Name Type Default value Description
AutoGoToTop bool false Enables auto-scroll to the top of the main container on navigation. A navigation that only changes the fragment of the url (an in-page anchor) is left alone. PersistScroll takes precedence over it.
AutoScroll bool false Keeps the main container pinned to the end of its content as the content grows, for as long as the reader left it standing at the end.
AutoScrollThreshold int 0 How near the end of the content (in pixels) the main container has to have been left for AutoScroll to keep pinning it there.
AvoidKeyboard bool false Takes the height of the on-screen keyboard off the scrolling area while it is open, publishes it on the root as the --bit-ash-keyboard-inset CSS variable and marks the root with the data-bit-ash-keyboard attribute. It measures 0 wherever the browser shrinks the layout viewport itself.
ChildContent RenderFragment? null The content of the app shell. It is rendered inside the main (scrolling) container.
Classes BitAppShellClassStyles? null Custom CSS classes for different parts of the app shell.
FullScreen bool false Pins the app shell to the four edges of the screen, so it fills the window whatever height the page around it has - which is what saves the host page from carrying a height of its own down through html and body.
Gutter BitScrollbarGutter? null Reserves the room the scrollbar of the main container takes, whether or not there is anything left to scroll, so the layout does not shift between a page that scrolls and a page that does not.
NoBottomInset bool false Removes the bottom safe area inset of the app shell, leaving the other three where they are.
NoEndInset bool false Removes the trailing side safe area inset of the app shell - the right of a left-to-right shell - leaving the other three where they are.
NoInsets bool false Removes the safe area insets, so the four edges of the app shell are not inset at all and the content fills the whole screen.
NoScroll bool false Prevents the reader from scrolling the main container at all; the content that overflows is clipped. The scrolling methods of the component still move it.
NoStartInset bool false Removes the leading side safe area inset of the app shell - the left of a left-to-right shell - leaving the other three where they are.
NoTopInset bool false Removes the top safe area inset of the app shell, leaving the other three where they are.
OnKeyboardInsetChanged EventCallback<double> Callback for how much of the app shell the on-screen keyboard covers, in pixels, raised as that changes and with 0 as it closes. Only a shell with AvoidKeyboard set measures it at all.
OnReachedBottom EventCallback Callback for when the main container reaches the bottom of its content, raised once per arrival rather than on every frame that stays there.
OnReachedLeft EventCallback Callback for when the main container reaches the visual left edge of its content, which is the same edge whichever way the shell reads.
OnReachedRight EventCallback Callback for when the main container reaches the visual right edge of its content.
OnReachedTop EventCallback Callback for when the main container reaches the top of its content.
OnScroll EventCallback<BitScrollOffset> Callback for the scroll position of the main container, raised as it is scrolled. Nothing is measured or reported until one of the scroll callbacks is handled.
OnScrollEnd EventCallback<BitScrollOffset> Callback for when a scroll of the main container comes to a stop.
OnScrollStart EventCallback<BitScrollOffset> Callback for when a scroll of the main container begins.
OverflowX BitOverflow? null What the main container does with content that overflows it sideways. Hidden clips it instead of offering it, and NoScroll wins over both axes.
OverflowY BitOverflow? null What the main container does with content that overflows it downwards. See OverflowX.
Overscroll BitOverscroll? null Determines what happens when the main container is scrolled past its edge. It defaults to None: no scroll chaining out of the shell and no pull-to-refresh or rubber-banding.
PersistScroll bool false Persists scroll position of the main container per url in session storage and restores it on navigation. A fragment-only navigation is left alone.
PreserveScroll bool false Keeps the place of the reader when content is added above what they are looking at, which is what an endless list growing upwards needs.
ReachOffset int 0 How near an edge (in pixels) counts as having reached it, for OnReachedTop and OnReachedBottom.
ScrollBehavior BitScrollBehavior? null The scroll behavior of the main container, which decides how every move the reader does not make by hand is animated. It defaults to Smooth, and is taken back off under the reduced motion preference.
ScrollPadding string? null The room the main container keeps between its edges and anything scrolled into view inside it, as any CSS length - which is what keeps a header stuck to the top of the shell from covering what was just scrolled to.
ScrollThrottle int 0 The shortest interval (in milliseconds) between two OnScroll reports. The default of 0 reports once per animation frame.
StableInsets bool false Sizes the four inset bars from the largest safe areas the device can ask for rather than from the ones it is asking for right now, so the layout is not relaid out as the browser slides its own chrome in and out.
Styles BitAppShellClassStyles? null Custom CSS styles for different parts of the app shell.
ValueList BitCascadingValueList? null The cascading value list to be provided for the children of the app shell. Its values are provided before (so they can be overridden by) the ones of the Values parameter.
Values IEnumerable<BitCascadingValue>? null The cascading values to be provided for the children of the app shell.

BitAppShell public members

Name Type Default value Description
ClearPersistedScroll Func<string?, Task> Forgets every scroll position PersistScroll has kept, for the pages of this app shell and of any other - or, given a url, only the position kept for that one page.
Container const string "BitAppShell.Container" The name the app shell cascades the element of its main container under, which is what a Modal, a Panel, a Dialog or an Overlay inside the shell reads to hold the right scroller.
ContainerId const string "BitAppShell-container" The id the main container carries when the app shell has no Id of its own.
ContainerRef ElementReference? null The element reference to the main container of the app shell.
GetScrollOffset Func<Task<BitScrollOffset?>> Reads where the main container currently stands, measured in the browser.
GoToBottom Func<BitScrollBehavior?, Task> Scrolls the main container to the bottom of its content.
GoToTop Func<BitScrollBehavior?, Task> Scrolls the main container to top.
MainContainerId string The id of the main container element of this app shell: ContainerId, or the Id of the shell with "-container" after it.
Refresh Func<Task> Re-measures the main container and reports whatever has changed since it was last measured - for the changes neither its own size nor its content announce, such as a web font that has finished loading.
ScrollBy Func<double, double, BitScrollBehavior?, Task> Scrolls the main container by an amount, from wherever it currently stands.
ScrollTo Func<double?, double?, BitScrollBehavior?, Task> Scrolls the main container to a position. A null axis is left where it stands.
ScrollToElement Func<string, double, bool, BitScrollAlignment, BitScrollBehavior?, Task> Brings an element inside the main container into view by scrolling the container itself rather than every scroller the page sits in.

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.

BitCascadingValueList properties

A helper class to ease the using of a list of the BitCascadingValue.

Name Type Default value Description
Add<T>(T value, string? name = null, bool isFixed = false) void Adds a typed BitCascadingValue to the list.

BitCascadingValue properties

The cascading value to be provided using the BitCascadingValueProvider component.

Name Type Default value Description
Name string? null The optional name of the cascading value.
Value object? null The value to be provided.
IsFixed bool false If true, indicates that Value will not change.

BitAppShellClassStyles properties

Name Type Default value Description
Root string? null Custom CSS classes/styles for the root of the BitAppShell.
Top string? null Custom CSS classes/styles for the top inset bar of the BitAppShell.
Center string? null Custom CSS classes/styles for the center row of the BitAppShell, which holds the two side inset bars and the main container.
Left string? null Custom CSS classes/styles for the leading side inset bar of the BitAppShell.
Main string? null Custom CSS classes/styles for the main (scrolling) container of the BitAppShell.
Right string? null Custom CSS classes/styles for the trailing side inset bar of the BitAppShell.
Bottom string? null Custom CSS classes/styles for the bottom inset bar of the BitAppShell.

BitScrollOffset properties

Where the main container of the app shell stands, as measured in the browser. Everything is in CSS pixels; the members derived from the measured ones cost nothing to read.

Name Type Default value Description
Left double 0 The raw scrollLeft of the container.
Top double 0 How far the content has been scrolled down.
ScrollWidth double 0 The full width of the content, including the part scrolled out of sight.
ScrollHeight double 0 The full height of the content, including the part scrolled out of sight.
ClientWidth double 0 The width of the visible area, without its scrollbar.
ClientHeight double 0 The height of the visible area, without its scrollbar.
Rtl bool false Whether the container was laid out right to left when it was measured.
DeltaLeft / DeltaTop double 0 How far the container has moved since the position before this one was reported. Only the OnScroll reports carry them.
OffsetLeft double The distance from the visual left edge, which is Left made positive and direction independent.
MaxLeft / MaxTop double The largest offset each axis can reach, which is how much of the content is out of sight.
ScrollableX / ScrollableY bool Whether there is anything to scroll along each axis at all.
AtLeft / AtRight / AtTop / AtBottom bool Whether the container is standing at each edge, within a pixel of slack.
PercentX / PercentY double How far the container has been scrolled along each axis, from 0 to 1.
ScrollingUp / ScrollingDown / ScrollingLeft / ScrollingRight bool Which way the move this report carries went, derived from the deltas - which is what a header that folds away on the way down reads.

BitScrollBehavior enum

Name Value Description
Smooth 0 Scrolling should animate smoothly.
Instant 1 Scrolling should happen instantly in a single jump.
Auto 2 Scroll behavior is determined by the computed value of scroll-behavior.

BitOverflow enum

Name Value Description
Auto 0 A scrollbar is offered along that axis when the content overflows, and nothing is shown when it does not.
Hidden 1 The overflow is clipped and no scrollbar is offered, though the axis can still be moved through the scrolling methods of the component.
Scroll 2 A scrollbar is always shown along that axis, whether or not there is anything to scroll.
Visible 3 The overflow is neither clipped nor scrollable, so it is painted outside the container.

BitScrollbarGutter enum

Name Value Description
Auto 0 The initial value: a classic scrollbar takes its room only while there is something to scroll, and an overlay scrollbar takes none at all.
Stable 1 The room is reserved whether or not there is anything to scroll, so the layout does not shift as pages of different lengths follow one another.
BothEdges 2 Like Stable, with the same room reserved on the opposite edge as well, so the content stays centered.

BitOverscroll enum

Name Value Description
Auto 0 The scroll carries on into the nearest scrolling ancestor, and the platform's own overscroll affordance is kept.
Contain 1 The scroll stops at the edge instead of carrying on into the page behind it, while the platform's own overscroll affordance is kept.
None 2 Like Contain, and the platform's own overscroll affordance is suppressed as well, so the container neither bounces nor triggers a pull to refresh.

BitScrollAlignment enum

Name Value Description
Start 0 The element is brought to the start of the container.
Center 1 The element is centered in the container along both axes.
End 2 The element is brought to the end of the container.
Nearest 3 The container moves as little as it can.

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.