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:
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:
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;
}
#hello {
background: blue 50%;
border: wide white;
width: auto;
}
"""
def compose(self) -> ComposeResult:
yield Static("Hello, World!", id="hello")
if __name__ == "__main__":
app = CenterApp()
app.run()
If you run this now, you should see the widget is aligned on both axis:
Aligning text¶
In addition to aligning widgets, you may also want to align text. In order to demonstrate the difference, lets update the example with some longer text. We will also set the width of the widget to something smaller, to force the text to wrap.
from textual.app import App, ComposeResult
from textual.widgets import Static
QUOTE = "Could not find you in Seattle and no terminal is in operation at your classified address."
class CenterApp(App):
"""How to center things."""
CSS = """
Screen {
align: center middle;
}
#hello {
background: blue 50%;