2

I have an Angular component that encapsulates a picture carousel. If uses the :host selector to make itself a flexbox and ngFor to repeat an img tag for each picture in an array of pictures passed in to it through an @Input property.

I have two, related problems.

1) I want to allow the pictures to be styled to a fixed height or width. 2) I want to set the margin-right and margin-bottom on the imgs to allow spacing the pictures.

The tricky part is that I want these settings to be determined in the host template, not the carousel template so that they can be vary based on the needs of a particular page.

I've got it working using custom css properties like this:

image-list css:

:host {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
    align-items: flex-start;
}

img {
    height: var(--pictureMaxHeight,-1);    
    margin-right: var(--pictureSpacing,0);
    margin-bottom: var(--pictureSpacing,0);
}

calling template css:

image-list {
   --pictureMaxHeight: 300px;
   --pictureSpacing: 0.5em;
   justify-content: center;
}

I'm getting the following warning:

Custom property ignored: not scoped to the top-level :root element (image-list { ... --pictureMaxHeight: ... })

Full text:

WARNING in ./src/app/pages/image-list-test/image-list-test.component.css (Emitted value instead of an instance of Error) postcss-custom-properties: /home/username/wwwroot/src/app/pages/image-list-test/image-list-test.component.css:2:5: Custom property ignored: not scoped to the top-level :root element (image-list { ... --pictureMaxHeight: ... }) NonErrorEmittedError: (Emitted value instead of an instance of Error) postcss-custom-properties: /home/username/wwwroot/src/app/pages/image-list-test/image-list-test.component.css:2:5: Custom property ignored: not scoped to the top-level :root element (image-list { ... --pictureMaxHeight: ... }) at Object.emitWarning (/home/username/wwwroot/node_modules/webpack/lib/NormalModule.js:117:16) at result.warnings.forEach (/home/username/wwwroot/node_modules/postcss-loader/lib/index.js:149:49) at Array.forEach (native) at postcss.process.then (/home/username/wwwroot/node_modules/postcss-loader/lib/index.js:149:27) @ ./src/app/pages/image-list-test/image-list-test.component.ts 48:21-62 @ ./src/app/app.module.ts @ ./src/main.ts @ multi webpack-dev-server/client?http://0.0.0.0:0 ./src/main.ts

I tried declaring the variable in the app.component.css file but it made no difference to the error received.

Besides, declaring custom properties for every component in the project would completely break the encapsulation.

The interesting thing is that it works, even with the warning.

I know I could declare a custom html attribute but since this is nothing to do with the structure of the component and is purely visual styling, that seems smelly to me.

Have I missed something here or is there some better way to address this requirement?

1
  • How about importing template.css with <link ref...>. At least it's how I got rid of the warning Commented Mar 18, 2018 at 22:43

1 Answer 1

1

Angular (or you) are using the postcss-custom-properties plugin (as you can see in the message) for custom properties that require you to declare @custom-properties to the :root selector for each component. You can disable the warning by passing the option.

I suggest you, if you can, to use postcss-css-variables that follow the css spec. So, starting from your snippet you can have this, that is much better and decoupled:

:host {
  --pictureMaxHeight: var(--public-var);
  --pictureSpacing: var(--public-var);

  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  align-items: flex-start;
}

img {
  height: var(--pictureMaxHeight,-1);    
  margin-right: var(--pictureSpacing,0);
  margin-bottom: var(--pictureSpacing,0);
}
Sign up to request clarification or add additional context in comments.

3 Comments

I tried your solution and it produced the same warnings. I also tried adding the custom variable assignments to var(--public-var) in :root instead of :host but that didn't work too.
Turning off the warnings worked, although it's a pain in the arse since it requires ejecting the ng-cli webpack config.
My snippet work only if you use postcss-css-variables and not postcss-custom-properties (the one that return the warning)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.