Vaadin-combo-box: Styling combo box items

Created on 28 Mar 2019  ·  8Comments  ·  Source: vaadin/vaadin-combo-box

I would like to use external styles in combo box items but this doesn't work since the items are within the shadow dom.

The concrete scenario is to show flag icons in a language selection combo box using flag-icon-css. For the flags to be shown, a span tag with some CSS classes from the flag-icon-css styles need to be applied but they are not picked up because of the shadow DOM. Shouldn't a combo box item be "slot" as in ListBox? For ListBox items it works fine to display the flag icons.

I have opened a question on stackoverflow recently, see https://stackoverflow.com/questions/55170886 for details.

All 8 comments

Is there a workaround available?

Because external styles don't penetrate into the shadow DOM, you need to import the CSS file inside the shadow DOM.

Maybe this StackOverflow thread helps.

Based on the second answer in that thread, <link rel="stylesheet"> should work inside shadow DOM. So something like this could work in your ComponentRenderer:

Element link = new Element("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("href", "./frontend/bower_components/flag-icon-css/css/flag-icon.min.css");
item.getElement().appendChild(link);

...or using @import suggested in the first answer:

Element style = new Element("style");
style.setProperty("innerHTML", "@import \"./frontend/bower_components/flag-icon-css/css/flag-icon.min.css\"");
item.getElement().appendChild(style);

I haven't properly tested these snippets myself though.

@steffen-harbich-itc, did you manage to make it work by using one of those approaches or some other way? I'd be interested to hear. :)

I tried your second suggestion and it worked. I didn't try the first approach. However, I tried to add the "@import ..." into my shared-styles.html in

 <dom-module id="my-combo-box-theme" theme-for="vaadin-combo-box">
   <template>
     <style>...

but that didn't work.

So a workaround is available for the issue but IMO there is still something inconsistent with the bahavior in contrast to ListItems.

Good to hear that at least one approach works!

About your shared-styles approach: You should set theme-for="vaadin-combo-box-item", since that is the element into which the styles should be injected. However, it might still not work with ComponentRenderer, because this renderer creates and additional web component (and thus shadow-root), between the vaadin-combo-box-item and your added components.

The stylability of the items and whether or not they should be inside shadow DOM concerns the web component (this repository includes just the Java wrapper for it), so I will move this ticket to the vaadin-combo-box repository.

A correct way to handle this would be to create a dom-module like this:

<dom-module id="my-item-css" theme-for="vaadin-combo-box-item">
  <template>
    <style>
    /* styles from flag-icons.css */
    </style>
  </template>
</dom-module>

Using @import is not guaranteed to work and is not recommended.

There is no easy fix for the issue, and it's not specific to vaadin-combo-box component.
We should document limitations of shadow DOM & external CSS in the new docs site.

Otherwise there is nothing for us to do here. So let me close this as it's not a bug.

I would still expect that combo box items shouldn't be placed within the shadow DOM but in separate slots.

combo box items shouldn't be placed within the shadow DOM but in separate slots.

We can consider this as a potential breaking change in the next major release.

Exposing the items needs to be done in a way that they work with the virtual scroller component (which will be definitely changed from iron-list to something else - has to be decided).

Was this page helpful?
0 / 5 - 0 ratings