Skip to content

Centering a `Rect`

You can use a Vertical layout followed by a Horizontal layout to get a centered Rect.

layout.rs
13 collapsed lines
/// Centers a [`Rect`] within another [`Rect`] using the provided [`Constraint`]s.
///
/// # Examples
///
/// ```rust
/// use ratatui::layout::{Constraint, Rect};
///
/// let area = Rect::new(0, 0, 100, 100);
/// let horizontal = Constraint::Percentage(20);
/// let vertical = Constraint::Percentage(30);
///
/// let centered = center(area, horizontal, vertical);
/// ```
fn center(area: Rect, horizontal: Constraint, vertical: Constraint) -> Rect {
let [area] = Layout::horizontal([horizontal])
.flex(Flex::Center)
.areas(area);
let [area] = Layout::vertical([vertical]).flex(Flex::Center).areas(area);
area
}

Then you can use this method to draw any widget centered on the containing area.

fn render(frame: &mut Frame) {
let text = Text::raw("Hello world!");
let area = center(
frame.size(),
Constraint::Length(text.width() as u16),
Constraint::Length(1),
);
frame.render_widget(text, area);
}

A common use case for this feature is to create a popup style dialog block. For this, typically, you’ll want to Clear the popup area before rendering your content to it. The following is an example of how you might do that:

fn render_popup(frame: &mut Frame) {
let area = center(
frame.size(),
Constraint::Percentage(20),
Constraint::Length(3), // top and bottom border + content
);
let popup = Paragraph::new("Popup content").block(Block::bordered().title("Popup"));
frame.render_widget(Clear, area);
frame.render_widget(popup, area);
}

Full code for this recipe is available in the website repo at: https://github.com/ratatui-org/ratatui-website/blob/main/code/recipes/src/layout.rs

See also

There are several third party widget libraries for making popups easy to use: