Release notes
Layout components are here
This article never runs wider than its container, however wide the page is, so lines stay easy to read.
Containers
TwContainer is a Blazor container component that centers content at a maximum width with side padding, rendered as any landmark or element.
Last updated
MaxWidth and pads its sides with the theme's Gutter, which widens on larger screens. The dashed outline shows the container's edges inside a wider page.Release notes
This article never runs wider than its container, however wide the page is, so lines stay easy to read.
<TwContainer Element="LayoutElement.Article" MaxWidth="ContainerSize.Xl2" Class="relative rounded-xl border-2 border-dashed border-purple-400 bg-white py-6 dark:border-purple-400/60 dark:bg-gray-900">
<span class="absolute -top-3 start-4 rounded-full bg-purple-600 px-2 py-0.5 font-mono text-xs font-medium text-white">max-w-2xl</span>
<p class="text-xs font-semibold uppercase tracking-wide text-purple-700 dark:text-purple-300">Release notes</p>
<h3 class="mt-1 text-xl font-semibold text-gray-900 dark:text-white">Layout components are here</h3>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-300">This article never runs wider than its container, however wide the page is, so lines stay easy to read.</p>
</TwContainer>MaxWidth to one of Tailwind's sizes, from Xs (20rem) to Xl7 (80rem). Prose keeps lines to a comfortable reading length, Full matches the parent and None removes the limit. Without it, the theme's DefaultMaxWidth applies, Xl7 by default. Each bar below is a container inside the same full-width track.@foreach (var (size, label) in _sizes)
{
<div class="rounded-full bg-gray-100 p-1 dark:bg-white/5">
<TwContainer MaxWidth="size" Gutter="0" Centered="false">
<TwFlex Align="AlignItems.Center" Justify="JustifyContent.Between" Gap="2" Class="rounded-full bg-linear-to-r from-purple-600 to-fuchsia-700 px-3 py-1.5 text-xs text-white">
<span class="font-mono font-medium">@size</span>
<span class="text-white/90">@label</span>
</TwFlex>
</TwContainer>
</div>
}@code {
private static readonly (ContainerSize Size, string Label)[] _sizes =
[
(ContainerSize.Xs, "20rem"),
(ContainerSize.Lg, "32rem"),
(ContainerSize.Xl2, "42rem"),
(ContainerSize.Xl4, "56rem"),
(ContainerSize.Full, "100%")
];
}Gutter to a step on Tailwind's spacing scale for fixed side padding, such as 6 for px-6, or 0 for none. PaddingY pads the top and bottom, and PaddingTop and PaddingBottom override one end. The tinted area is the padding.Gutter="0"
Gutter="8" PaddingY="6"
Gutter="4" PaddingY="6" PaddingBottom="2"
@foreach (var (label, gutter, paddingY, paddingBottom) in _paddings)
{
<TwContainer MaxWidth="ContainerSize.Xl3" Gutter="gutter" PaddingY="paddingY" PaddingBottom="paddingBottom" Rounded="Rounded.Lg" Class="bg-purple-100 bg-[repeating-linear-gradient(45deg,transparent,transparent_6px,rgb(147_51_234/0.12)_6px,rgb(147_51_234/0.12)_7px)] ring-1 ring-purple-600/20 dark:bg-purple-500/15 dark:ring-purple-400/30">
<p class="rounded-md bg-white px-3 py-2 font-mono text-xs text-gray-800 shadow-sm dark:bg-gray-900 dark:text-gray-100">@label</p>
</TwContainer>
}@code {
private static readonly (string Label, double Gutter, double? PaddingY, double? PaddingBottom)[] _paddings =
[
("Gutter=\"0\"", 0, null, null),
("Gutter=\"8\" PaddingY=\"6\"", 8, 6, null),
("Gutter=\"4\" PaddingY=\"6\" PaddingBottom=\"2\"", 4, 6, 2)
];
}Surface to paint the theme's Default, Subtle or Elevated background behind the content, for a band of the page or a panel. A container has no corners or shadow of its own; set Rounded and Shadow to add them.Default
The same surface as a card.
Subtle
A quiet tint for a band of the page.
Elevated
A step up from the default surface.
<TwGrid Cols="1" ColsMd="3" Gap="4">
@foreach (var (surface, shadow, text, icon) in _surfaces)
{
<TwContainer Surface="surface" Shadow="shadow" Gutter="5" PaddingY="5" Rounded="Rounded.Lg" Class="ring-1 ring-gray-900/5 dark:ring-white/10">
<span class="flex size-9 items-center justify-center rounded-lg bg-purple-50 text-purple-700 ring-1 ring-purple-600/10 dark:bg-purple-500/15 dark:text-purple-300 dark:ring-purple-400/20">
<TwIcon Icon="icon" />
</span>
<p class="mt-3 text-sm font-semibold">@surface</p>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">@text</p>
</TwContainer>
}
</TwGrid>@code {
private static readonly (ContainerSurface Surface, Shadow Shadow, string Text, Icon Icon)[] _surfaces =
[
(ContainerSurface.Default, Shadow.Md, "The same surface as a card.", Icon.Grid_3X3_Gap),
(ContainerSurface.Subtle, Shadow.None, "A quiet tint for a band of the page.", Icon.Columns_Gap),
(ContainerSurface.Elevated, Shadow.Sm, "A step up from the default surface.", Icon.Lightning_Charge)
];
}Element to render the element the content calls for, so screen reader users can find it: Main for the page's main content, Section for a band named by its heading, Nav, Aside, Header, Footer and more. Name a section with AriaLabelledBy pointing at its heading to make it a region landmark.Up to 30% off headphones, speakers and smart watches. This band is a section landmark named by its heading.
<TwContainer Element="LayoutElement.Section" AriaLabelledBy="container-offers-heading" MaxWidth="ContainerSize.Xl4" Gutter="8" PaddingY="10" Rounded="Rounded.Lg" Class="relative overflow-hidden bg-linear-to-br from-purple-700 via-purple-700 to-fuchsia-800 text-white">
<TwIcon Icon="Icon.Tag" Class="pointer-events-none absolute -end-6 -bottom-8 text-[10rem] text-white/10" />
<TwChip Label="Ends Sunday" Color="Color.Light" Size="ChipSize.Small" StartIcon="Icon.Clock" />
<h3 id="container-offers-heading" class="mt-3 text-2xl font-semibold tracking-tight">This week's offers</h3>
<p class="mt-2 max-w-md text-sm text-purple-50">Up to 30% off headphones, speakers and smart watches. This band is a section landmark named by its heading.</p>
<TwButton Label="Shop the offers" Color="Color.Light" EndIcon="Icon.Arrow_Up_Right" Class="mt-5" />
</TwContainer>Centered="false" to keep the container at the start of its parent, for example a form that lines up with a heading on the left. It moves to the right in a right to left layout.New components and releases, once a month. No spam.
<TwContainer Element="LayoutElement.Section" AriaLabelledBy="container-newsletter-heading" MaxWidth="ContainerSize.Lg" Centered="false" Gutter="0">
<TwFlex Align="AlignItems.Center" Gap="2">
<TwIcon Icon="Icon.Envelope" Class="text-lg text-purple-700 dark:text-purple-300" />
<h3 id="container-newsletter-heading" class="font-semibold text-gray-900 dark:text-white">Get the monthly update</h3>
</TwFlex>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">New components and releases, once a month. No spam.</p>
<TwFlex Align="AlignItems.End" Gap="2" Class="mt-4">
<TwFlexItem Flex="FlexSize.Fill">
<TwTextfield Id="container-start-email" Label="Email address" @bind-Value="email" Placeholder="[email protected]" type="email" autocomplete="email" />
</TwFlexItem>
<TwButton Label="Subscribe" Color="Color.Primary" />
</TwFlex>
</TwContainer>QueryContainer to let the content respond to the container's width instead of the screen's, with Tailwind's @sm:, @md: and similar prefixes. The same markup sits in a narrow and a wide container below: the narrow one stacks, the wide one lays out in a row.Priya Patel
Product designer, London
AvailablePriya Patel
Product designer, London
Available@foreach (var size in _querySizes)
{
<TwContainer MaxWidth="size" Gutter="4" PaddingY="4" Centered="false" QueryContainer Surface="ContainerSurface.Default" Rounded="Rounded.Lg" Shadow="Shadow.Sm" Class="ring-1 ring-gray-900/5 dark:ring-white/10">
<div class="@queryLayout">
<TwAvatar Name="Priya Patel" Color="Color.Primary" Size="AvatarSize.Large" />
<div class="min-w-0 flex-1">
<p class="font-semibold">Priya Patel</p>
<p class="text-sm text-gray-600 dark:text-gray-300">Product designer, London</p>
<TwChip Label="Available" Color="Color.Success" Size="ChipSize.Small" Class="mt-1.5" />
</div>
<TwButton Label="Message" Variant="ButtonVariant.Outlined" Color="Color.Primary" StartIcon="Icon.Chat_Dots" AriaLabel="@($"Message Priya Patel, {size} container")" />
</div>
</TwContainer>
}@code {
private static readonly ContainerSize[] _querySizes = [ContainerSize.Xs, ContainerSize.Full];
// The @md: prefix responds to the nearest query container, not the screen.
private const string queryLayout = "flex flex-col items-start gap-3 @md:flex-row @md:items-center";
}TwBlazorTheme.Components (a TwContainerTheme), configured via the
AddTwBlazor() options callback described on the Get Started page.
Every property is a set of Tailwind classes, so changes are picked up by your own Tailwind build.
| Property | Type | Controls |
|---|---|---|
Base |
string | |
Centered |
string | |
Gutter |
string | |
DefaultMaxWidth |
ContainerSize | |
QueryContainer |
string | |
SurfaceDefault |
string | |
SurfaceSubtle |
string | |
SurfaceElevated |
string |
The maximum widths come from the shared Sizing.MaxWidth scale and the numeric padding from Spacing, so any component theme can reuse them.
Padding accepts the steps 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20 and 24; add a step to Spacing in your theme to allow another.
Full reference: TwContainerTheme on the API docs.