Min/Max columns on auto-responsive form layout may overlap

I’ve blurred out some information in the screenshots, so please disregard that.
What you’re seeing is a form layout with autoResponsive=true and responsiveSteps configured to expand columns. Inside this form layout, there’s a form row that contains two nested form layouts — both also set to be auto-responsive. Additionally, I’ve defined minColumns and maxColumns for them, as I want the layout to respect these constraints rather than adjust automatically based on available space.
The issue arises when there isn’t enough space: the left container (which spans more columns) causes the grid to wrap using repeat, and the content starts to overlap into the right container.
Is there a way to prevent this overlap — ideally by forcing the second container to start after the space taken by the container on the left?

Hi,

Is there a specific reason why you want to nest two FormLayouts inside another one? FormLayout is better suitable to be used with form fields. We could probably use a HorizontalLayout to wrap both FormLayout instances in this case.

The new front end is not “handmade” since there are a lot of views that need to be migrated.
There is an engine that builds the new front end based on the information from the old one, and that is how we’ve done the “translation” of the legacy containers. (Form layouts containing form layouts is a possibility)

I would strongly encourage you to try to refactor the “translation” to avoid that, or implement your own layout instead of using FormLayout, which is definitely not intended to host other FormLayouts. I just don’t see how you would not end up with various issues by that nesting, even if you managed to solve this one.

I understand your concerns, and as an owner of the tech stack they are most probably valid. What we missed in our original implementation is how to arrange/align the containers(form layouts) which hold the fields around the UI, so one thing we’ve done is making the most use of the auto responsiveness and form layouts, and they seem to do a great job. Can you give more hints what may go wrong, and if we have to change our implementation, any tips or design approaches we may use, on a high level of course. Thanks!

Sorry, not really, as we have never even thought about nesting them.
I just think you’d be better off with your own css grid based containers if you need nesting.

Possibly look into container queries to help make things responsive in just the right way?

“Own Css grid based containers”, so this is some kind of a custom solution with CSS and grid, and not something I can use Vaadin for? Because this is the only grid like structure I know of, form layout. Unfortunately, I do not know how to do a proper custom css solution since I am not a front end developer and may require additional research.

Sorry, I am not sure what you mean by container queries.

Yes, that would require building the CSS yourself, unfortunately.

But so I went ahead and tried putting two FormLayouts inside another FormLayout, and it actually works surprisingly well. A lucky coincidence I suppose.

Maybe the problem is your configuration.

How are you configuring the outer and inner formlayouts? What are the minColumns set to? And I now realized you mentioned both autoResponsive and responsiveSteps, which are mutually exclusive modes: setting one disables the other.

responsiveSteps seems like a typo on my side, when I was redacting the post. I am not using responsive steps. What I meant is “formLayout with auto responsive true and that it the parent of the two layouts is configured to expand columns”.

I am pretty sure the problem is in my configuration. It really does work surprisingly well, though.

So the outer form layout is with expandColumns set as True, autoResponsive set as true.
The inner form layouts have auto responsive as well, and in this specific case the minColumns is set to the number of columns of the row, so that the UI is generated the same way as in the old front end, triyng to achieve the same number of columns on one row, and in the same place.

What I observe is that the most outer form layout splits the screen in two, since in the old front end it is done like this,
but the number of columns and their width multiplied by the “repeat” statement in css exceeds the middle of the screen and starts overlapping on the right part. What I was wondering is can I make the containers bump one another and not overlap.
The other solution I did is just to remove the min and max columns I set, this way, the UI is not 100% the same, but around 95%, since there are a few places where the columns are rearranged by the Vaadin autoresponsiveness, but I gain full responsiveness of the app. I guess both solutions have upsides and downsides

Right, so FormLayout always uses a specific column width. When you place fields into it, as intended, they would normally shrink to fit that, and only when the layout’s width can no longer accommodate X number of columns of that width will it collapse into X-1 columns.

The way you’re using it, however, doesn’t fit that model at all.

I suppose you could kind of make it work by setting the column width (setColumWidth) on the outer formlayout to the width of the wider of the two columns? But then both sides will always take the same amount of space.

Or you could setColSpan to each inner FormLayout to whatever number of columns they have (making sure to set colspan to 1 on the actual fields). I think you might need to also setMaxColumns on the outer layout to the sum of the two, because it defaults to something reasonable (which this is not).

That seems to kind of work:

        var outer = new FormLayout();
        outer.setAutoResponsive(true);
        outer.setWidthFull();

        var left = new FormLayout();
        left.setAutoResponsive(true);
        var leftRow = left.addFormRow();
        left.setMinColumns(6);

        var right = new FormLayout();
        right.setAutoResponsive(true);
        var rightRow = right.addFormRow();
        right.setMinColumns(6);

        for (int i=0; i<6; i++) {
            leftRow.add(new TextField("Foo"), 1);
            rightRow.add(new TextField("Bar"), 1);
        }

        var outerRow = outer.addFormRow();
        outerRow.add(left, 6);
        outerRow.add(right, 6);
        outer.setMaxColumns(12);

        add(outer);

OR, you could consider not using FormLayout at all, and instead doing this with HorizontalLayouts, where the outer one has setWrap(true), since you’re not really benefitting from the FormLayout’s features much here.