javascriptcssangulartypescriptuser-agent

How should I reference different files for different devices using Angular?


So this is my project's structure in version 18.2.8. enter image description here

This is the structure if I'm looking with a pc: enter image description here

What I want to do is to show a css file depending on what you are logged with. But I'm not entirely sure on how I'm suposed to reference the CSS files in an angular project. I did not want to use media queries because I don't want my app to show on the pc as if it were a phone whenever I make the window very small, so I tried to do it with userAgent to check if it's beeing looked at with a phone or a desktop.

Right now I'm very confused because when I compile the code into the website, my styles.css gets combined with both of the other CSS files as if I were to do @include.

The website also creates another "copy?" of the desktop.css (when I'm looking with a desktop) and puts it on the same level as the styles.css, so if I have multiple variables named the same, it uses this file first and it's fine. But if I have a variable in mobile.css and not in desktop.css, it shows in both because it gets combined in styles.css.

What should I do?

For some context this is what is in my AppComponent: This works as it should.

constructor() {
  const userAgent = navigator.userAgent.toLowerCase();

  if (/mobile/i.test(userAgent)) {
    this.device = "mobile";
  } else {
    this.device = "desktop";
  }

  this.loadStylesheet();
}

loadStylesheet() {
  const head = document.getElementsByTagName('head')[0];

  // Create a new link element
  const linkElement = document.createElement('link');
  linkElement.rel = 'stylesheet';
  linkElement.type = 'text/css';
  linkElement.href = this.device === 'mobile' 
    ? 'mobile.css' 
    : 'desktop.css';

  // Append the link element to the head
  head.appendChild(linkElement);
}

I tried to add the css files like this in my angular.json:

"styles": [
    "src/styles.css",
    "src/app/styles/desktop.css",
    "src/app/styles/mobile.css"
]

I expected to see the files just to stay as they are, and show only when I'm on the pc or phone as it should. But actually what happened is what I described before, it creates a css file automatically, and also combines all the css into styles.css.

Also, on the begining I just deleted styles.css and removed it from angular.json, but it got created anyway. I want to keep the file regardless, but I think it's worth pointing out.


Solution

  • By default Angular combines all entries in styles into a single bundle while preserving their order.

    You can control that behaviour by using complex configuration values. Based on your example the following configuration should create separate desktop.css and mobile.css bundles without including them on the page automatically, allowing you to add them using your custom logic in AppComponent

    "styles": [
        "src/styles.css",
        {
          "input": "src/app/styles/desktop.css",
          // By default, angular is injecting each file .
          // Set to false to exclude the bundle from injection, since you are handling it yourself
          "inject": false,
          "bundleName": "desktop"
        },
        {
          "input": "src/app/styles/mobile.css",
          "inject": false,
          "bundleName": "mobile"
        }
    ]
    

    For more details check the Angular docs

    Hope that helps :)