Search code examples
pythoncsstextual-framework

dynamically determine height of widget in python-textual


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?


Solution

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