Lately I am updating my software to support dark mode, in response to research that looking at a paper-white background display is bad for the eyes and for sleep rhythms. Is
Unfortunately the dark mode detection methodology does not exist for server side-processing (including PHP).
All efforts thus-far by the W3C (and its sponsors) has been focused on client-side / Jamstack, and the Media Queries Level 5 specification uses a prefers-color-scheme
media query for detection. This useful in both CSS and JavaScript.
There is a recommendation by Thomas Steiner (@DenverCoder9) from Google to implement a Proposed server-side client hint, but this has not been adopted (yet?) by the W3C or the browsers.
Either way - there is a significant drawback in server-side detection (both with Thomas' recommendation and my solution below) in that the server will only know about a state change (e.g. macOS "Auto" mode when night fall happens) on the next server request, or more visibly, the first load of the page.
The recommendation is to leave this detection on the client and projects like vinorodrigues/bootstrap-dark show how easy that can be - without server-side processing.
Having said that - there is a workaround:
The most efficient way is to leverage the js-cookie/js-cookie project, and include the following code into your HTML pages:
<script src="https://cdn.jsdelivr.net/npm/js-cookie/dist/js.cookie.min.js"></script>
<script>
// code to set the `color_scheme` cookie
var $color_scheme = Cookies.get("color_scheme");
function get_color_scheme() {
return (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) ? "dark" : "light";
}
function update_color_scheme() {
Cookies.set("color_scheme", get_color_scheme());
}
// read & compare cookie `color-scheme`
if ((typeof $color_scheme === "undefined") || (get_color_scheme() != $color_scheme))
update_color_scheme();
// detect changes and change the cookie
if (window.matchMedia)
window.matchMedia("(prefers-color-scheme: dark)").addListener( update_color_scheme );
</script>
And then your PHP will detect this cookie like this:
$color_scheme = isset($_COOKIE["color_scheme"]) ? $_COOKIE["color_scheme"] : false;
if ($color_scheme === false) $color_scheme = 'light'; // fallback
Which you can use to load the CSS:
// Load the CSS for the correct color-scheme
if ($color_scheme == 'dark') {
?><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vinorodrigues/bootstrap-dark@0.0/dist/bootstrap-night.min.css"><?php
} else {
?><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0.css/bootstrap.css"><?php
}
Or, like this:
?>You are in <?= $color_scheme ?> mode.<?php
Since PHP executes on the server without any knowledge of the client, there is no direct way of finding this out.
If it is possible to detect the color mode in JS, you could embed a small JS script to your site, that sets a cookie. Cookies are transmitted to the server on request, so PHP is able to query them.