The <time> element should actually do something
76 points by nolan
76 points by nolan
Note: I’m assuming some Tooltip component written in your favorite framework, e.g. React, Svelte, Vue, etc. There’s also the bleeding-edge popover="hint" and Interest Invokers API, which would give us a succinct way to do this in native HTML/CSS.
AAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!1
<span title="tootltip">some stuff</span>
my life
I didn't mention title because 1) it has serious accessibility issues and 2) it's kind of ugly. But yes it works okay in a pinch.
This is one of several confusing accessibility sections on MDN. title is literally an accessibility feature. Screen readers do read it. Yes you can't see it on mobile because.... It's a tooltip? Obviously don't put things that should be visible without hover in it.
And ugly? It uses the OS tooltips. Maybe the OS should be less ugly?
AIUI screen reader support is patchy at best. And yes touchscreen users and keyboard users cannot use it.
I would love for title to be more broadly usable, but sadly we don't seem to live in that world.
The reason touchscreen and keyboard users can’t see tooltips is because tooltips are bad UX for touchscreen users. Don’t write your own bad UX to undo that.
If you want a tooltip everyone can use, you don’t want a tooltip, you want some other affordance.
It's so annoying that implementations screw up accessibility of simple features, so then the platform has to add more complex features to compensate, and then every website has to individually reimplement the behavior that the browser should have had all along.
The biggest issues of title are that they're tooltips... amusingly I wrote a blog post about pretty much just this in March of this year too:
https://dpldocs.info/this-week-in-arsd/Blog.Posted_2025_03_03.html#tip-of-the-month
I rant about tooltips in the context of using them for time! But yeah, if you're doing <time> element specifically, the attribute does feel redundant, especially if you do what my blog said and just put the text up there (the example I used there was " just show "2025-02-27 (Yesterday)". ") but that's ok if it is a bit redundant, I still say html is a kind of api so having formatted data is nice and like I said in my other comment too, you can use it in some progressive enhancement javascript or user css as well. Even if the browser doesn't do anything, you can use it yourself sometimes.
title must be only a plain string. The Popover API lets you use HTML inside the tooltip. Also, title does not work on focus.
But for time both are irrelevant. A UA should just parse the datetime attribute and produce whatever the user expects.
Do you really have to yell? A tooltip is not the same thing as a popover. And that's kinda not what the article is about.
I think the frustration being expressed - one which I share - is that front-end developers seemingly do not care to let the user-agent do what it's supposed to do and instead implement complicated site-specific workarounds and functionality which break all too often and slow down the website.
And that's kinda not what the article is about.
The article is about having the browser do more with the semantic information given to it via the time tag. Makes it even more frustrating to be honest.
Some of the credit for this also goes to the subset of designers and product owners who insist that, say, a web app's drop-down menus need to be pixel-perfect implementations of an immutable, word-of-God Figma mockup; if the browser's built-in controls can't get it quite right, then obviously the only possible remaining option is to implement a custom drop-down menu, accessibility and maintainability be damned.
One cute thing you can do is make a css rule to display attributes as content too. For example, you could do time::after { content: attr(datetime); } and then it'll show it next to it. But you'd probably want to format it differently, a little script on load could let the browser localize it, like set the title attribute to element.setAttribute("title", new Date(element.getAttribute("datetime").toString();). since the Date toString localizes by default for the user, and then title automatically does a hover tooltip.
of course yeah would be nice if the browsers did a bit more by default too...
I think I heard Mozilla's Eemeli Aro talk about making <time> into an actual semantic time element this summer at Web Engines Hackfest.
On my blog I have a script which finds all time elements and replaces the content with a human friendly representation.
title attribute is set to a date formatted with the user's locale.Which is quite nice. But I agree that it really feels like something that should be built in. I told the browser what the time is, it should present it to the user in their preferred format (fully localized, user preference for using relative times, ...).
Before the time element does anything, it should probably mean something. Right now it is basically just a type hint. But what does the time mean? On its own, there is no semantic meaning behind it like published date / edit date / etc.
Schema.org itself supports using the itemprop attribute with the time element
Yes. I screamed when the author said “not even HTML”. HTML can apply ontologies from ANYWHERE (wikidata.org had a lot of them, and so do other WikiBase-powered projects) just fine with the item and itemprop attributes.
I have a project that displays timestamps relative to the current time, uses the title attribute to display the absolute time (converted to the user's local timezone), and allows the element to be clicked to toggle between displaying local time and relative time. It's pretty generic and should be easy to use on other sites. It's useful for both casual users and power users who want more info.
I also set a CSS cursor to "wait" if the user hovers before the code runs or if an error happens and the conversion doesn't occur.
For a demo click the "created" timestamp on this page: https://rfchub.app/rfchub/rfc1-org-batch-markdown-exporter-job
Note that it requires the date-fns library.
And here's the code:
<!-- the server sends the UTC date and the expected format -->
<time datetime="2025-11-13T04:13:52.330Z" format="LLL d u HH:mm">Nov 13 2025 04:13</time>
// call updateTimeElementsToBeLocalTime(el) when content updates
const time_units = {
year : 24 * 60 * 60 * 1000 * 365,
month : 24 * 60 * 60 * 1000 * 365/12,
day : 24 * 60 * 60 * 1000,
hour : 60 * 60 * 1000,
minute: 60 * 1000,
second: 1000,
};
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
function getRelativeTime (d1, d2 = new Date()) {
const elapsed = d1 - d2;
// "Math.abs" accounts for both "past" & "future" scenarios
for (const u in time_units) {
if (Math.abs(elapsed) > time_units[u] || u === 'second') {
return rtf.format(Math.round(elapsed/time_units[u]), u);
}
}
}
function updateTimeElementsToBeLocalTime(root = document.body) {
try {
const $times = $$('time', root);
for (let $time of $times) {
if ($time.classList.contains('localized')) return;
if (!$time.attributes.format) continue;
const format = $time.attributes.format.value; // string dateFns format
if (format === 'iso') continue;
const iso = $time.dateTime; // string iso8601
const d = new Date(iso);
const local = dateFns.format(d, format);
$time.innerText = getRelativeTime(d);
$time.title = local;
$time.classList.add('localized');
$time.addEventListener('click', function(event) {
const swap = $time.title;
$time.title = $time.innerText;
$time.innerText = swap;
});
}
} catch (err) {
console.error('error attempting to localize timestamps', err);
}
}
window.updateTimeElementsToBeLocalTime = updateTimeElementsToBeLocalTime;
time {
cursor: wait;
text-decoration: underline #0006 dashed 1px;
text-underline-offset: 2px;
}
time.localized {
cursor: context-menu;
}
On my blog, I use time tags like this to show the publication time (yes I cheat on the dates):
<time datetime="2020-11-11T22:30:00+00:00">2020-11-11 22:30:00 UTC</time>
Then I use JavaScript to transform it to:
<time datetime="2020-11-11T22:30:00+00:00" title="2020-11-11 22:30:00 UTC">2020-11-11 23:30:00 CET</time>
My timezone handling is far from perfect but it's a start.