Set sass variable value in Angular 7

后端 未结 6 2620
悲哀的现实
悲哀的现实 2021-02-19 22:11

I have been working with angular for the last few weeks, and now I have a requirement to dynamically style a public site. The site admin set various color codes as well as a log

6条回答
  •  误落风尘
    2021-02-19 22:36

    As other answers explained, it is not possible to set SASS variables and process that on the client, as SASS is converted to plain CSS at build time and when app is running or in APP_INITIALIZER browser can process only CSS.

    I see two options to achieve what you want.

    Generally, you would have some base css for the app, and then you need to load the additional css based on admin settings. What needs to be considered from css point of view is that all css specificity in additional css should be greater than base css, because otherwise it won't override the base. That requires basic css knowledge so I won't go into details.

    Method 1

    Generate your additional css on server request. Load it when app is started from server URL. Reload it by js when admin change any settings.

    1. Define backend endpoint at address /additional.css (or it could be similar to /api/theme/custom-css) which will generate css out of database. For example you have background=red in db, then the endpoint should return
    body {background-color: red;}
    
    1. Add in of index.html. And that will be enough to make it work.
    2. To reload you can use different methods, but I believe this should work
    document.getElementById('additionalCss').href = document.getElementById('additionalCss').href;
    

    This will make new request to the server, server will execute DB -> css and return the updated css, which will be applied to the browser.

    And if you want to be cool (or need to support big and complex themes) scss can be used. Backend should generate scss variable definitions out of database, then should use some server-side app to compile scss -> css, and then serve compiled css back to the client. But this will be overkill if additional css is simple enough.

    One important consideration of this method is browser caching, because content behind additional.css is dynamic, but browser may cache it, not call the backend and serve outdated version.

    Method 2

    If you don't want or can't mess with the backend. Load settings from DB by some API endpoint in json, then generate css code on the client and apply it.

    1. Use HttpClient to get settings JSON and generate css as string out of it. For example server returns
    {
      "background": "red"
    }
    

    then you convert this to string as

    cssCode = 'body {background-color: red}';
    
    1. Use
    let additionalCssStyle = document.getElementById('additionalCss');
    if (! additionalCssStyle) {
      additionalCssStyle = document.createElement("style");
      additionalCssStyle.id = 'additionalCss';
      document.head.appendChild(additionalCssStyle);
    }
    additionalCssStyle.innerText = cssCode;
    
    1. To reload - save changed to backend, then repeat 1. and 2.

提交回复
热议问题