nicegui icon indicating copy to clipboard operation
nicegui copied to clipboard

ui.expansion flex styling makes item caption jump

Open platinops opened this issue 9 months ago • 4 comments

First Check

  • [x] I added a very descriptive title here.
  • [x] This is not a Q&A. I am sure something is wrong with NiceGUI or its documentation.
  • [x] I used the GitHub search to find a similar issue and came up empty.

Example Code

from nicegui import ui

with ui.element("div").classes("q-pa-md").style("width: 350px"):
    with ui.list().style("background-color:#f1948a"):
        with ui.expansion("Expansion (NiceGUI)", caption="Caption"):
            with ui.item():
                with ui.item_section():
                    ui.item_label("Item")
                    ui.item_label("Caption").props("caption")

    with ui.list().style("background-color:#f8c471"):
        with ui.expansion("Expansion (add ui.column)", caption="Caption"):
            with ui.item():
                with ui.column():
                    with ui.item_section():
                        ui.item_label("Item")
                        ui.item_label("Caption").props("caption")

    with ui.list().style("background-color:#85c1e9"):
        with ui.expansion(
            "Expansion (remove .nicegui-expansion)", caption="Caption"
        ).classes(remove="nicegui-expansion"):
            with ui.item():
                with ui.item_section():
                    ui.item_label("Item")
                    ui.item_label("Caption").props("caption")

    with ui.element("q-list").style("background-color:#7dcea0"):
        with ui.element("q-expansion-item").props(
            "label='Expansion (Quasar)' caption=Caption"
        ):
            with ui.element("q-item"):
                with ui.element("q-item-section"):
                    with ui.element("q-item-label"):
                        ui.label("Item")
                    with ui.element("q-item-label").props("caption"):
                        ui.label("Caption")

ui.run(show=False)

Description

4 implementations of ui.expansion containing an item with a label and caption:

  1. NiceGUI default: label and caption are initially not properly aligned - while expanding the caption jumps below the label
  2. Add ui.column: label and caption appear below each other, but still stutter when opening
  3. Remove nicegui-expansion class: same behaviour as Quasar (see below), no jump/stutter when opening expansion
  4. Raw Quasar implementation: no jump/stutter

I came across #1796, but am not sure whether this issue was overlooked or a direct consequence of this PR.

Image

NiceGUI Version

2.20.0

Python Version

3.11.9

Browser

Firefox

Operating System

Windows

Additional Context

No response

platinops avatar Jul 01 '25 08:07 platinops

Thanks for reporting this issue, @platinops! I can definitely confirm the bug with this minimum reproduction:

with ui.expansion('Expansion'):
    with ui.item():
        with ui.item_section():
            ui.item_label('Line 1')
            ui.item_label('Line 2')

At first sight I have no idea what is going on. Any help with debugging this layout glitch is very welcome!

falkoschindler avatar Jul 01 '25 10:07 falkoschindler

Hi @falkoschindler, thanks for the quick feedback!

I noticed that during the expansion, the style of one element gets changed by Quasar through a JS event.

This is the style that makes both items appear next to each other:

Image

overflow-y: hidden; height: 80px; transition: height 300ms cubic-bezier(0.25, 0.8, 0.5, 1);

I am by no means a css/js expert, but I guess this style somehow clashes with the .nicegui-expansion class, since when I remove that class, the issue no longer occurs (= blue case from my initial post).

platinops avatar Jul 02 '25 07:07 platinops

Interesting! .nicegui-expansion sets display: flex. If I remove this style property, the layout is fixed. But how does display: flex clash with any of overflow-y, height, or transition?

After some investigation, I wonder if it's really a bug or rather a usage problem. The expansion content slowly grows to its full height. This is how QExpansion works. If the content doesn't define the desired behavior for small heights, its children wrap and overflow by default. Here's an example turning this off:

with ui.expansion('Expansion'):
    with ui.item():
        with ui.item_section().classes('flex-nowrap overflow-hidden'):
            ui.item_label('Line 1')
            ui.item_label('Line 2')

But you could argue that NiceGUI's ui.expansion should behave more nicely. The content should be slowly revealed, without changing its height. Maybe we can wrap it in another container acting as some kind of adapter.

falkoschindler avatar Jul 02 '25 07:07 falkoschindler

.nicegui-expansion sets display: flex. If I remove this style property, the layout is fixed. Yes, hence the title of this issue 🤓 Apologies for not pointing this out explicitly in my post.

I would not classify this as a usage problem if it does not occur in Quasar though.

If NiceGUI's styling deviates from Quasar, I believe it should only do this to make the user's life easier, not more complex (e.g. requiring the user to add ui.column like in my orange example).

So I do hope this can get fixed in the source rather than leaving it to the user.

platinops avatar Jul 02 '25 08:07 platinops