Никита Дубко, Яндекс
            Никита Дубко
            разработчик интерфейсов, Яндекс
        
    
    
            
            
            
            
            
            
    
    
    
    
    
    
    
    
    
    
    
        
    
        
    
    
    
    
        RG|Blue Light Hazard
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
    
    
        
    
    
    
    
    
    html[data-theme='dark'] {
    --hue: 210; /* Blue */
    --accent-hue: 25; /* Orange */
    --text-color-normal: hsl(var(--hue), 10%, 62%);
    --text-color-light: hsl(var(--hue), 15%, 35%);
    --text-color-highlight: hsl(var(--accent-hue), 70%, 45%);
    --link-color: hsl(var(--hue), 90%, 70%);
    --accent-color: hsl(var(--accent-hue), 100%, 70%);
    --error-color: rgb(240, 50, 50);
}
        Dark theme in a day
    html.theme-in-transition,
html.theme-in-transition *,
html.theme-in-transition *:before,
html.theme-in-transition *:after {
    transition: all 750ms !important;
    transition-delay: 0 !important;
}
        Dark theme in a day
    const target = document.documentElement;
target.classList.add('theme-in-transition')
target.setAttribute('data-theme', theme)
window.setTimeout(function() {
    target.classList.remove('theme-in-transition')
}, 1000)
        Dark theme in a day
    
    
    
        Переключатель темы
    :root {
    background-color: #fefefe;
    filter: invert(100%);
}
* {
    background-color: inherit;
}
img:not([src*=".svg"]), video {
    filter: invert(100%);
}
    
    if ("geolocation" in navigator) {
    /* геолокация доступна */
} else {
    /* геолокация НЕдоступна */
}
        Использование геолокации
        
    navigator.geolocation.watchPosition(function(position) {
    const sunTimes = getSunTimes(
        position.coords.latitude,
        position.coords.longitude
    );
    setDarkThemeState(sunTimes);
});
    function getSunTimes(latitude, longitude) {
    const times = SunCalc.getTimes(
        new Date(), latitude, longitude
    );
    return {
        sunrise: times.sunrise,
        sunset: times.sunset
    };
}
        github.com/mourner/suncalc
    function setDarkThemeState({ sunset, sunrise }) {
    const now = new Date();
    const toMinutes = (d) =>
        d.getHours() * 60 + d.getMinutes();
    if (toMinutes(now) <= toMinutes(sunrise) ||
        toMinutes(now) >= toMinutes(sunset)) {
        setDarkTheme();
    } else {
        setLightTheme();
    }
}
    function setDarkThemeState() {
    const now = new Date();
    if (now.getHours() < 6 ||
        now.getHours() >= 18) {
        setDarkTheme();
    } else {
        setLightTheme();
    }
}
    
    :root {
    --body-bg: #fafafa;
    --body-color: #555;
}
@media (prefers-color-scheme: dark) {
    :root {
        --body-bg: #212529;
        --body-color: #6c757d;
    }
}
        New WebKit Features in Safari 12.1
    /* Any of Windows’ High Contrast Mode themes: */
@media screen and (-ms-high-contrast: active) { }
/* Windows’ "High Contrast Black" theme: */
@media screen and (-ms-high-contrast: white-on-black) { }
/* Windows’ "High Contrast White" theme: */
@media screen and (-ms-high-contrast: black-on-white) { }
        Accessible SVGs in High Contrast Mode
    <meta
    name="supported-color-schemes"
    content="dark">
        What Does Dark Mode’s “supported-color-schemes” Actually Do?
    html.dark img {
    opacity: .75;
    transition: opacity .5s ease-in-out;
}
html.dark img:hover {
    opacity: 1;
}
        CSS dark mode
    <picture>
    <source media="(prefers-color-scheme: dark)"
            srcset="dark.jpg">
    <img src="light.jpg"
         alt="И так можно!">
</picture>
    window.addEventListener("devicelight", function (event) {
    var luminosity = event.value;
    // 10 ~ 50 lux : тусклое освещение
    // 100 ~ 1000 lux : нормальное
    // > 10000 lux : яркое
});
        Using light sensors
    if ('AmbientLightSensor' in window) {
    const sensor = new AmbientLightSensor();
    sensor.onreading = () => {
        console.log('Светит на ' + sensor.illuminance);
    };
    sensor.onerror = (event) => {
        console.log(event.error.name, event.error.message);
    };
    sensor.start();
}
        developer.mozilla.org/en-US/docs/Web/API/AmbientLightSensor
    navigator.getBattery().then(function(battery) {
    battery.addEventListener('chargingchange', function(){
        console.log("Заряжаемся? "
            + (battery.charging ? "Да" : "Нет"));
    });
    battery.addEventListener('levelchange', function(){
        console.log("Уровень батареи: "
            + battery.level * 100 + "%");
    });
});
    navigator.getBattery().then(function(battery) {
    battery.addEventListener('chargingtimechange', function(){
        console.log("Время до зарядки: "
            + battery.chargingTime + " с");
    });
    battery.addEventListener('dischargingtimechange', function(){
        console.log("Время до разрядки: "
            + battery.dischargingTime + " с");
    });
});
        Battery Status API
        
    
        github.com/darkreader/darkreader
    
    
    Гигиена детей и подростков. Гигиенические требования к изданиям книжным и журнальным для детей и подростков
Электронный фонд правовой и нормативно-технической документации
    
    
        
            mefody.github.io/talks/dark-themes/
            
            @dark_mefody
            
            mefody@yandex-team.ru