Why doesn't background transparent on hover work?

.menu-bar::part(menu-bar-button) {
    background-color: transparent;
}

.menu-bar::part(menu-bar-button):hover {
    background-color: ?;
}

I’m able to change the button background to transparent using the value “transparent”. Setting the background on hover to transparent does nothing. Setting the alpha to zero (#00000000) should be transparent as well, but that doesn’t do anything either. Nor do any of the examples given in the State attributes section of the vaadin-themable-mixin documentation seem to work. Using !important doesn’t make it work either. However, setting the background to any color other than the background color of the navbar - hsl(210, 20%, 96%), which is not even a color that’s listed in the Lumo documentation - makes the background that color on hover. Setting the background color on hover to hsl(210, 20%, 96%) is ignored and the default color is displayed instead.

Hi Brian,

If you want to theme vaadin-menu-bar-button you can do the following:

  1. Import styles (Java)
@CssImport(value = "./styles/components/menu-bar-button.css", themeFor = "vaadin-menu-bar-button")
  1. menu-bar-button.css
:host {
  background-color: transparent;
}
:host(:hover)::before {
  opacity: 0;
}

Thanks Joacim

That works, but shouldn’t @CssImport(value = "./styles/menu-item.css, themeFor = "vaadin-context-menu-item") work as well using the same CSS code?

Hi Brian,

Unfortunately they’re implemented differently (it annoys me too) so in that case you need to do the following:

  1. Import styles (Java)
@CssImport(value = "./styles/context-menu-list-box.css", themeFor = "vaadin-context-menu-list-box")
  1. context-menu-list-box.css
[part="items"]
 ::slotted(.vaadin-menu-item:hover:not([disabled]
)),
[part="items"]
 ::slotted(.vaadin-menu-item[expanded]
:not([disabled]
)) {
  background-color: ...;
}

Source: https://github.com/vaadin/vaadin-context-menu/blob/master/theme/lumo/vaadin-context-menu-styles.html#L70.

Hi Joacim

Thanks for all the help, and sorry for all the questions. I understand the basics of CSS, but it almost seems that most of the basic rules of CSS don’t apply to Vaadin. The CSS seems extremely convoluted.

So far, I have a menu bar with 2 buttons and one of the buttons has a sub-menu. The first code sample that you posted removes the background color from both buttons. It also removes the hover background color on the button with no sub-menu, but doesn’t remove the background color on hover on the other button. The second code sample that you posted removed the background color on hover for all of the sub-menu items. Given the fact that both menu buttons are elements of type vaadin-menu-bar-button, why does the CSS behave differently on the 2 buttons?

Hi Brian,

I must’ve misunderstood what you were trying to accomplish. I’ll try to illustrate with an example, taken from https://vaadin.com/components/vaadin-menu-bar/java-examples:

MenuBar menuBar = new MenuBar();
Text selected = new Text("");
Div message = new Div(new Text("Selected: "), selected);

MenuItem project = menuBar.addItem("Project");
MenuItem account = menuBar.addItem("Account");
menuBar.addItem("Sign Out", e -> selected.setText("Sign Out"));

SubMenu projectSubMenu = project.getSubMenu();
MenuItem users = projectSubMenu.addItem("Users");
MenuItem billing = projectSubMenu.addItem("Billing");

SubMenu usersSubMenu = users.getSubMenu();
usersSubMenu.addItem("List", e -> selected.setText("List"));
usersSubMenu.addItem("Add", e -> selected.setText("Add"));

SubMenu billingSubMenu = billing.getSubMenu();
billingSubMenu.addItem("Invoices", e -> selected.setText("Invoices"));
billingSubMenu.addItem("Balance Events",
        e -> selected.setText("Balance Events"));

account.getSubMenu().addItem("Edit Profile",
        e -> selected.setText("Edit Profile"));
account.getSubMenu().addItem("Privacy Settings",
        e -> selected.setText("Privacy Settings"));

By default we get what is shown in ex1.png.

Now, the first requirement seems to be a transparent background. That light gray background you see exists on the vaadin-menu-bar-button element (as opposed to the vaadin-context-menu-item element). To change it we need to import our styles using @CssImport (if you’re using Java) and then of course write the CSS we want applied.

  1. Import styles;
@CssImport(value = "./styles/components/menu-bar-button.css", themeFor = "vaadin-menu-bar-button")
  1. menu-bar-button.css;
:host {
  background-color: transparent;
}

The result is shown in ex2.png.

The hover style for vaadin-menu-bar-button is done in :host(:hover)::before. You can make it transparent by setting the opacity to 0 or by changing the background-color to transparent. If you want to use a solid color then set opacity to 1 and background-color to whatever color you wish.

:host(:hover)::before {
  // Transparent (alt 1)
  opacity: 0;
  // Transparent (alt 2)
  background-color: transparent;
  // Hover color
  opacity: 1;
  background-color: <color-value>;
}

Hopefully that helps.
18193092.png
18193095.png

Brian Sheely:
That works, but shouldn’t @CssImport(value = "./styles/menu-item.css, themeFor = "vaadin-context-menu-item") work as well using the same CSS code?

No, unfortunately not, since the background-color is not set for that element.

Brian Sheely:
Thanks for all the help, and sorry for all the questions.

No worries, happy to try to help.

I understand the basics of CSS, but it almost seems that most of the basic rules of CSS don’t apply to Vaadin. The CSS seems extremely convoluted.

It does apply, but the difficulty is usually finding the right component to theme. We’re aware that it’s an issue for devs, and we’re working on improving the documentation (and other tools) to help make theming easier.

So far, I have a menu bar with 2 buttons and one of the buttons has a sub-menu. The first code sample that you posted removes the background color from both buttons. It also removes the hover background color on the button with no sub-menu, but doesn’t remove the background color on hover on the other button.

This should make the background transparent by default and on hover as well:

@CssImport(value = "./styles/menu-bar-button.css", themeFor = "vaadin-menu-bar-button")
:host {
  background-color: transparent;
}
:host(:hover)::before {
  opacity: 0;
}

It won’t affect items in the overlay/popup as they are not vaadin-menu-bar-button elements.

The second code sample that you posted removed the background color on hover for all of the sub-menu items. Given the fact that both menu buttons are elements of type vaadin-menu-bar-button, why does the CSS behave differently on the 2 buttons?

The items you see in the overlay/popup are vaadin-context-menu-item elements. Their hover style is actually set by vaadin-context-menu-list-box. Source code: https://github.com/vaadin/vaadin-context-menu/blob/master/theme/lumo/vaadin-context-menu-styles.html#L70.

So, if you wish to change that you need to do the following:

@CssImport(value = "./styles/context-menu-list-box.css", themeFor = "vaadin-context-menu-list-box")

context-menu-list-box.css:

[part="items"]
 ::slotted(.vaadin-menu-item:hover:not([disabled]
)),
[part="items"]
 ::slotted(.vaadin-menu-item[expanded]
:not([disabled]
)) {
  background-color: ...;
}

Hi Joacim

Thanks for all the help, and sorry for all the questions. I understand the basics of CSS, but it almost seems that most of the basic rules of CSS don’t apply to Vaadin. The CSS seems extremely convoluted.

So far, I have a menu bar with 2 buttons and one of the buttons has a sub-menu. The first code sample that you posted removes the background color from both buttons. It also removes the hover background color on the button with no sub-menu, but doesn’t remove the background color on hover on the other button. The second code sample that you posted removed the background color on hover for all of the sub-menu items. Given the fact that both menu buttons are elements of type vaadin-menu-bar-button, why does the CSS behave differently on the 2 buttons?

Joacim

That’s exactly what I have currently. The vaadin-menu-bar-button that does not have a subMenu has no background color either on hover or not hover. None of the vaadin-menu-context-item have a background color either on hover or not hover. The problem is that the vaadin-menu-bar-button that has a subMenu does have a background color on hover. Why would 1 vaadin-menu-bar-button not have a background color on hover and a different vaadin-menu-bar-button, in the same menuBar, have a background color on hover? Shouldn’t the CSS file apply to both buttons?

Ah! I see. I wasn’t able to reproduce that issue at first. Clicking the MenuBar and then hovering an item reproduced it.

That’s :host([expanded] ). You can set background-color: transparent; for that as well.

menu-bar-button.css

:host {
  background-color: transparent;
}
:host(:hover)::before {
  opacity: 0;
}
:host([expanded]
) {
  background-color: transparent;
}

Hi,

i’ve also tried to change styles of one special menu-bar in my app. After some research it ended with this:

(custom theme name)

var menuBar = new MenuBar();
menuBar.addThemeVariants(MenuBarVariant.LUMO_TERTIARY);
menuBar.addThemeName("top-level-menu");

My first approach was to import an extra css-file for the different components used by a vaadin-menu-bar (four times).
(Custom theme name attribute “top-level-menu” is propagated to all inner components)

@CssImport(value = "./styles/views/XYZ.css"m themeFor="vaadin-menu-bar")
@CssImport(value = "./styles/views/XYZ.css"m themeFor="vaadin-context-menu-overlay")
@CssImport(value = "./styles/views/XYZ.css"m themeFor="vaadin-context-menu-item")
@CssImport(value = "./styles/views/XYZ.css"m themeFor="vaadin-context-menu-list-box")

XYZ.css:

:host([theme~="top-level-menu"]
) [part="container"]
 {
                overflow: unset;
            }
            
            :host([theme~="top-level-menu"]
) [part="content"]
 {
                background-color: inherit;
            }
            
            :host(vaadin-context-menu-overlay[theme~="top-level-menu"]
) [part="overlay"]
 {
                background-color: black;
            }
            
            :host(vaadin-context-menu-item[theme~="top-level-menu"]
) [part=content]
 {
                color: var(--lumo-text-color);
            }
            
            :host(vaadin-context-menu-list-box[theme~="top-level-menu"]
) [part="items"]
 ::slotted(.vaadin-menu-item:hover:not([disabled]
)) {
                background-color: var(--lumo-base-color);
            }        

I felt a bit unhappy with importing same file four times, so i decided to move to my “shared-styles.js”. There it is possible to assign a style-block to many “themeFor”-names:


<dom-module id="menu-bar-style" theme-for="vaadin-menu-bar vaadin-context-menu-overlay vaadin-context-menu-item vaadin-context-menu-list-box">
    <template>
        <style>
            :host([theme~="top-level-menu"]
) [part="container"]
 {
                overflow: unset;
            }
            
            :host([theme~="top-level-menu"]
) [part="content"]
 {
                background-color: inherit;
            }
            
            :host(vaadin-context-menu-overlay[theme~="top-level-menu"]
) [part="overlay"]
 {
                background-color: black;
            }
            
            :host(vaadin-context-menu-item[theme~="top-level-menu"]
) [part=content]
 {
                color: var(--lumo-text-color);
            }
            
            :host(vaadin-context-menu-list-box[theme~="top-level-menu"]
) [part="items"]
 ::slotted(.vaadin-menu-item:hover:not([disabled]
)) {
                background-color: var(--lumo-base-color);
            }        
        </style>
    </template>
</dom-module>