Grow your CSS skills. Land your dream job.

Using CSS without HTML

Published by Guest Author

Big thanks to Mathias Bynens for the guest post today! I'd call this a bonafide CSS trick!

A few days ago, Chris tweeted:

If we could stack pseudo elements (e.g. :after:after) we could build a whole website with no HTML other than <html>. Probably good we can’t.

In response to this, I created this quick demo (view in Firefox or Opera), illustrating that technically you don’t need any HTML at all to use CSS.

Since this demo apparently caused some confusion among tweeps, I decided to write an article about it. Basically, all this magical demo does is combine two nifty little tricks most people don’t seem to know about.

Some HTML elements are implied

The opening and closing <html>, <head> and <body> tags aren’t required in HTML. The following document is perfectly valid and conforming:

<!DOCTYPE html>
<title>Example</title>

For brevity, this code sample uses the HTML5 DOCTYPE, but don’t let that confuse you — if you’d switch to the HTML 4.01 DOCTYPE, the document would still validate. Obviously, XHTML has a much stricter syntax, which doesn’t allow omitting optional opening and/or closing tags. But it's almost 2011, who’s still using XHTML anyway?

When a browser renders our example document, it notices the <html>, <head> and <body> elements are missing from the source, and — wait for it — automatically generates them. You can confirm this by opening the demo page and inspecting the generated source using Firebug, the Web Inspector, or Opera Dragonfly.

Because these elements are implied, they can also be styled through CSS, regardless of whether they occur in the source code or not. Consider the following example:

<!DOCTYPE html>
<title>Example</title>
<style>
  html {
    background: red;
  }
  body {
    background: blue;
    margin: 0 auto;
    width: 30em;
  }
</style>

Even though there’s no mention of the <html> and <body> elements in the HTML source, we can still style them because browsers generate them automatically.

Basically, this is the first trick I used; I just took it one step further. I didn’t bother to specify a DOCTYPE, let alone a <title>, and simply used no HTML at all. Never, ever do this for a real website. Because of the missing DOCTYPE, the document will be rendered in quirks mode instead of standards mode. It goes without saying that the document won’t validate either.

Even with a completely empty HTML document, browsers will still auto-generate the implied HTML elements.

(Interesting sidenote: It’s also possible to style hidden elements such as <head>, <title>, <meta>, <script>, etc.)

The Link: HTTP header

RFC 5988 defines the Link HTTP header, which allows you to send <link> elements through HTTP headers instead of including them in the HTML. To give you an example, you can serve a document with the following HTTP header:

Link: <some-document.html>;rel=prefetch

...which would have the same effect as placing this in your HTML:

<link href="some-document.html" rel="prefetch">

Similarly, RFC 5988 makes it possible to include stylesheets in an HTML document using nothing but a HTTP header:

Link: <magic.css>;rel=stylesheet

Which is equivalent to...

<link href="magic.css" rel="stylesheet">

Usage

So if you want to play around with this at home, you make your demo page PHP and set the header right at the top of the page:

<?php header('Link: <demo.css>;rel=stylesheet'); ?>

In this demo, the content was inserted into the page using pseudo elements in the CSS:

html { 
   background: #666; 
   padding: 1em; 
}
body { 
   border: 5px dashed #eee; 
   color: #fff; 
   font: 3em/1.5 sans-serif;
   padding: 1em; 
   width: 30em; 
   margin: 0 auto; 
}
body::after { 
   content: 'O HAI! Have a look at my source code :)'; /* This needs to be on the ::after (and not just on `body`) for it to work in Firefox 3.6.x. */ 
}

Well, that’s the theory. In practice, not a lot of browsers implement the Link header. At the time of writing, only Opera and Firefox support this little gem.

If you’re interested to see how browser support for this feature will improve over time, you can subscribe to the bug reports for WebKit (Chromium has separate bug tickets for the CSS and the general variant) and Internet Explorer.

Disclaimer

