Footer
Live Demo
Open the demo in a separate tab.
The standalone Footer component is created with footer(...). This is
different from the .footer(...) content-section helper available on Card,
Container, Form, Modal, Alert, Toast, Tabs, and Sidebar fluent elements.
#![allow(unused)]
fn main() {
app()
.children([footer(false, FooterConfig::default())])
.run();
}
A Footer is a layout primitive for organizing content along the bottom of an interface.
It follows the same composition model as the Navbar, providing three named sections:
leftcenterright
The center section is always centered within the Footer. The left and right sections work inward from their respective edges.
The Footer can also contain arbitrary children(), making it useful for simple layouts as well as structured application footers.
The Footer provides the layout. The application provides the content.
Basic Usage
Create a Footer with footer() and compose content into its sections:
#![allow(unused)]
fn main() {
footer()
.left([
text("© 2026 Beverly"),
])
.center([
text("Built with Rust"),
])
.right([
text("v1.0.0"),
])
}
The three sections have predictable spatial behavior:
┌──────────────────────────────────────────────────────────┐
│ LEFT CENTER RIGHT │
│ ←─────── ─────── ───────→ │
└──────────────────────────────────────────────────────────┘
The center remains centered relative to the Footer rather than simply appearing after the left section.
Named Sections
The three named sections are semantic conveniences for common Footer layouts.
Left
left() places content against the left side of the Footer.
#![allow(unused)]
fn main() {
footer()
.left([
text("© 2026 Beverly"),
text("All rights reserved"),
])
}
The left section grows inward from the edge toward the center.
Center
center() places content in the center of the Footer.
#![allow(unused)]
fn main() {
footer()
.center([
text("Built with Rust"),
])
}
The center section is centered relative to the Footer itself.
It does not simply follow the left section.
Right
right() places content against the right side of the Footer.
#![allow(unused)]
fn main() {
footer()
.right([
button().text(localize("footer.settings")),
])
}
The right section grows inward from the right edge toward the center.
Using All Three
A typical application Footer might look like this:
#![allow(unused)]
fn main() {
footer()
.left([
text("© 2026 Beverly"),
])
.center([
text("Privacy"),
text("Terms"),
])
.right([
text("v1.0.0"),
])
}
The center remains centered even when the left and right sections contain different amounts of content.
This makes Footer layouts predictable without requiring application-specific positioning logic.
Children
children() remains the general composition primitive.
#![allow(unused)]
fn main() {
footer()
.children([
text("© 2026 Beverly"),
text("All rights reserved"),
])
}
This is useful when the application does not need the three-section layout.
Named sections are conveniences, not a replacement for children().
A Footer can therefore be used as a simple container:
#![allow(unused)]
fn main() {
footer()
.children([
text("© 2026 Beverly"),
])
}
or as a structured three-section layout:
#![allow(unused)]
fn main() {
footer()
.left(text("© 2026 Beverly"))
.center(text("Privacy"))
.right(text("v1.0.0"))
}
A section can accept one child or many children:
#![allow(unused)]
fn main() {
footer()
.left(text("Beverly"))
}
#![allow(unused)]
fn main() {
footer()
.left([
icon("copyright"),
text("2026 Beverly"),
])
}
children() is the general primitive. Named sections add useful semantics.
Fixed and Non-Fixed Footers
A Footer can either participate in normal layout flow or remain fixed relative to its containing interface.
For a normal Footer:
#![allow(unused)]
fn main() {
footer()
.left(text("© 2026 Beverly"))
.center(text("Privacy"))
.right(text("v1.0.0"))
}
For a fixed Footer:
#![allow(unused)]
fn main() {
footer()
.fixed(true)
.left(text("© 2026 Beverly"))
.center(text("Privacy"))
.right(text("v1.0.0"))
}
A fixed Footer remains positioned according to the application’s layout rules rather than moving with ordinary content flow.
The Footer does not decide whether fixed positioning is appropriate. It simply provides the option.
Styling
Footer uses the same fluent styling model as other Beverly components.
#![allow(unused)]
fn main() {
footer()
.padding(16)
.height(64)
.radius(12)
.left(text("© 2026 Beverly"))
.center(text("Privacy"))
.right(text("v1.0.0"))
}
Layout and presentation remain separate from application behavior.
The Footer determines where content goes. Its children determine what that content is.
Interactive Content
A Footer is not inherently interactive.
It can contain Buttons and other interactive components when the application needs them:
#![allow(unused)]
fn main() {
footer()
.left([
text("© 2026 Beverly"),
])
.right([
button().text(localize("footer.settings"))
.on("click", Command::Settings::Open),
])
}
The Footer does not need to know what the Command does.
It simply provides the layout in which the control appears.
The Footer provides the layout. The children provide the interaction. The application provides the behavior.
Data-Driven Footers
Footer content can come directly from application data:
#![allow(unused)]
fn main() {
footer()
.left(text(app.copyright()))
.center(footer_links())
.right(text(app.version()))
}
Higher-level pieces remain ordinary Rust functions:
#![allow(unused)]
fn main() {
fn footer_links() -> impl Component {
row()
.children([
button().text(localize("footer.privacy"))
.on("click", Command::Navigation::Privacy),
button().text(localize("footer.terms"))
.on("click", Command::Navigation::Terms),
])
}
}
There is no separate Footer component language.
Higher-level components are ordinary Rust functions that return lower-level components.
Accessibility
The Footer is primarily a layout primitive. Interactive elements inside it remain responsible for their own accessible semantics.
#![allow(unused)]
fn main() {
footer()
.left([
text("© 2026 Beverly"),
])
.right([
button().text(localize("footer.settings")),
])
}
The Footer can also expose accessible semantics when the application needs the footer region to be identified:
#![allow(unused)]
fn main() {
footer()
.label(localize("footer.label"))
.aria(localize("footer.description"))
.left([
text("© 2026 Beverly"),
])
.center([
text("Privacy"),
])
.right([
text("v1.0.0"),
])
}
The underlying semantic and layout behavior should be handled by Beverly rather than requiring developers to manually reproduce it.
Accessible by construction, not accessible by cleanup.
What Footer Does Not Do
Footer does not:
- own application state
- manage navigation state
- manage routing
- own application data
- define permissions
- define authentication
- require a separate layout system
- determine what footer content means
Those concerns belong to the application.
The Footer is responsible for organizing interface content.
Navbar and Footer
Navbar and Footer intentionally share the same basic layout vocabulary.
| Component | Purpose |
|---|---|
navbar() | Organizes content at the top or edge of an interface |
footer() | Organizes content at the bottom or edge of an interface |
Both provide:
children()left()center()right()- predictable centered positioning
- optional fixed positioning
- fluent styling
- ordinary Rust composition
The difference is semantic placement, not architectural complexity.
Same composition model. Different place in the interface.
Design Principle
The Footer deliberately provides only the structure that applications repeatedly need:
- content from the left edge
- content from the center
- content from the right edge
- predictable centered positioning
- optional fixed positioning
- general
children()composition
Everything else remains ordinary Beverly composition and ordinary Rust.
Three sections when you need them. children() when you don’t.
The center stays centered. The edges work inward. The application owns the meaning.