Hiding scrollbars in chrome/safari

Hi everybody,
I’ve recently started developing a webapp using vaadin for an Italian bank, and after solving a couple of issues related to the Reverse Proxy they’re using by digging into vaadin sources (kudos for your great documentation, btw! :D) I just started designing the UI.

I’ve stumbled into a minor problem that I can’t get away with: I have a Panel (with style set with
hPanel.setStyleName(Reindeer.PANEL_LIGHT)
) with a multi-line TextField packed inside a HorizontalLayout, the width of which extends over the width of the page. Hence, I need a horizontal scrollbar.

My problem is that I don’t want the Panel to have a vertical scrollbar on its side, because the TextField must have its own and having two vertical scrollbars side by side is plain ugly.

I tried to set a custom CSS style for the panel (and the horizontal layout), a simple:

.novscroll {
	overflow-y: hidden;
	overflow-x: auto;
}

and I also tried to win over the inherited reindeer styles by putting this as well:

.v-panel-content.v-panel-content-light.v-panel-content-novscroll {
	overflow-y: hidden;
	overflow-x: auto;
}

But, while all components have the style I set with the usual
addStyle(“novscroll”)
the inner content of the panel still has this style (I use chrome’s Inspect Element):

<div class="v-panel-content v-panel-content-light v-panel-content-novscroll" style="position: relative; height: 300px; overflow-x: auto; overflow-y: auto; ">

and as you can see the
overflow-y: auto
is still there, listed by chrome as “Style Attribute”, with my style coming second (and thus overridden). If I uncheck the checkbox with
overflow-y: auto
I get exactly what I want.

Internet Explorer 6+ and Firefox display the page correctly, so this is not an urgent issue at all (the bank’s “official” browser is IE), but I’d like to know whether the style can be overridden or a custom component would be required to accomplish what I want.

Thanks!

Hi Michele, and welcome to the forum!

One option is to use the !important modifier for the CSS. That will always win over any other declarations, even inline styles. But it’s considered bad practice, so you might want to look for other solutions.

.v-panel-content-novscroll {
	overflow-y: hidden !important;
	overflow-x: auto !important;
}

Could you post a test case here, so we could try it out, what the problem might be? And didn’t completely understand what you were trying to accomplish, where scrollbars were needed and what component should overflow the Panel (is the Panel as wide as the page, or smaller?).

Thanks Jouni!
The workaround works well, but I agree with you… it may not look as the best way to write CSS :smug:

I’ve added a simple war containing a little test case.
The panel looks the way it’s supposed to be when you launch the app as-is. In order to see the vertical scrollbar that I don’t like, just delete the
!important
tags from the styles.css file of my theme.

The Panel as you’ll see from the code (that I’m posting here as well) is as wide as the tabsheet it’s in.

package com.example.scrollbardemo;

import com.vaadin.Application;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Reindeer;

public class ScrollbardemoApplication extends Application {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void init() {
		setTheme("scrollbar-theme");
		Window mainWindow = new Window("Scrollbardemo Application");
		TabSheet tabSheet = new TabSheet();

		// just to have more than one tab...
		final VerticalLayout barLayout = new VerticalLayout();
		barLayout.setHeight("450px");
		barLayout.addComponent(new Label("Hello Vaadin user!"));

		// here's the panel we're talking about
		final Panel fooPanel = new Panel();
		fooPanel.setWidth("100%");
		final Panel hPanel = new Panel();
		hPanel.setStyleName(Reindeer.PANEL_LIGHT);
		hPanel.setWidth("100%");
		/*
		 * set a fixed height, so that the horizontal scrollbar is always
		 * displayed (commenting the following line results on the h. scrollbar
		 * being concealed "under" the parent panel)
		 */
		hPanel.setHeight("200px");
		HorizontalLayout hLayout = new HorizontalLayout();
		// here's the text area that must contain up to 320 chars
		TextField longField = new TextField();
		// magic number to fit 320 chars with the font I've chosen
		longField.setColumns(188);
		longField.addStyleName("truetype");
		longField.setWordwrap(false);
		longField.setHeight("100%");
		longField.setInputPrompt("Here the user can write rows of fixed-length data"
				+ " and they should be able to visually compare fields on-the-fly\n"
				+ "That's why we have this odd-looking very long text area containing "
				+ "approximately up to 320 chars.\n"
				+ "Try adding some lines to see the text area's scrollbar appear at "
				+ "the right end of the page");

		hLayout.setHeight("100%");
		hLayout.addComponent(longField);

		hPanel.setContent(hLayout);
		hPanel.addStyleName("novscroll");
		hLayout.addStyleName("novscroll");

		fooPanel.addComponent(hPanel);
		fooPanel.addComponent(new Label("Here goes other stuff..."));

		tabSheet.addTab(fooPanel, "Foo", new ThemeResource("../runo/icons/16/globe.png"));
		tabSheet.addTab(barLayout, "Bar", new ThemeResource("../runo/icons/16/folder.png"));

		mainWindow.addComponent(tabSheet);
		setMainWindow(mainWindow);
	}

}

Thanks again!

[Edit: here’s my styles.css]

@import "../reindeer/styles.css";
div .v-textfield-truetype,
div .v-textarea-truetype {
	font-family: monospace, 'Courier new';
}
.v-textarea {
	resize: none;
}
.novscroll {
	overflow-y: hidden;
	overflow-x: auto;
}
.v-panel-content.v-panel-content-light.v-panel-content-novscroll {
	overflow-y: hidden !important;
	overflow-x: auto;
}

11257.war (5.39 MB)

Thanks for the test case, wasn’t exactly a very regular type of layout :slight_smile:

I reduced it a bit, removed the theme (not needed to reproduce the error):

public void init() {
		Window mainWindow = new Window("Scrollbardemo Application");
		setMainWindow(mainWindow);
		
		TabSheet tabSheet = new TabSheet();
		mainWindow.addComponent(tabSheet);

		VerticalLayout root = new VerticalLayout();
		tabSheet.addTab(root, "TextField Overflow", null);
		
		Panel scroll = new Panel();
		scroll.setWidth("100%");
		scroll.setStyleName(Reindeer.PANEL_LIGHT);
		root.addComponent(scroll);
		
		VerticalLayout panelContent = new VerticalLayout();
		panelContent.setSizeUndefined();
		scroll.setContent(panelContent);
		
		TextField longField = new TextField();
		longField.setColumns(188);
		longField.setHeight("100px");
		panelContent.addComponent(longField);

		root.addComponent(new Label("Here goes other stuff..."));

	}

In my opinion, this looks like yet-another WebKit overflow:auto bug. We’ve got a few fixes already for WebKit’s overly-aggressive optimizations with scrollbars, and I bet this is one of them (either our fault, or WebKit’s, hard to say).

The symptom is that the horizontal scrollbar underneath the textfield (the Panel’s scrollbar) doesn’t appear in WebKit. I was able to get it visible by running the internal “layout function” two times (type
javascript:vaadin.forceLayout()
in the address bar twice), so it might be fixable in our framework.

You could create a ticket for this issue, but the CSS !important workaround is the best I can offer at this point.

Ok, the
!important
hack combined with a very specific css class is enough for such a minor issue, in my opinion :wink:

Thanks!