Stencil: CSS variables not recognized

Created on 13 Apr 2019  路  13Comments  路  Source: ionic-team/stencil


Following implementation instructions from https://stenciljs.com/ for styles does not render the correct result when using CSS Variables for Shadow DOM styling.

Stencil version:

 @stencil/core@<0.18.1>

I'm submitting a:

[X ] bug report

Current behavior:
The CSS Variables definition in Stenciljs components style does not get recognized.

Expected behavior:
The CSS Variables on global bases would be substituted for Stenciljs components.

Steps to reproduce:
Following instructions for global use of CSS Variables.

Related code:

### stencil-config-ts

import { Config } from "@stencil/core";

export const config: Config = {
namespace: "mycomponent",
globalStyle: "src/globals/variables.css",
outputTargets: [
{
type: "dist"
},
{
type: "www",
serviceWorker: null
}
]
};

### src/globals/variables.css

:root {
--button-color: #7892e7;
--button-ease-out-color: #ec0f0f;
--button-font-color: #760fec;
}

### my-button.tsx

import { Component, Prop } from "@stencil/core";

@Component({
tag: "my-button",
styleUrl: "./my-button.css",
shadow: true
})
export class MyButton {
@Prop({ reflectToAttr: true }) label: string;
@Prop() disabled: boolean;

render() {
return (




);
}
}

### my-button.css

.button {
background-color: var(--button-color, #4caf50);
border: none;
color: var(--button-font-color, black);
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}

.button:hover {
transition: 0.3s ease-out;
background-color: var(--button-ease-out-color, cyan);
}

.ripple {
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.ripple:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
background-position: 50%;
transform: scale(10, 10);
opacity: 0;
left: 0;
pointer-events: none;
background-image: radial-gradient(circle, #000 10%, transparent 10.01%);
background-repeat: no-repeat;
transition: transform 0.5s, opacity 1s;
}
.ripple:active:after {
transform: scale(0, 0);
opacity: 0.2;
transition: 0s;
}

Other information:
none

triage

Most helpful comment

@willycamargo This was driving me insane too. @CookieCookson had a great solution that worked for me.

Stencil.config.js

...
sass({
  injectGlobalPaths: [
    "src/global/styles/app.scss"
  ]
})
...

I had to use SASS but sure look it - a fix is a fix :)

All 13 comments

Similar issue, seems pretty major and it's not just related to IE11 (as I just tried this on Chrome).
I've done nearly nothing beyond the default project setup and attempted to use the defined path of globals/variables.css to define the :root styles. These styles are not applied to the components with or without the shadow: true attribute.

A repo to reproduce:
https://github.com/Kikketer/workgrid-components/blob/master/src/global/variables.css

[Update] - this is fixed when I added the stylesheet to the index file:
<link rel="stylesheet" href="/build/workgrid-components.css">

Met the similar issue here on my Chrome.
Adding stylesheet to the index.html mentioned by @Kikketer works for me but I don't think it make sense to do this in production?

I seem to still have this issue. I'm on "@stencil/core": "^1.0.7". It seems that var(--cssVariable) will get compiled correctly on html elements, but don't compile correctly when using var() through a class

How is this fixed? I am still seeing the same issues.

@manucorporat do you have an example?

How is this fixed? I am still seeing the same issues.

@manucorporat do you have an example?

1. You need to create a CSS stylesheet with the global config, including the variables.

my-project/src/global/variables.css

:root {
  --color-1: green;
}

2. Point this stylesheet in the stencil config as globalStyle:

my-project/stencil.config.ts

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

export const config: Config = {
  namespace: 'cws-web-components',
  globalStyle: 'src/global/variables.css',
  outputTargets: [
    {
      type: 'dist',
      esmLoaderPath: '../loader'
    },
    {
      type: 'docs-readme'
    },
    {
      type: 'www',
      serviceWorker: null // disable service workers
    }
  ]
};

3. Add the css link on the index.html

Attention to the css file name that is my-project.css at this point

my-project/src/index.html

<link rel="stylesheet" href="/build/my-project.css">

4. Finally you can use the variables on your components

  • Make sure they aren't using shadow: true feature
  • Use the var(--color-1) inside your component CSS

@willycamargo This was driving me insane too. @CookieCookson had a great solution that worked for me.

Stencil.config.js

...
sass({
  injectGlobalPaths: [
    "src/global/styles/app.scss"
  ]
})
...

I had to use SASS but sure look it - a fix is a fix :)

@willycamargo This was driving me insane too. @CookieCookson had a great solution that worked for me.

Stencil.config.js

...
sass({
  injectGlobalPaths: [
    "src/global/styles/app.scss"
  ]
})
...

I had to use SASS but sure look it - a fix is a fix :)

is this working with shadow : true?
could you please give us a COMPLETE example?

Hello guys, do you know if is possible to inject global keyframes using shadow dom?

Nothing works for me. I simply want global css3 variable for the theme / colors.

src/global/app.scss

:root {
  --theme-dark: #222428;
  --theme-dark-contrast: #ffffff;
  --theme-dark-shade: #1e2023;
  --theme-dark-tint: #383a3e;
  --theme-dark-rgb: 34, 36, 40;
  --theme-dark-contrast-rgb: 255, 255, 255;
  /* ... */
}

My component just consumes it with var(--theme-dark) etc. with or without the component attributes like shadow or scoped. It just don't works.
I think I'll try it with sass-variable now... 馃槥

It would be great if the root component I defined is like app.component.scss in Angular. The styles are accessable to the childs. (aka global styles, for this scope.)

Update: Ok adding the css link to the index.html works. But is this how web components works? Sounds for me as a workaround. But I'll prefer a more official solution.

index.html

<script type="module" src="/build/my-lib-name.esm.js"></script>
<script nomodule src="/build/my-lib-name.js"></script>
<!-- Adding this: -->
<link rel="stylesheet" href="/build/my-lib-name.css" />

If someone with this problem could try defining variables in the :host selector instead of :root, that was what ended up fixing it for me. Defining in :root only worked for non-shadow components.

For me the variables work.

stencil.config.ts (prject root)

import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';

export const config: Config = {
  // ...
  globalStyle: 'src/global/variables.scss',
  plugins: [sass()],
  // ...
};

Just define a global style sheet for sharing e.g. css variables in root scope.
(SCSS plugin is not necessary, but here in my example because I recommend it.)

variables.scss

:root {
  --color-red: #ff0000;
  --color-green: #00ff00;
  --color-blue: #0000ff;
  --color-yellow: #ffff00;
}

some-component.scss

.awesome-button {
  background-color: var(--color-blue);
}

Works 馃憤
Variables in hosts are only for the host (e.g. component)

For me the variables work.

stencil.config.ts (prject root)

import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';

export const config: Config = {
  // ...
  globalStyle: 'src/global/variables.scss',
  plugins: [sass()],
  // ...
};

Just define a global style sheet for sharing e.g. css variables in root scope.
(SCSS plugin is not necessary, but here in my example because I recommend it.)

variables.scss

:root {
  --color-red: #ff0000;
  --color-green: #00ff00;
  --color-blue: #0000ff;
  --color-yellow: #ffff00;
}

some-component.scss

.awesome-button {
  background-color: var(--color-blue);
}

Works 馃憤
Variables in hosts are only for the host (e.g. component)

Are you using shadow component? can you please share code the decoration of your component?

Was this page helpful?
0 / 5 - 0 ratings