Open Crissov opened 7 months ago
Note that this approach still allows some fingerprinting depending on when exactly the media query matches.
Imagine this:
@custom-media --monday (day: Monday) {
background-image: url('https://example.com/timetracker');
}
So https://example.com/timetracker
will be called in the second when the user's local date switches from Sunday to Monday. Based on that you can infer their longitudinal location with such media features.
Nonetheless, I still like the idea of date- and time-based media queries.
@tabatkins wrote in the other issue:
I've virtually never seen any site trying to theme itself in such a way
Here's one:
That site is in light mode from 8am to 6pm and switches to dark mode, otherwise. It also styles its logo for Pride Month, which was another seasonal use case mentioned by @teh-maxh in the other issue. Similarily, many websites style their logos or parts of their contents for different recurring events like Christmas, Hanukkah, carnival, etc. (@Crissov named a lot more).
So there are a lot of use cases for having such media features, which, I believe, justify an integration into CSS.
And if it's not something the group considers important enough to integrate into CSS directly, it could still be achieved via script-based custom media queries.
As @frivoal wrote in the other issue:
I encourage people who want this sort of things to contribute proposals to make https://drafts.csswg.org/mediaqueries-5/#script-custom-mq more than a rough sketch.
Here's an example for how a script-based CSS variant could look like for the page I mentioned above:
JS:
setInterval(() => {
const currentHour = new Date().getHours();
CSS.customMedia.set('--dark-mode-time', currentHour >= 18 && currentHour < 8);
}, 60000);
CSS:
body {
background-color: #fafafa;
color: #1a1d20;
}
@media (--dark-mode-time) {
body {
background-color: #1a1d20;
color: #e3e4e5;
}
}
Sebastian
Unfortunately, many holidays that authors would use this for, do not have simply fixed annual dates in the Gregorian calendar, e.g. Chinese New Year, US Thanksgiving, Orthodox Easter. With a simple year
, month
, day
solution, authors would need to maintain a comprehensive list of explicit dates.
Also, it is common to apply a styling for the tide leading up to the holiday, not just in the date itself.
PS: I believe for dark mode we have better solutions that respect the user preference.
Unfortunately, many holidays that authors would use this for, do not have simply fixed annual dates in the Gregorian calendar, e.g. Chinese New Year, US Thanksgiving, Orthodox Easter. With a simple
year
,month
,day
solution, authors would need to maintain a comprehensive list of explicit dates.
Yes, that's true. Though as @frivoal pointed out in #4627, there's no way to provide a built-in, exhaustive solution for that. Though giving a way query the date and time, as you suggested, makes fixed-date use cases easily possible. And for events that have dynamic dates, authors can fall back to script-based custom media queries.
E.g. the date for Easter is calculated via a complicated formula. For the Gregorian calendar, this might look like:
JS:
function calculateEasterDay(year) {
const a = year % 4;
const b = year % 7;
const c = year % 19;
const d = (19 * c + 24) % 30;
const e = (2 * a + 4 * b + 6 * d + 5) % 7;
const f = Math.floor((c + 11 * d + 22 * e) / 451);
let day = 22 + d + e - 7 * f;
if (day <= 31) {
return new Date(year, 2, day);
} else {
day = d + e - 7 * f - 9;
return new Date(year, 3, day);
}
}
function isTodayEasterDay() {
const currentDate = new Date();
currentDate.setHours(0, 0, 0, 0);
const easterDayDate = calculateEaster(currentDate.getFullYear());
return currentDate === easterDayDate;
}
CSS.customMedia.set('--easter-day', isTodayEasterDay());
CSS:
@media (--easter-day) {
body {
background-image: url('easter-eggs.svg');
}
}
Also, it is common to apply a styling for the tide leading up to the holiday, not just in the date itself.
Yeah. Very common for Advent season, for example, which we're in right now. For such timespans, the same rules as above apply.
For those, we probably want to express date spans using the range syntax of media features. The same for time spans. Examples for that:
@media (month: 12) and (1 <= day <= 24) {
body {
background-image: url('christmas-decoration.svg');
}
}
@media (2023-11-20 <= date <= 2023-11-26) {
.event-price {
background-image: url('black-friday.svg');
}
}
@media (10pm <= time <= 4am) or (22:00 <= time <= 04:00) {
.logo {
background-image: url('night-owl-logo.png');
}
}
Talking about dates and times, the issues I can see are the focus on the Gregorian calendar and the format in which they are expressed.
PS: I believe for dark mode we have better solutions that respect the user preference.
Absolutely agree. I just took the example from that page which uses fixed times.
Sebastian
I'm somewhat skeptical (though I could certainly be wrong) that a feature like this would be widely used given the way it makes styles harder to test. I suspect many developers would prefer to push changes around specific dates when they want different styles, because those changes can be more easily tested in advance of pushing them.
In #4627 I entertained the idea of date-dependent styles, primarily in order to allow for holiday theming.
Respondents mostly agreed that this could be useful, but would easily turn into a privacy nightmare.
@frivoal suggested, pointing to Custom MQs:
I’m proposing the first item since I believe authors should not need to use JS to achieve that.
Although I think styling by time of day might even be more popular, it also is more prone to fingerprinting.