Trick: Use CSS to show dynamic text

· 385 words · 2 minute read

This page is a stub: I know almost nothing about CSS, and I tried to do some really wired things on my websites. I am also not the author of this trick. This post is to share the trick with others, probably just to show that “because we can” or “because I know”.

I am not a lover of JavaScript / TypeScript, at all. Aggresively, I want my websites to run flawlessly with JavaScript disabled. However, displaying server-generated text is still required. Doing server-side-rendering of the whole HTML document is too heavy: the backend has to read the file, parse templates, apply variables, and generate the output. Is there such a way that we can lift the weight of server-side-rendering? Fortunately, there is a trick to do with CSS. (Thanks to my friend Hykilpikonna for this smart idea.)

The answer is the CSS content property. It sets the content of an element. According to W3Schools: “The content property is used with the ::before and ::after pseudo-elements, to insert generated content.” To be honest, I do not know how to write CSS at all, but this trick still seems to work.

I can just let the server to generate a tiny CSS, containing some selectors on <p> elements, with ::before or ::after, to set the content property. Then, the text hard-coded will be surrounded with ::before and ::after texts in the CSS.

For example, I want my homepage to display the users’ IP address:

Frontend:

<link href='/ip.css' rel='stylesheet' type='text/css' /> 
<p class='ip'>You are visiting from: </p>

Backend:

location    /ip.css {
    add_header  Content-Type    "text/css; charset=utf-8";
    default_type    text/css;
    return      200     ".ip::after { content: \"$remote_addr\"; }";
}

Note: the CSS-inserted text seems not to be selectable by browsers.

Bonus: it is also possible to make a tiny page view counter using CSS alone, without JavaScript. I can just write a simple HTTP service (probably in C) that reads the path of the requested CSS and increase the view count by one, and return a new CSS that contains the updated view count. The frontend could use relative path CSS, so the current webpage’s path appears in the CSS request, which the backend could exploit to find the location of the page. Moreover, I can also add some caching-by-IP stuff in front of the backend, making the data more precise.