Skip to content

Center things

If you have ever needed to center something in a web page, you will be glad to know it is much easier in Textual.

This article discusses a few different ways in which things can be centered, and the differences between them.

Aligning widgets

The align rule will center a widget relative to one or both edges. This rule is applied to a container, and will impact how the container's children are arranged. Let's see this in practice with a trivial app containing a Static widget:

from textual.app import App, ComposeResult
from textual.widgets import Static


class CenterApp(App):
    """How to center things."""

    CSS = """
    Screen {
        align: center middle;
    }
    """

    def compose(self) -> ComposeResult:
        yield Static("Hello, World!")


if __name__ == "__main__":
    app = CenterApp()
    app.run()

Here's the output:

CenterApp Hello, World!

The container of the widget is the screen, which has the align: center middle; rule applied. The center part tells Textual to align in the horizontal direction, and middle tells Textual to align in the vertical direction.

The output may surprise you. The text appears to be aligned in the middle (i.e. vertical edge), but left aligned on the horizontal. This isn't a bug — I promise. Let's make a small change to reveal what is happening here. In the next example, we will add a background and a border to our text:

Tip

Adding a border is a very good way of visualizing layout issues, if something isn't behaving as you would expect.

from textual.app import App, ComposeResult
from textual.widgets import Static


class CenterApp(App):
    """How to center things."""

    CSS = """
    Screen {
        align: center middle;
    }

    #hello {
        background: blue 50%;
        border: wide white;
    }
    """

    def compose(self) -> ComposeResult:
        yield Static("Hello, World!", id="hello")


if __name__ == "__main__":
    app = CenterApp()
    app.run()

The static widget will now have a blue background and white border:

CenterApp ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Hello, World! ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Note the static widget is as wide as the screen. Since the widget is as wide as its container, there is no room for it to move in the horizontal direction.

Info

The align rule applies to widgets, not the text.

In order to see the center alignment, we will have to make the widget smaller than the width of the screen. Let's set the width of the Static widget to auto, which will make the widget just wide enough to fit the content:

from textual.app import App, ComposeResult
from textual.widgets import Static


class CenterApp(App):
    """How to center things."""

    CSS = """
    Screen {
        align: center middle;