TabSheet moves depending on content, and tall tab-content causes double vertical scrollbars

I have some issues with TabSheet moving and getting double scrollbars.
What I want is for the TabSheet to have the same vertical position no matter the content, and of course only have scrollbars on the inner content, not the page.

I’ve tried putting the tab content, which is a FormLayout, inside a VerticalLayout and a Scroller, but none seem to help

public class Test extends VerticalLayout {

    public Test() {


        var toolbar = new HorizontalLayout(new Span("Toolbar"));
        toolbar.getStyle().set("background-color", "azure");

        var screenLayout = new VerticalLayout();

        add(toolbar, screenLayout);

        // ----

        var topHalf = new VerticalLayout();
        topHalf.getStyle().set("background-color", "pink");

        var bottomHalf = new VerticalLayout();

        screenLayout.add(topHalf, bottomHalf);


        var tabSheet = new TabSheet();

        // First tab is a "form"

        var formLayout = new FormLayout();

        var tabOne = new Scroller(formLayout, ScrollDirection.VERTICAL);

        formLayout.setResponsiveSteps(new ResponsiveStep("0px", 1, LabelsPosition.ASIDE));
        for(int i=0; i<20; i++) {
            formLayout.addFormItem(new TextField(), "Field " + i);


        tabSheet.add("One", tabOne);
        tabSheet.add("Two", new VerticalLayout());



ok, that took a while to figure out

You’ve run into the #1 most annoying flexbox behavior, which is that the default min-height of a flex item is not 0 (as one might expect), but the height of its contents. In most cases this is harmless, but in some combinations of nested flex layouts, it causes stuff like this.

in this case it causes the bottom-layout to ignore that its top-layout sibling there also wants the same share of the available space, and insists on honoring its own default min-height, i.e. streching to accommodate its contents.

The solution is to do one of the following:

Option 1: bottomHalf.setMinHeight("0"); or
Option 2: bottomHalf.getStyle().setOverflow(Overflow.HIDDEN);

(Would be nice to solve this in the platform directly, but every solution I’ve come up with either has rather significant breaking change effects on existing applications, and one of them changes the default behavior of our layouts in other ways as well…)

Thanks for taking the time to help me on this one. I must confess that modern css is way out of my comfort zone.
I see that layout comes up again and again. Does vaadin have some guidance on it?


The tabs still jumps a bit when I switch between them, and when showing tab One, I get double scrollbars


That worked perfectly ! :slightly_smiling_face:

Does vaadin have some guidance on it?
Not at the moment. It’s a bit difficult to provide guidance as the correct place to apply that fix depends on the details of the layout in question. I intend to write something about it in the relevant docs pages, but haven’t figured out how to explain it succinctly to users with little css knowhow.

It’s one of those things that even seasoned css folks like myself get confused by.

Maybe a repository of various layouts?
Btw; It also works fine if I switch from Scroller to VerticalLayout. What’s the difference between these? Is it just a convenience thing?

Simplest solution, build simple Layouts :grimacing: without tab(sheet) it’s easier.

Scroller scrolls. VerticalLayout doesn’t, and it’s not a good idea to set overflow:auto/scroll on a VerticalLayout because then you’re combining flex-layouting and scrolling in the same container and that just leads to a mess.

In this case you probably don’t need a Scroller though, because the content wrapper in TabSheet also acts as a scroll container

I assumed VerticalLayout scrolled, but I might’ve tricked myself, since it has always been inside a tab…

Btw, the double scrollbar wasn’t gone after all :frowning_with_open_mouth:
It was fine when I maximized my window, but when I made it smaller, the double scrollbar came back

Adding Overflow.HIDDEN to the view itself solved that.

@quirky-zebra , simple is hard

I was too quick declaring victory btw… Yes, I got rid of the double scrollbars, but only because I was clipping the bottom of the form…
Moving the overflow:hidden from the view itself to the screenLayout seems to do the trick.
It also works when I wrap the topHalf and bottomHalf in a SplitLayout, which is my real objective.
Now to see if it works in the real app

Yes! For my real app, it looks like I only needed the overflow:hidden on the “screenLayout” equivalent.
Now I have no double scrollbars, and the TabSheet stays put when I switch between tabs