Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to tell a child widget to be 100% the height of the parent widget #1319

Closed
davep opened this issue Dec 5, 2022 · 9 comments
Closed

Comments

@davep
Copy link
Contributor

davep commented Dec 5, 2022

Given this code:

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

class HeightApp( App[ None ] ):

    CSS = """
    Horizontal {
        border: solid red;
        height: auto;
    }

    Static {
        border: solid green;
        width: auto;
    }

    #fill_parent {
        height: auto;
    }

    #static {
        height: 23;
    }
    """

    def compose( self ) -> ComposeResult:
        yield Horizontal(
            Static( "How to make this as tall as container?", id="fill_parent" ),
            Static( "This has default\nheight\nbut a\nfew lines" ),
            Static( "I have a static height", id="static" ),
        )

if __name__ == "__main__":
    HeightApp().run()

this is the output:
Screenshot 2022-12-05 at 12 08 10
Now imagine you want to make the first widget exactly as tall as the containing widget. Given all other things seen in CSS, it feels like you should be able to set the height of fill_parent to 100% and it will vertically fill the parent -- in effect matching the height of the tallest non-relative-sized widget. But if I do that the widget does this instead:
Screenshot 2022-12-05 at 12 09 07
It's as if it is taking the height from the container's container, or simply the Screen.

Note the same happens if height is set to 1fr.

Raising this issue to first check if this is the expected behaviour.

@GreNait
Copy link

GreNait commented Dec 5, 2022

Isn't that due to the reason, that your "horizontal" layout is also set to auto? If you change that to a "fixed" value, would that solve the issue?

@davep
Copy link
Contributor Author

davep commented Dec 5, 2022

If you change that to a "fixed" value, would that solve the issue?

I'd say that would work around it rather than solve it; and aye it'd work, kinda. Of course it would mean the layout would have to have advance knowledge of how tall the children are and it's not going to easily react to and handle changes in the width of the terminal.

The above though is mostly constructed that way as a small isolated way of demonstrating that perhaps the choice being made for a 100% or 1fr child, in this case, isn't the best one.

@GreNait
Copy link

GreNait commented Dec 5, 2022

You are right, I also would rather changed that behavior. Btw.: wouldn't that also have issues with the header&footer and their size? Typically, I would have expected that in the perfect case, the height would be optimized to stop at the "footer" border. But it isn't with the behavior above, right?

@davep
Copy link
Contributor Author

davep commented Dec 5, 2022

If I'm understanding you correctly... that's fine, the enclosing Horizontal avoids those:

Screenshot 2022-12-05 at 15 53 20

I've not dived into the code yet (this issue is for future investigation for me as much as anything), but I feel like there could be a tweak to be had here regarding deciding which child height wins when trying to decide the best height.

davep added a commit to davep/textual-sandbox that referenced this issue Dec 5, 2022
@willmcgugan
Copy link
Collaborator

There's a chicken and egg situation here where the container needs to know how tall the children are, and the children needs to know how tall the container is.

You can't always expect the layout engine to figure this out. Imagine a child has a height of 120% and the container has height auto. The container can never be big enough to fit its children, so height: auto can't be satisfied.

That said, there is a solution that I think may give you your desired result. Try this:

    Horizontal > * {
        min-height: 100%;
    }

@davep
Copy link
Contributor Author

davep commented Dec 6, 2022

There's a chicken and egg situation here where the container needs to know how tall the children are, and the children needs to know how tall the container is.

Indeed. I suppose, in part, what I'm trying to work out here is what the rules currently are about what wins -- perhaps this issue should be less about trying to work out this case and more about looking to document the rules?

In the over-height case I think my (possibly ignorant) expectation would be that the container would be the height of the (hand-waves here) most specifically-sized child and the 120% child would cause the container to scroll? Or perhaps would cause the size to grow to 120% of the previously-calculated height.

Expectation aside though, perhaps that's what this issue is really about: a reminder for us to ensure there's some clear documentation about the rules of size calculation so we can know what to expect with confidence.

@davep
Copy link
Contributor Author

davep commented Dec 6, 2022

Forgot to mention:

That said, there is a solution that I think may give you your desired result. Try this:

Horizontal > * {
    min-height: 100%;
}

That didn't do what I was trying to do (it made all children as tall as the screen), but I think leaning on min-height will be handy for something else I'm trying. :-)

@willmcgugan
Copy link
Collaborator

Should be fixed in main. Making that column expand is now as simple as:

height: 100%;

@github-actions
Copy link

github-actions bot commented Dec 8, 2022

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants