Custom CSS attributes for Angular components

旧时模样 提交于 2019-12-14 03:57:15

问题


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:


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);
}


来源:https://stackoverflow.com/questions/48138238/custom-css-attributes-for-angular-components

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!