Textualize / textual

The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.
https://textual.textualize.io/
MIT License
25.57k stars 786 forks source link

Are inherited multi-part styles working as intended? #3945

Open davep opened 10 months ago

davep commented 10 months ago

This is one I run into now and again with my own apps, and I keep meaning to check if this is intended behaviour, or if this is a bug. Consider this code:

from textual.app import App, ComposeResult
from textual.containers import Container
from textual.widgets import Label

class LotsOfPadding(Container):

    DEFAULT_CSS = """
    LotsOfPadding {
        border: dashed blue;
        padding: 7;
    }
    """

class NoLeftPadding(LotsOfPadding):

    DEFAULT_CSS = """
    NoLeftPadding {
        padding-left: 0;
    }
    """

class NoRightPadding(LotsOfPadding):

    DEFAULT_CSS = """
    NoRightPadding {
        padding-right: 0;
    }
    """

class PartialStylingApp(App[None]):

    CSS = """
    Label {
        width: 1fr;
        height: 1fr;
        background: red;
        border: solid white;
    }
    """

    def compose(self) -> ComposeResult:
        yield LotsOfPadding(Label("This should be 10 all round"))
        yield NoLeftPadding(Label("This should have no padding to the left"))
        yield NoRightPadding(Label("This should have no padding to the right"))

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

The idea is that there's a container that has a padding value, which is inherited by any container that inherits from it. There are a couple of containers that do inherit from it, and they seek to make the padding a little more specific by use of padding-left and padding-right (in each case removing the padding on one particular side). It feels like a reasonable expectation that padding-left (for example) means "whatever all the current padding-* values are, with this applied on top.

In other words, my expectation would be that the above code ends up looking like this:

Screenshot 2024-01-02 at 15 34 49

what actually happens though is I get this:

Screenshot 2024-01-02 at 15 35 22

with the padding-left and padding-right removed from the child containers, we can see that the padding is inherited from the parent:

Screenshot 2024-01-02 at 15 36 04

so it would appear that if you override (for example) padding-left of a widget that inherits from a widget that has set padding, all of the individual padding values get reset (presumably because of the specificity of DEFAULT_CSS?).

So, initially at least, this issue asks: is this a reasonable expectation and as such is a change needed here, or is this intended behaviour?

rodrigogiraoserrao commented 10 months ago

For what is worth, my expectation matches yours.