I develop a simple app using Textual framework. I have two widgets W1 and W2. W1 has a fixed height of 20
(lines). Now I want W2 to take up the rest of the vertical space. In css for a browser I would use calc(100vh - 20)
but textual does not (yet) support this.
How can I achieve this dynamic (i.e. viewport-height-dependent) layout?
Your best approach here will be to use the fr
dimension unit. This makes it easy to split a container up while retaining relative dimensions and it also mixes well with specific-value dimensions. So, in your code, it would make sense to say that one particular widget is simply height: 20
while the other is height: 1fr
.
As a simple example:
from textual.app import App, ComposeResult
from textual.containers import Vertical
from textual.widgets import Header, Footer, Static
class HeightApp( App[ None ] ):
CSS = """
Static {
border: round green;
}
#top {
height: 20;
}
#bottom {
height: 1fr;
}
"""
def compose( self ) -> ComposeResult:
yield Header()
with Vertical():
yield Static( "This is 20 high", id="top" )
yield Static( "This is the rest of the terminal high", id="bottom" )
yield Footer()
if __name__ == "__main__":
HeightApp().run()