Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  • left
  • center
  • right

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() 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.

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 intentionally share the same basic layout vocabulary.

ComponentPurpose
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.