As mentioned, these techniques are fun tricks, and it’s definitely good to know they exist. However, it wouldn’t be a good idea to use these in practice. The no-HTML ‘hack’ is all kinds of evil, and no web developer would seriously consider using this for a real site.

The Link HTTP header is a lot more interesting. The only reason this can’t really be used yet, is lack of browser support. Maybe one day...

Kudos to Anne van Kesteren for teaching me about the Link header back in 2005 :)

Comments

  1. I am going to build my whole website this way!!!!

    jk.

    lol This was a fun and interesting post!

    • Permalink to comment#

      Why not?
      If this way of creating website would support all the positioning and formating features, i would think about making some small websites with it.

      The problem is that you can just style html, head and body. No other elements are generated automatically.

  2. Permalink to comment#

    That is really impressive !!!!!

    Thanx a lot for sharing

  3. Permalink to comment#

    We *can* stack pseudo-elements, but it’s not supported by any browser yet :( http://www.w3.org/TR/css3-content/#inserting0

  4. Permalink to comment#

    Nice one! Not that I’m about to use it, but interesting anyway!

  5. Permalink to comment#

    You are a genius ;) Great.

  6. Really amazing! If we could stack those pseudoclasses, I’d be the first to build PHP library that’d allow us to create such structure! ;]

  7. Permalink to comment#

    Got to know some new things like styling for the title tag is possible. I’m going to try that first before trying out the rest. ;)

  8. Permalink to comment#

    I think this is a nice use-case with before/after:

    http://matthamm.com/box-shadow-curl.html

    cheers.

  9. Permalink to comment#

    Nice Mathias!

    I think would be useful link the style in headers if all browsers had implemented this.
    However I figure out that FFX start the css download when html download finish. That is bad for perfomance.

    • Yes, it would be awesome if the Link header was better supported across browsers. This would allow for lots of cool stuff, e.g. feed autodiscovery on non-HTML documents — think images or plain text files!

      Interesting that Firefox only starts downloading the CSS after the HTML download is finished. Care to file a bug?

      Note that Firefox’s implementation of Link isn’t complete; from my tests, it seems like it only works for rel=prefetch and rel=stylesheet. Things like rel=alternate (for feeds) don’t trigger feed autodiscovery just yet: https://bugzilla.mozilla.org/show_bug.cgi?id=498117 (This works fine in Opera.)

  10. Cool stuff, very interesting

  11. Joshua Bryant
    Permalink to comment#

    Couldn’t a potential application of the LINK header be to essentially link a conditional stylesheet? In it, you could specify styles for FF & Opera only.

    Maybe not as useful as conditional stylesheets for IE, but still an intriguing concept.

    • Please don’t ever do that.

      Sure, what you’re suggesting would work *today*, but as soon as WebKit and/or IE decide to implement the Link header, they’ll end up getting your Firefox/Opera-only stylesheets as well. So much for future-proof code :)

      Besides, have you ever felt the need for a Firefox/Opera-specific stylesheet?

  12. Erkan Yilmaz
    Permalink to comment#

    Does this mean the end of HTML ?

  13. Girish
    Permalink to comment#

    What the?

  14. “But it’s almost 2011, who’s still using XHTML anyway?”

    Haha! I love it!

  15. Ryan Litts
    Permalink to comment#

    This is pretty cool. Could you apply this as a fallback for flash object that don’t load for agents like ipads ect.

  16. Neat trick, but one downside of generated content is it can be hard to debug problems it might be having/causing because it isn’t part of the DOM.

  17. Permalink to comment#

    Hahaha, when I first saw the title of your article I thought: “WHAT ??? HOW ??? IMPOSSIBLE ???” – Funny and interesting article ! :D

    P.S. I like the new design of CSS-Tricks, makes me wanna stay here and read anything I see. :O

  18. Permalink to comment#

    There is a lot of things happening behind the scenes of the web, and that is one of them.
    Nice Trick.

  19. Impressive. Simply, impressive!

  20. While this post is meant to be taken somewhat likely and not a suggested way for going about design it is very helpful to experiment with the power of control that you have with CSS. It can be pretty surprising.

    I have actually been in situations where a page needed a new style or design but I didn’t have access to the HTML as it was dynamically generated from XSL and XML that were bound to a global server and powering several sites. Because of constraints like these advanced control and selection of elements with CSS actually becomes a very helpful tool to have on your side.

  21. Permalink to comment#

    HA! Interesting…thanks! This makes me want to play…

  22. Permalink to comment#

    Greaat…

  23. Permalink to comment#

    It’s 2011. Everyone SHOULD be using XHTML.

  24. Ramesh Vishwakarma
    Permalink to comment#

    What about the other browser if this technique is not useful for them ?

  25. Permalink to comment#

    As Bob said, everybody should use XHTML for now. I don’t know how you come up with idea of not recommending XHTML. Do you still write in HTML 4.01, dear author?

    • toufik
      Permalink to comment#

      it’s golden age of HTML5. we should embrace it.

      btw, it this somekind of Inappropriate uses of CSS??
      just like you said at this articles

      thanks.

    • seutje
      Permalink to comment#

      XHTML takes away your freedoms!

    • Roy Tomeij
      Permalink to comment#

      You do know that something new came into our world after XHTML, right?

    • Permalink to comment#

      @Toufik, HTML5 is still draft and until it’s not supported by browsers it’s not worth using. HTML5 is only loud slogan for now.

      @Seutje, if by freedom you mean tag soup I’m glad XHTML takes it away.

    • seutje
      Permalink to comment#

      @marines: I could take that as a serious argument, but your personal page throwing my IE in quirks made me assume you don’t rly take web development serious
      try properly closing your tags, quoting your attributes and all that other crap, u know… like XHTML demands
      then again, this mess wouldn’t conform to HTML5 either
      no worries, I won’t pick on the trailing-comma js errors ♥

    • Permalink to comment#

      It was made few years ago and it’s not really mine code but you’re right. ;)

    • I was thinking the same thing.
      Yes, HTML5 is nice. I’m excited for it. We should be experimenting and practicing with it. We should not be relying on a draft that’s not fully implemented across all browsers. It’s hard enough to get older IE to not shit a brick, and at least there we know the limitations. With HTML5 it’s a crapshoot what your user might have supported.

      XHTML is strict adherence to a standard. That is a good thing.

    • HTML5 is in draft because web designers demanded better options and because browsers needed to keep up with the methods we are already using. We need to use HTML5 now in areas where it is appropriate (as in doesn’t destroy functionality) because using the latest and greatest of the tools available to us is what pushes the development of browsers and new specifications faster. If we all wait for it to be released and supported by every browser we are slowing the improvement of the web and hindering ourselves.

    • Permalink to comment#

      to everyone extolling the wondrousness of xhtml: how many of you serve your pages with the correct mime-type?

      I’m sure some of you realize this, but I’m also sure many of you don’t: xhtml is not simply a matter of using lowercase, self-closing tags and a verbose doctype. Most “xhtml” on the web is poorly-formed and/or invalid, and is actually rendered by browsers as excessively-error-corrected html.

    • seutje
      Permalink to comment#

      @brian: I hope you’re not using CSS2.1 then, as it isn’t fully implemented in any single browser and all that yada yada

      also, you should read up on http://hixie.ch/advocacy/xhtml

    • XHTML is strict adherence to a standard. That is a good thing.

      How is that an argument in favor of XHTML? You could say the exact same thing about HTML 4.01.

    • Permalink to comment#

      What is frustrating is that if not for IE, we all could have served real XHTML as application/xhtml+xml by now. I have a rant about it on Reddit here:

      http://www.reddit.com/r/web_design/comments/ese39/how_ie_damaged_xhtml_adoption/

  26. Permalink to comment#

    It is really great !

  27. Nice, but it has nothing to do with semantic structured content.

  28. Permalink to comment#

    Haha, really nice idea. =)

  29. If this is us experimenting, just imagine what the guru’s of W3C have come up with.

  30. Permalink to comment#

    Excellent Article with Great Examples.

  31. Crimlo
    Permalink to comment#

    i did this ages ago, too bad i don’t have a blog

  32. That’s so cool!

    What else could we strip out just for fun?

    • Permalink to comment#

      you could eliminate the need for a stylesheet altogether, along with the browser-generated markup, by serving all your content in PDFs

  33. oguzagel
    Permalink to comment#

    Nice!

    It is really great !

  34. That’s pretty awesome. If somebody would have asked me I probably would have said it’s possible but never knew you could post content through the css. You learn something new about CSS every day ;-)

  35. Nice trick. Quite informative.

  36. Permalink to comment#

    Very interesting article – i probably wont be coding any clients sites like this but might have a little play on one of my own test sites. Thanks for the insight.

  37. Permalink to comment#

    Hi Chris:

    i like your work and articles, but this topic is of no use to anyone. The things you cant use should not be places as newbies can get confused and lost by articles like this.

    I am telling you this because one of our new employee who i recommended to go to your site and learn new tips and tricks was lost by this article.

    This is our community and we should take full responsibility to guide programmers in right direction including newbies.

    • Mathias included an entire section in the articled titled “Disclaimer.” Please read that.

    • Permalink to comment#

      Chris:

      Be honest and tell me HOW many times one read a Disclaimer.

      Anyways, Once again, I like your work but still feels that this post can be misguiding for ppl who joined in.

    • Permalink to comment#

      be honest, how many times is it the author’s fault that someone doesn’t read the disclaimer?

      If you’re going to send employees here to learn, that’s great. But if you’re worried about this sort of thing, maybe you should select specific articles for them. Or get a real training program.

  38. Permalink to comment#

    lol, this is funny. didnt expect to see that. this would be amazing if it did work. but how would google index keywords on the site? lol prolly bad for seo if it did work.

  39. Permalink to comment#

    This was fun! Still Chris is right: don’t use this for real websites…not to mention SEO and stuff :)

  40. Permalink to comment#

    Gurvinder, if chris never posted this i would’ve never known this existed. maybe someone could turn this idea into a working one. having html,css,and javascript show is good for other people to learn how something was made. but for websites that want to be 100% secure if the field data was actually hidden just imagine how much more security can exist by having all the html feilds hidden though source.

    • Permalink to comment#

      I agree on the security aspect of it and will look forward to implement them but this is also a know fact that is’t not been implemented across browser yet and as i mentioned earlier will NOT gonna help young/New programmers.

    • How would this technique improve security at all? Everything is still being sent over the wire unencrypted. It has nothing to do with security.

  41. DeepThinker
    Permalink to comment#

    what’s u all aspects from HTML5

  42. Permalink to comment#

    Great Article! It would be interesting building a whole site in this manner.

  43. Permalink to comment#

    Sweet – New tricks rock!! Loved It :-)

  44. Jarod Billingslea
    Permalink to comment#

    lol only problem though is that this can be on one page only.

  45. JayB
    Permalink to comment#

    You’ve done another great job chris!
    -waiting to have another screencast!

  46. I’m little scared to implement this. ‘cos what will google do if it see sites like this will it rank ? if not i’m not into this..but so far this is a real adventure..

  47. Permalink to comment#

    That is really impressive !!!!! but how to find this website when google can not see their content?
    I think it would really be a revolution

  48. Permalink to comment#

    Nice! Thanks for sharing!

  49. Kev
    Permalink to comment#

    Would it be possible to use the :after pseudo element to insert html like this:

    <a href='domain.com' rel="nofollow">This is a link generated by CSS</a>

  50. keshav
    Permalink to comment#

    Jhakkaas!

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".