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 . 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 ,
and
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 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 :)
I am going to build my whole website this way!!!!
jk.
lol This was a fun and interesting post!
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.
That is really impressive !!!!!
Thanx a lot for sharing
We *can* stack pseudo-elements, but it’s not supported by any browser yet :( http://www.w3.org/TR/css3-content/#inserting0
You’re right, I kinda ignored Chris’s initial question. Luckily other people like you are willing to answer the poor man ;)
Ah, Necolas beat me to it :)
Well technically, we can’t, but there is a proposal to allow such a thing
Nice one! Not that I’m about to use it, but interesting anyway!
You are a genius ;) Great.
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! ;]
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. ;)
I think this is a nice use-case with before/after:
http://matthamm.com/box-shadow-curl.html
cheers.
Here’s a slightly different version of the same effect: http://jsfiddle.net/simurai/FrspS/
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.)
Cool stuff, very interesting
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?
Does this mean the end of HTML ?
HTML0
What the?
“But it’s almost 2011, who’s still using XHTML anyway?”
Haha! I love it!
if only…
This is pretty cool. Could you apply this as a fallback for flash object that don’t load for agents like ipads ect.
haha Flash.
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.
Just a matter of debug tools getting better. Web Inspector shows and can alter pseudo elements now.
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
There is a lot of things happening behind the scenes of the web, and that is one of them.
Nice Trick.
Impressive. Simply, impressive!
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.
HA! Interesting…thanks! This makes me want to play…
Greaat…
It’s 2011. Everyone SHOULD be using XHTML.
What about the other browser if this technique is not useful for them ?
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?
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.
XHTML takes away your freedoms!
You do know that something new came into our world after XHTML, right?
@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.
@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 ♥
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.
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.
@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
How is that an argument in favor of XHTML? You could say the exact same thing about HTML 4.01.
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/
It is really great !
Nice, but it has nothing to do with semantic structured content.
What?
Haha, really nice idea. =)
If this is us experimenting, just imagine what the guru’s of W3C have come up with.
Excellent Article with Great Examples.
i did this ages ago, too bad i don’t have a blog
That’s so cool!
What else could we strip out just for fun?
you could eliminate the need for a stylesheet altogether, along with the browser-generated markup, by serving all your content in PDFs
Nice!
It is really great !
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 ;-)
Nice trick. Quite informative.
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.
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.
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.
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.
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.
This was fun! Still Chris is right: don’t use this for real websites…not to mention SEO and stuff :)
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.
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.
what’s u all aspects from HTML5
Great Article! It would be interesting building a whole site in this manner.
Sweet – New tricks rock!! Loved It :-)
lol only problem though is that this can be on one page only.
You’ve done another great job chris!
-waiting to have another screencast!
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..
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
Nice! Thanks for sharing!
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>
Jhakkaas!