Search code examples
cssangularsass

How to use an injected string as part of the path in a URL within CSS (in Angular)


I have a library that allows you to inject a base-href value for your specific app so that the lib's assets (which you're hosting as an npm dependency in your app) can be accessed without a proxy. This works in most cases, except I can't figure out how to use that injected value in CSS to do this:

$fonts: '#{<injected base path here>}/fonts';

@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 300;
    src: local('Roboto Light'), local('Roboto-Light'),
    url('#{$fonts}/roboto-v18-greek-ext_cyrillic-ext_latin-ext-300.woff2') format('woff2'),
    url('#{$fonts}/roboto-v18-greek-ext_cyrillic-ext_latin-ext-300.woff') format('woff');
}

The problem is the URL needs to resolve at build time, so this code won't compile.

2 notes:

  1. I'm using Angular with injection tokens.

  2. In my case, in the scss file, I tried $fonts: '#{var(--asset-base-path)}/fonts'; and in the component.ts file, I tried:

@HostBinding('style.--asset-base-path') assetBasePath = '';

constructor(@Inject(LIB_ASSET_BASE_PATH) path: string) {
    this.assetBasePath = path
}

Solution

  • No, This can not be done by DI. DI(Depedency Injection) is a run-time behavior, when Angular initiate a component after application runs, the DI system will create and injecting the depedencies for that component.

    CSS Preprocessor such as Sass/Scss/Less will be compiled to pure css files (Since browser only accepts css, not Sass/Scss/Less) and all variables in style files must be evaluated after build. which means you css code has no dynamic behavior at run-time.

    The only way to achive your requirement is to use JavaScript to operate styles and set the font path at run-time.