gnomie
gnomie

Reputation: 439

How to construct a Vaadin design that keeps min-dimensions, stretches when possible, shows browser-level scrollbars

The basic visual structure of a Vaadin application that I am maintaining consists of a centered workarea that mainly consists of a TabSheet implemented menu. The inner workarea has a fixed width (at least currently).

What I am trying to achieve is:

  1. The workarea should stretch to the bottom of the viewport but it should be no smaller, vertically, than, say, 400px.
  2. When resizing the viewport the workarea should adapt (in horizontal position and vertical size).
  3. If the viewport gets smaller than the workarea, in height or width, scrollbars should appear on the viewport (i.e. not on the workarea)
  4. On iOS or Android devices the location bar should disappear. A note on this: I noticed that, unlike "normal" web sites, Vaadin applications that have computed heights seem to eagerly size down so that browsers on mobile device see no necessity to hide the location bar for more real estate.

Here is one attempt of mine:

public class VaadinApplicationImpl1 extends Application {
  private static final long serialVersionUID = 1L;

  @Override
  public void init() {
    setTheme("sample");
    setMainWindow(new Window() {{
      setCaption("Vaadin-Layouting Sample");
      setContent(
        new CssLayout() {{
          addStyleName("workareacontainer");
          addComponent( 
            new TabSheet() {{
              addTab(
                new VerticalLayout() {{
                  setSizeFull();
                  setSpacing(true);
                  Label l = new Label("Workarea");
                  addComponent(l);
                  setExpandRatio(l, 1.0f);
                  addComponent(
                    new HorizontalLayout() {{
                      setSpacing(true);
                      addComponent(new Button("Button 1"));
                      addComponent(new Button("Button 2"));
                    }}
                  );
                }}, 
                "First"
              );
            }}
          );
        }}
      );
    }});
  }
}

where

.workareacontainer {
    min-height: 400px;
    height: 100%;
}

.workareacontainer > div {
    position: relative;
    height: 100%;
    width: 800px;
    min-width: 800px;
    margin: 0 auto;
    background-color: red;
}

.workareacontainer > div > div {
    position:absolute;
    top:5px;
    bottom:5px;
    left:5px;
    right:5px;
    background-color: green;
}

The result is a tab sheet stretched and centered as I wanted it, but not resizing when the browser is resized. Is that a limitation of the CssLayout? Can that be overcome?

Furthermore I would only get vertical scrollbars and never horizontal ones. Any idea how to fix that?

Supposedly you can get browser level scrollbars when starting with a Panel and an inner layout of setSizeUndefined(). That only seems to work if there is no 100%-stretch requirements though.

Sorry, if this is a duplicate and I was just not able to identify a good solution from other questions.

Any suggestions would be great!

Upvotes: 3

Views: 5216

Answers (1)

dinox0r
dinox0r

Reputation: 16039

As I understand your problem, you want the workarea to be dynamically centered at a percent of the browser's view dimensions, isn't? I managed to reproduce your sample and solved both the minimun-size scrollbars and the dynamic centering problem adjusting your css to the following:


Update

With the following modifications the TabSheet resizes to adjust to the container div.

public class Vaadinapplicationimpl1Application extends Application {
    private static final long serialVersionUID = 1L;

    @Override
    public void init() {
        setTheme("sample");
        setMainWindow(new Window() {{
                setCaption("Vaadin-Layouting Sample");
                setContent(new CssLayout() {{
                        addStyleName("workareacontainer");
                        setSizeFull();
                        addComponent(new TabSheet() {{
                                // If you set the width to "100%" the TabSheet will overflows the
                                // the green and red divs. Set this to 100% and add 
                                // "overflow-x:hidden" to the CSS if you don't care about
                                // the right margin  
                                setWidth("99%");

                                addTab(new VerticalLayout() {{
                                        setSpacing(true);
                                        Label l = new Label("Workarea");
                                        addComponent(l);
                                        addComponent(new HorizontalLayout() {{
                                                setSpacing(true);
                                                addComponent(new Button("Button 1"));
                                                addComponent(new Button("Button 2"));
                                            }
                                        });
                                    }
                                }, "First");
                            }
                        });
                    }
                });
            }
        });
    }
}

Also change your CSS file to the following:

.workareacontainer {
    min-height: 400px;
    height: 100%;

    /* 
    Add a minimun width to the "workareacontainer" container div, 
    the browser will use this value when the resize event takes in
    for the minimun width calculation (as it does for the height) 
    */
    min-width: 800px;
}

.workareacontainer > div {
    height: 100%;

    /* 
    Add extra padding to the right
    so the green div shows contained inside this
    */
    padding: 5px;        
    padding-right: 30px;

    /* 
    Replace this line 
       width: 800px;
    with: 
    */
       width: 90%; 
    /* 
    Here you make the workarea adaptable to the browser's width size, 
    leaving a small gap of 5% at both margins that will make your 
    workarea look "centered" 
    */

    min-width: 800px;
    margin: 0 auto;
    background-color: red;
}

.workareacontainer > div > div {
    /* 
    Remove the absolute positioning, add extra padding to the right
    so the TabSheet shows contained inside the div
    */
      padding: 5px;
    padding-right: 20px;

    height:100%;
    width:100%;

    background-color: green;
}

Tested with Google's Chromium 30.0.1599.114 and Firefox 25.0.1 (when working with CSSLayout is recommeded to test for browser compatibility).

enter image description here

enter image description here

Upvotes: 1

Related Questions