Skip to main content
Ben Nadel at InVision In Real Life (IRL) 2019 (Phoenix, AZ) with: Michiel Westerbeek
Ben Nadel at InVision In Real Life (IRL) 2019 (Phoenix, AZ) with: Michiel Westerbeek ( @happylinks )

Including CSS File Content Using CFInclude In ColdFusion

By on
Tags:

In my first pass at building Dig Deep Fitness - my ColdFusion fitness tracker - I'm using a traditional, multi-page application (MPA) approach. Which means, every navigation is a full-page refresh. This is slower than a single-page application (SPA). As such, in order to help decrease page load times - especially on first load - I'm rendering my temporary CSS directly in the page <head> tag. This way, the browser doesn't need to block-and-request the .css file in a separate HTTP request. And, to keep things super simple, I'm doing this with the CFInclude tag; which, in ColdFusion, can include any kind of text file.

Normally, when we use the CFInclude tag, we're including a ColdFusion file. Specifically, a .cfm file. ColdFusion will then compile this file down into byte code, execute it (as ColdFusion code), and then append the output to the current page output.

But, there's nothing that says the referenced template has to be a .cfm file. In fact, you can include any text file and ColdFusion will happily compile and execute it. In my case, to cut down on network requests, I'm using CFInclude to include a .css file:

<doctype html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<!---
		NOTE: I'm using the CFInclude tag to inline my .CSS file content into my main
		page. This way, the browser won't have to block and request the CSS file in a
		separate HTTP request.
		--
		CAUTION: By default, this WILL evaluate the contents of the .CSS file as if it
		were a ColdFusion file (which should be fine in 99.999999% of cases).
	--->
	<style type="text/css">
		<cfinclude template="./main.css" />
	</style>
</head>
<body>

	<h1>
		Using CFInclude To Inject CSS Into The Head Tag
	</h1>

	<p>
		Hey there, my CSS is now
		<strong class="highlight">inlined in the page</strong>!
	</p>

</body>
</html>

Notice that instead of using a <link> tag to reference my .css file, I'm using a <style> block. And then, inside that <style> block, I have a CFInclude tag. This tag is going to pull the contents of my main.css file right into the contextual <style> block of my page.

This approach does have a caveat! The .css content is going to be evaluated as if it were ColdFusion code. Here's the .css file for this demo - notice that it uses a content property to define text that contains what would be a CFML expression:

body {
	font-family: monospace ;
	font-size: 18px ;
	line-height: 1.4 ;
}

body::after {
	/*
		CAUTION: On output, the CFSET will disappear because ColdFusion will evaluate this
		text as CFML code, and will evaluate the SET operation. Of course, this will never
		actually be a problem.
	*/
	content: "==>[<cfset x=3 />]<==" ;
}

.highlight {
	background-color: #ffdd00 ;
	display: inline-block ;
	padding: 2px 8px 2px 8px ;
}

Now, if we run the ColdFusion page and look at the rendered output, here's what we see:

Rendered HTML of the page demonstrating that Style tag has been populated with .css file content; but, that the SET code has been removed.

First and foremost, we can see that the contents of the .css file have been included into the rendering of the main page request - the browser no longer needs to make a blocking HTTP request in order to gather that code. And second, we can see that our <cfset> tag has been excluded from the output. This is because ColdFusion evaluated the code as CFML (which executed the set-operation).

In reality, however, you'll never have ColdFusion code inside your CSS file; so this is never going to be a problem. Which means, using the CFInclude tag is an easy and effective way to inline your CSS into your top-level page request.

This works with JavaScript (.js) files as well.

Adobe ColdFusion Exposes this.compileExtForInclude Setting

So, I just learned about this. Apparently Adobe ColdFusion (not Lucee CFML compatible) has an Application.cfc setting (and a server-wide setting) in which you can tell the runtime which file-extensions should be parsed as CFML code: this.compileExtForInclude. If the given file is not in the list of file-extensions, ColdFusion will include the file as static text. Which means, in Adobe ColdFusion, if we added this Application.cfc:

component {

	this.name = "InlineCssDemo";
	this.applicationTimeout = createTimeSpan( 1, 0, 0, 0 );
	this.sessionManagement = false;

	// Only evaluate CFM files when consumed via CFInclude.
	this.compileExtForInclude = "cfm";

}

... ColdFusion will include our .css file, but will not evaluate it as ColdFusion code. Which means, the <cfset> statement inside the content property will be output as static text.

By default, the server-wide setting for this is *, which means, by default, ColdFusion will evaluate all files as "CFML" when consumed via CFInclude.

Want to use code from this post? Check out the license.

Reader Comments

Post A Comment — I'd Love To Hear From You!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel