CodeinWP CodeinWP

Adding CSS to a Page via HTTP Headers

I’ve been coding websites for a long time but even I was a little puzzled when I came across a Hacker News comment where the commenter described their own makeshift CMS that involves using your own file system. The most interesting part to me was when the person said they add CSS to pages on their personal projects by means of HTTP headers.

I had heard of this technique before and the person does say in the comment that this doesn’t work in every browser. But I decided to do some research to figure out how one might do this and why this would be easier than just dropping in one or more <link> elements in the HTML.

I’m sure many of you who have been developing sites for some time now are familiar with this. But I thought I’d write it up for those looking for a quick solution. This should especially be helpful because this apparently isn’t the easiest topic to search for since the terms “HTTP” and “header” are quite common in web development (and due to the fact that Google search has sucked for many years now).

Adding Headers via .htaccess

Before getting to the actual solution, let’s take a brief look at how to add HTTP headers in general. You can put a line like the following in your website’s (or directory’s) .htaccess file (assuming you’re on an Apache server):

Header add Header-Name "parameter=value"

This uses Apache’s Header directive. The part inside the quotes is a parameter/value pair that works as the value for that specific header.

To demonstrate, I’ll do the following, which creates a custom header:

Header add Funky-Music "getdownand=boogie"

This is just a header that I made up. You can also add any valid HTTP header, assuming you use the correct syntax. You also have the option to use the set argument instead of add, which will overwrite the header if it already exists. There are other arguments you can use, described in the aforementioned apache.org doc.

I’ve set up a demo directory and I’ve added an .htaccess file to that directory, along with a basic HTML file called index.html. When you load up that page in your browser, you can see the headers that the server responds with by viewing the Network tab in the browser’s developer tools:

Viewing a Custom HTTP Header

In Firefox it looks like this:

Viewing a Custom HTTP Header in Firefox

In both cases you can see the custom header that I added. You can also see any other headers that are added by default.

That’s a fairly basic summary of adding HTTP headers, including adding custom headers. For a more thorough discussion of the topic, check out this post by Jeff Starr.

Adding CSS via HTTP Headers

Now that you have a basic idea of how to add HTTP headers, let’s take a look at how to add a stylesheet via the same method. The W3C’s HTML4 spec has some info on how to do this, however it notes:

This section only applies to user agents conforming to versions of HTTP that define a Link header field. Note that HTTP 1.1 as defined by [RFC2616] does not include a Link header field.

According to my testing, the only current desktop browser that supports this feature is Firefox. The only mobile browser that I could find that supports this is Opera Mini (tested on iPad). This leads me to believe that pre-WebKit Opera supported the feature.

Nonetheless, to add CSS using an HTTP header, you can put the following line in your .htaccess file:

Header add Link "<style.css>;rel=stylesheet;media=all"

The syntax is the same as that for the custom header I added previously, and basically the same syntax as when adding any HTTP headers, custom or not.

In this case, I’m using Link as the name of the header. This is what tells a supporting browser that I want to add a <link> element to my page. The value for the header consists of:

  • The URL of the stylesheet inside angle brackets
  • Attribute/value pairs separated by semi-colons

The quotes around the full value are optional if the value doesn’t contain spaces. If it does, then the quotes are mandatory for correct parsing.

So the above header would be equivalent to adding the following to the HTML:

<link rel="stylesheet" href="style.css" media="all">

The href value can of course be relative or absolute. And, as you probably figured out, this isn’t just for CSS but for anything that can be added using HTML’s <link> element.

I’ve set up another demo page that adds some CSS using the Link header. As mentioned, you’ll have to view it in Firefox to see it work. View the HTTP headers in the Network tab of the developer tools, and you’ll see the stylesheet included:

Viewing a Link HTTP Header in Firefox

Try viewing source on the page itself. You’ll see there’s no CSS file in the source, but the styles are there if you inspect each element. The header will be visible in the Network tab of any browser, but the CSS will only work in Firefox or another browser that supports the Link HTTP header.

From what I can see, the Link header is not a deprecated or obsolete feature, it’s just not well supported. It’s confusing to try to figure out if this is still considered a valid web feature, but here’s what I’ve uncovered:

  • MDN has an article on it and doesn’t indicate that it’s obsolete (though the browser support section is missing).
  • The Link Header is described in the IETF’s RFC 8288, which I believe is the latest proposed standard for “Web Linking”.
  • As the HTML4 spec mentions, the last version of the HTTP 1.1 spec doesn’t include it, whereas the HTTP2 spec seems to mention the Link header in passing.

Why Add CSS Via HTTP Headers?

With so little browser support, it’s hard to justify any use for this other than novelty. As the user on Hacker News said, personal projects can be fun because you can do whatever you want, including using a feature that apparently more than 90% of your users won’t see.

I suppose if you have a lot of HTML pages and you’re not using any kind of back-end scripting or includes, then maybe the best solution is using the Link header. But the fact that it’s so poorly supported doesn’t make it very attractive, personal project or not.

At this point, the only thing I can think of that could justify use for this in production is as a way to include some Firefox-only CSS, which Eric Meyer mentions as a possibility in an old post on this subject. But it’s not guaranteed to always only work in Firefox, so that’s still a problem.

Do with this what you like, but it’s extremely unlikely that this will have any use in a real project. I just thought it would be fun to mess around with it and write it up.

22 Responses

  1. Amit Biswas says:

    This concept is very promising. Can this be done in WordPress sites? Maybe via plugins?

    • Nirmal Kumar says:

      Hey Amit,

      I am also forward to know if this is possible in WordPress in any way. But adding more codes to the .htaccess will make it heavy. Is is a good Coding practice to have too many lines of code in .htaccess, especially in a WordPress website?

  2. Max says:

    if you ask for “plugins” you neither understood the article nor HTTP….

  3. @Amit You could add it to a WordPress site via .htaccess, just as you can do other things with a WordPress site via .htaccess. (Assuming you’re on Apache and it USES .htaccess.) You’d still have the same browser compatibility as everywhere else, though, and I can’t see why doing it this way would be preferable to adding it to your existing stylesheet or enqueuing a new stylesheet via functions.php

  4. If you use Cloudflare the Link header can be used for HTTP/2 Server Push per https://www.cloudflare.com/website-optimization/http2/serverpush/
    Pushing CSS to the client thus way can noticeably speed up a web page.

    • That’s interesting… But wouldn’t it still be dependent on browser support?

      • Scott says:

        I believe the idea is that you have both the Link header and <link> in the HTML. Browsers without support will load the CSS as normal; browsers with support will download the CSS file earlier for better performance.

        • Scott says:

          Sorry forgot to add, Server Push is a separate thing from the Link header and does actually have wide support.

  5. Josh says:

    Why Add CSS Via HTTP Headers?

    Simple: Preloading.

    Using rel=preload for CSS (in particular) is rather pointless, but if the stylesheets are announced via response headers, a browser can find out about them via a lightweight HEAD request. ;)

  6. Great article. Thank you!

  7. Anil Agarwal says:

    Hi Louis,

    I use WordPress CMS, so rather than changing the pre-defined script, I would like to increase the security feature for my WordPress. Adding more code to .htaccess may slow down the speed. In my view, it’s a good idea to increase security by using a plugin like Wordfence and others. Also, adding a code for a non-technical user will be a problem that can damage the design of the website.

    • Yes, Anil
      I agree with you. Most WordPress users are non-techie and editing .htacces file may be intimidating for them.

      Using plugins like Wordfence makes sense to improve the security of WordPress websites.

  8. Very interesting article and relevant to page speed. How about adding the comment <!-- Look, ma! No CSS! --> into the html source code of the example page? Is this made via HTTP header or htaccess?

  9. Dan Q says:

    I’ve long thought that this technique – were support more widespread – would be a great way to inject CSS at at proxy server: much less processor-intensive than HTML injection.

    Use cases could include injecting regional CSS at geographically distributed edge caches, adding local CSS when your externally-hosted intranet is reached from inside your network, or just enforcing the separation of content and style as part of a “headless” CMS. I considered it myself using a reverse proxy to rebrand a proprietary service hosted on my local network before discovering that most browsers don’t (yet) support it: maybe some day!

  10. Sid says:

    Where is the style.css being fetched from?
    It still needs to be added to the server directory right!

  11. jonny says:

    Hey! Is there any way to just configure the Link http header in only one html page? what is the syntax to do so in html? Please respond!

    • I believe you can do it using this sort of format in your .htaccess file:

      <Directory /path/to/folder>
        <Files /path/to/file.php>
          Header add Link "<style.css>;rel=stylesheet;media=all"
        </Files>
      </Directory>
      

      I’m not sure this will work, but you can check this forum discussion which is basically the same topic.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).