5
votes

I am trying to apply the styles from the website where a stencilJS component is included ... but don't know how.

import { Component } from '@stencil/core';

@Component({
  tag: 'menu-component',
  styleUrl: 'menu-component.css',
  shadow: true
})

export class MyComponent {

 render() {
    return (
      <div>
        <h1>Hello World</h1>
        <p id="red">This is JSX!</p>
      </div>
    );
  }
}

The component is included like this:

<link rel="stylesheet" href="css/main.css" type="text/css" />
<script src='https://unpkg.com/[email protected]/dist/mycomponent.js'></script>
<my-component></my-component>

In my main.css file I have something like this:

#red{
    color: red;
}

I would like the style to be applied to the element from the stencil component. Is this possible?

3

3 Answers

3
votes

You can use css variables for this. Look at the following code samples:

index.html

<my-component style="--text-color:red;"></my-component>

my-component.css

#red {
    color: var(--text-color, black);
}

In the component's styling you assign a CSS variable as value to the text color of the class [id="red"]. In your application, you're now able to change the color by setting the value of the variable.

1
votes

Your component has a "Shadow DOM", which serves the purpose of encapsulating everything, including styles in a separate DOM, so it pretty much exists to prevent you from overriding it's styles.

Previously there were some "shadow piercing" CSS directives like /deep/ and ::shadow, but they have been deprecated and are no longer functional.

So that's pretty much how it's supposed to be.

Now for workarounds:

  • create a shared css file and include it in both your component and your application - or
  • set the style using javascript from your host application using the shadowRoot property:
var div = document.querySelector('#comp').shadowRoot.querySelector('div#red');
div.style['color'] = 'red';
1
votes

You should be able to use the :host psuedo selector in your stylesheet to apply host level styles:

:host {
    style: value
}

You could easily bring in @stencil.sass for your style sheets, link here: https://github.com/ionic-team/stencil-sass/blob/master/readme.md

This will give you greater functionality with your styles in stencil.

EDIT:

I misunderstood and now see you want to manipulate outside of the component. You could supply a <slot /> element in your web component and add specifically styled elements from outside of the web components DOM. Link here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot