Dynamically choosing CSS file based on $routeParams

2,723 views
Skip to first unread message

Kristopher Schultz

unread,
Jan 30, 2013, 11:03:04 AM1/30/13
to ang...@googlegroups.com
I'd like to implement simple theming support for an AngularJS application. Ideally, I'd like to define a route with a "themeId" parameter and use that parameter to dynamically apply the the appropriate CSS file to the root page of my app.

For example, if I define this route...

    $routeProvider.when('/:themeId', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    });

...then for a URL like this...


...I want my app to use the CSS file "styles/fantastic-theme.css"

I'm stumped as to how to go about this. Any suggestions are appreciated.

Michael Bielski

unread,
Jan 30, 2013, 11:18:27 AM1/30/13
to ang...@googlegroups.com
I did this in my own work and solved it by giving the link tag an ID and then updating the href attribute as needed for the different themes. The browser does the rest. I did mine in jQuery, but you should probably do yours in a directive. You could do it in your route, but I'm not sure that that is the right way to do it.

Guillaume Biton

unread,
Jan 30, 2013, 4:49:50 PM1/30/13
to ang...@googlegroups.com
Maybe you could do something like slides from html5rocks.

I have create a jsfiddle to illustrate : http://jsfiddle.net/guillaumebiton/863f6/

In your case, get $routeParams.themeId and mark your style sheet as not disable.

Ugly hack but it works.

Kristopher Schultz

unread,
Feb 5, 2013, 3:58:56 PM2/5/13
to ang...@googlegroups.com
I came up with a solution I'm pretty satisfied with. In my original description of my goal I said I just the stylesheet to be applied dynamically, but to be more complete I ideally wanted the stylesheet and the view HTML partial to be applied dynamically. That way a theme developer wouldn't be limited to just modifications that were cosmetic (CSS) but could actually make structural modifications. The solution I arrived at does this!

The Solution

To start with, my route definition looks like this...

  $routeProvider.when('/:themeId', {
    templateUrl: 'views/main-view-shim.html',
    controller: 'MainCtrl'
  });

Then, my "main-view-shim.html" file contains a single <div>, using the ng-include directive to dynamically select the right HTML view partial...

  <div ng-include="'themes/' + themeId + '/views/main.html'"></div>

Finally, in the "themes/[someThemeName]/views/main.html" file, I link to the appropriate stylesheet like so...

  <link rel="stylesheet" ng-href="themes/{{themeId}}/styles/main.css">
  <!-- other HTML here -->

Luckily, the consensus seems to be that unlike older HTML specs, HTML5 does allow a <link> in the body of an HTML page and not just in the head. The only potential issue is that the HTML may be displayed unstyled for a bit if the CSS file takes a while to load, but in my experience so far that hasn't happened although I'm sure the possibility is real over slower connections with large CSS files. But in my case this is a perfectly acceptable tradeoff.

Andy Joslin

unread,
Feb 5, 2013, 11:55:00 PM2/5/13
to ang...@googlegroups.com
Nice, Kristopher! :-)

Alexander Castillo

unread,
Jan 9, 2015, 2:30:48 PM1/9/15
to ang...@googlegroups.com
Hi Kristopher,

You could use AngularCSS to accomplish this.


This Angular module allows you to reference stylesheets in your components (directives) and pages (routes).


If you are using ngRoute

    $routeProvider
      .when('/my-page', {
        templateUrl: 'my-page/my-page.html',
        controller: 'pageCtrl',
        css: 'my-page/my-page.css'
      });


If you are using directives

    myApp.directive('miyDirective', function () {
      return {
        restrict: 'E',
        templateUrl: 'my-directive/my-directive.html',
        css: 'my-directive/my-directive.css'
      }
    });
Reply all
Reply to author
Forward
0 new messages