Using date-based CSS to make old web pages *look* old
How do you know you're looking at an old website? You may have found a page which has lots of interesting information, but how can you tell it's a modern and relevant result?
Some websites don't contain dates in their URls. There may not be a © date or publication date shown on the page. And the <meta>
tags might not contain anything useful. If you're lucky, the site will look old fashioned:
Unlike the BBC, most sites have adopted the "Eternal CSS" pattern. When fashions change, the entire site gets a facelift - which means ancient articles look modern. This can mislead readers into thinking old information is new.
Here's (one way) this can be fixed - inspired by Moriel Schottlender fabulous historic CSS selector.
Get the page's publication date
A page might have a date published on it. For example:
HTMLPublished on <time id="published" datetime="2005-02-14">Valentine's Day</time>
CSS has an attribute selector which can see the year encoded in that datetime
:
[attr|=value]
Represents elements with an attribute name of attr whose value can be exactly value or can begin with value immediately followed by a hyphen,-
(U+002D). It is often used for language subcode matches.
That means, the element can be styled based on its year. For example, make the year 2005 green, and the year 2006 blue:
CSStime[datetime|="2005"] {
color: green;
}
time[datetime|="2006"] {
color: blue;
}
That's fine for styling a specific element, but using the CSS property has()
it is possible to set variables based on the date. For example, this code sets a variable which can be used anywhere on the page:
CSS:root:has( time[datetime|="2005"] ) {
--timeColor: green;
}
:root:has( time[datetime|="2006"] ) {
--timeColor: blue;
}
p {
color: var(--timeColor);
}
(Note that has()
is only available in Chrome. It is coming soon to Firefox.)
Variables from Metadata
If the published date is in the metadata, rather than the body, it can still be used in CSS. This is how WordPress adds the original published date to a page's <head>
:
HTML<meta property="article:published_time" name="article:published_time" content="2007-11-16T12:34:41+00:00" />
The date can be accessed and used to set specific variables depending on the year:
CSS:root:has( [name="article:published_time"][content|="2007"] ) {
--font: "Old Fashioned";
--bgColor: green;
--fontColor: red;
...
}
:root:has( [name="article:published_time"][content|="2023"] ) {
--font: "Modern";
--bgColor: white;
--fontColor: black;
...
}
Using this pattern, it is possible to have a single style-sheet which has a different look and feel depending on the age of the article.
Imagine that! You could set old pages to have a 1990's look and feel while keeping modern markup.
Maths limitations
It isn't yet possible to use the attr()
CSS Function to get the date. And it is impossible to do if/else or use less than / greater than in CSS.
But we can cheat!
A variable can be set depending on the year published:
CSS:root:has( [name="article:published_time"][content|="1998"] ) {
--publishedYear: 1997;
}
:root:has( [name="article:published_time"][content|="1999"] ) {
--publishedYear: 1999;
}
:root:has( [name="article:published_time"][content|="2000"] ) {
--publishedYear: 2000;
}
...
That pattern can be repeated as far back as your site goes - and as far forward as you think you'll still be publishing.
CSS has no access to the computer's datetime functions - that requires JavaScript. But if the website does expose the date it was generated, it should be possible to calculate the age of the page.
For example, if the <body>
contains:
HTML<time id="RomanYear" datetime="2023">ⅯⅯⅩⅩⅠⅠⅠ</time>
The year can be turned into a variable using a similar pattern:
CSS:root:has( #RomanYear[datetime|="2023"] ) {
--currentYear: 2023;
}
:root:has( #RomanYear[datetime|="2024"] ) {
--currentYear: 2024;
}
:root:has( #RomanYear[datetime|="2025"] ) {
--currentYear: 2025;
}
...
It is then possible to use the calc()
CSS function to calculate the age of the page:
CSS--age: calc( var(--currentYear) - var(--publishedYear) );
From this, it's possible to work out how old the page is as a percentage of the site's history. For example, if the earliest publication on the site is from 2001:
CSS--oldestYear: 2001;
--currentYear: 2023;
--publishedYear: 2014;
--siteAge: calc( var(--currentYear) - var(--oldestYear) ); /* 16 */
--pageAge: calc( var(--currentYear) - var(--publishedYear) ); /* 9 */
Finally, a sepia filter can be placed over the page - with its intensity higher the older a page is.
CSS--percentAge: calc( var(--pageAge) / var(--site-age) );
--filterRatio: calc( var(--percentAge) );
filter: sepia( var(--filterRatio) );
What's next
What will you do with this forbidden information?
Jon Hicks said on mastodon.social:
@Edent I love this! If I had the energy I would love to re-implement the relevant site designs to my older blog articles.
🎄 Sex, Drugs, and Glühwein 🎅🍷 said on bsky.app:
ha, nice hack
sam henri gold said on hachyderm.io:
@Edent This is brilliant
Jeff Sikes said on mastodon.social:
@Edent I had no idea! Great little trick. Could be used to identify old content in search results, conference events occurring in the past on a listings page, highlight current work sections on a resume…lots of thoughts.
Eric says:
In the "Maths limitations" section, there's a nice example of a limitation of cheating: the code is wrong for 1997/98. The code looks for things published in 1998 but then assigns the CSS variable to be 1997. Cool concept though.
Ryan Castellucci :nonbinary_flag: said on infosec.exchange:
@Edent Delightfully cursed.
dwm said on mastodon.social:
@Edent Yes! But also: no.
Alaric Snell-Pym said on fosstodon.org:
@Edent that's a fun idea, but I cannot condone that CSS hackery 🤣Much nicer to make the server put out differing CSS based on antiquity, if it can put today's date in it should be able to do that! Plenty of software is unable, though, I'm sure...
More comments on Mastodon.