cssSweet and Dynamic CSS in MODX

Jan 5, 2017

Someone recently emailed a question about cssSweet, which was something along the lines of, "How do I render dynamic CSS styles that vary per-page, while using cssSweet to manage global styles?"

Example Case

Let's say the requirement is for the CMS user to be able to specify a background image for a certain element, that can vary with each page (aka MODX "Resource").

As with everything MODX, there are many ways to do this. One approach is to assign a custom field (aka MODX "TV") to the Template used by these Resources. The CMS user selects an image using the TV, and the value is available in a placeholder like [[*name_of_tv]].

It may be tempting to try to use this placeholder inside a cssSweet Chunk. However, MODX Resource field placeholders like [[*pagetitle]] and [[*name_of_tv]] are only available on the page-rendering event—when MODX generates a response to a request on the front end.

You can use these placeholders in Resource fields like the "content" field, or in the Resource Template, or in a Chunk that's called from one of those places, but you can't use these placeholders in a Chunk parsed by cssSweet.

This is because cssSweet executes on a back end Manager event, namely when someone clears the cache or saves a Chunk that cssSweet is configured to "watch". The output from cssSweet is a static file that has no "knowledge" whatsoever about the page on which it is being included.

So the solution in this case, is to put the dynamic CSS in a style tag. It doesn't matter whether the style tag markup is in the Template, or a Chunk called from the Template, only that it needs to be rendered on the page.

<head>
...
<style>
...
.element {
  background-image: url([[*name_of_tv]]); 
}
...
</style>
...
</head>

This will have the effect of overriding the background image for elements with the class "element", and can be set per page, while still allow you to manage your CSS in a performant way using cssSweet.

Advanced Usage

On the MODX Services Team we're often asked to optimize our clients' sites/codebase, to get better Pagespeed scores. Interestingly (and perhaps contrary to web development best practices) Google Pagespeed actually rewards you for putting all your CSS in a style tag versus including an external file.

If you want your cssSweet-managed CSS in a style tag, you can do it easily:

  1. Setup cssSweet as you normally do.
  2. Create a static Chunk that references cssSweet's output file.
  3. Call that Chunk into your Template, inside a style tag in the document head.

You can still use dynamic, per-page overrides. The above example would look like this:

<head>
...
<style>
[[$cssSweet_output]]
.element {
  background-image: url([[*name_of_tv]]); 
}
...
</style>
...
</head>

In this video I show you how you can get your Pagespeed score to the high 90s by doing something very similar. In reality, if your site visitors tend to visit more than one page, then this approach is folly, because it means your users won't benefit from in-browser caching of your CSS, but that's a discussion for another post or maybe the comments.

Happy MODX-ing!