This is actually quite interesting, and I’m going to have to look into it a bit closer when I have time.
I’m pretty sure this is not an issue in vaadin-select per se, but in the browser’s implementation of the ::part() selector. Unless I’m mistaken ::part() is not supposed to work on nested shadow roots at all, which is what we’re dealing with here, in that the value part is actually part of the vaadin-text-field component inside vaadin-select. So I did not expected vaadin-select::part(value) to work at all, but for some reason it does (at least in Chrome and Firefox).
This is actually quite interesting, and I’m going to have to look into it a bit closer when I have time.
I’m pretty sure this is not an issue in vaadin-select per se, but in the browser’s implementation of the ::part() selector. Unless I’m mistaken ::part() is not supposed to work on nested shadow roots at all, which is what we’re dealing with here, in that the value part is actually part of the vaadin-text-field component inside vaadin-select. So I did not expected vaadin-select::part(value) to work at all, but for some reason it does (at least in Chrome and Firefox).
The reason why vaadin-select::part(value) works for styling the text representing the selected value is that it’s actually rendered as a vaadin-item element slotted into the text-field, replacing the its normal value part, which means that it’s part of the select’s shadow dom rather than that of the text-field, thus accessible as a part of vaadin-select.
However, when no value is selected, and the placeholder is shown, the built-in value part of the internal vaadin-text-field is used instead, and because the value is in that case part of the text-field inside select, and not a direct part of the select component itself, a ::part selector on vaadin-select can’t reach it.
The reason for this arrangement is that by using a vaadin-item to show the selected value, the component can support rich content for rendering the value (e.g. icons), whereas when no value is selected, the placeholder feature of vaadin-text-field is utilized instead of re-implementing the same functionality as part of vaadin-select.
So the root problem is really the limitations of the ::part selector. The [exportparts attribute]
(https://www.w3.org/TR/css-shadow-parts-1/#exportparts-attr) will solve many of the shortcomings of ::part selectors, but we haven’t applied that to Vaadin components yet due to lacking browser support. This will be added in a future version, however, and in the meantime you can bypass the entire issue by using the @CssImport annotation with the themeFor parameter to inject any css anywhere inside a component.