How to style the default/placeholder text of an <ion-select>
component in the Ionic framework? The default text is inside the shadow root, so therefore the HTML element has a class of "select-placeholder" it cannot be accessed via traditional CSS.
framework.com/docs/api/select#css-custom-properties
The docs for ion-select mention to use custom properties but there are only two custom properties:
--placeholder-color
--placeholder-opacity
Both work fine for updating the color and opacity, but I would really like to specifically update font-weight and font-style, and there aren't custom properties for those.
The Ionic team mentions that if there are not custom properties, to "access the shadow root of the element and apply the styles yourself in JS." But they don't expand on how to do that.
How, specifically, can I add styles in the shadow root of Ionic components where a custom property is not supplied?
TLDR; Add the part attribute to the placeholder element inside the shadow dom and then style using ::part(thePartName) in css.
Here was my solution (I didn't love it). And by the way I am on Ionic 4.
So ultimately, the problem with styling elements inside the shadow DOM of certain ionic components, is that traditional CSS selectors from an outside* style stylesheet have zero affect on elements inside the shadow dom. This is one of the main points of the shadow DOM: to create encapsulated components where CSS doesn't leak in and doesn't leak out. There are two exceptions that I'm aware of:
1 - Use one of Ionic's CSS variables (aka CSS Custom Properties). These are limited to --placeholder-color
in Ionic 4 and adding --placeholder-opacity
in ionic 5. I happened to be on ionic 4 so i couldn't take advantage of the opacity variable. However to use these custom properties you would do so like this:
ion-select {
--placeholder-color: 'hotpink';
}
I needed to style font-weight, font-style, and opacity so I needed another solution other than CSS Custom Properties.
::part()
pseudo element.html that lives in the shadow dom provided by Ionic:
<div part="SorryIonicDoesntAddThisAttribute" class="select-text select-placeholder>my text</div>
Your css:
::part(thePartName) {
opacity: 1;
font-style: italic;
font-weight: normal;
}
If the "part" HTML attribute exists on the element inside the shadow dom its like a portal into the shadow dom.
However in Ionic 4, Ionic doesn't add the part attribute to the ion-select component's elements in the shadow dom.
I used javascript to add it (inspired by @ivanreutkers comment) to add the part attribute so I could thus style it in CSS.
document.getElementById("the-id").shadowRoot.querySelector(".select-placeholder").setAttribute("part", "myPartName");
*Outside, meaning the stylesheet for my website/application and not the specific styles provided by Ionic that live inside the web component.