Comments 38
Если шрифт Roboto не загрузится, то браузеры применят шрифт Arial.
Браузеры применят тот шрифт, который выбран в их настройках
@media (prefers-color-scheme: dark)
Такая реализация не позволяет включить или выключить тёмную тему для отдельного сайта, поэтому так никто не делает
Браузеры применят тот шрифт, который выбран в их настройках
Спасибо за замечание.
Темная тема не получится что-ли, не рабочий код?
Такая реализация не позволяет включить или выключить тёмную тему для отдельного сайта, поэтому так никто не делает
Позволяет.
Добавляем checkbox
<input id="theme" type="checkbox" />
И еще немного CSS
:root:has(#theme:checked) {
color-scheme: dark;
/* */
}
:root:has(#theme:not(:checked)) {
color-scheme: light;
/* */
}
Нужно также иметь ввиду, что любое переключение темы через CSS/JS всегда будет конкурировать с настройкой ОС, что не всегда хорошо.
А поддержка color-scheme браузерами уже заметно хуже чем prefers-color-scheme
заметно хуже
Не так уж и заметно:
prefer-color-scheme с 30 июля 2019 г.
color-scheme c 7 апреля 2020 г.
Вообще, :root {color-scheme: light dark;} - эта история не про выбор цветовой схемы по умолчанию, а декларация того, что документ вообще поддерживает цветовые схемы на уровне системы.
Я к тому, что считаю верным отделять понятия цветовой схемы от цветовой палитры/темы.
:root { color-scheme: light dark; }
Такая инструкция говорит браузеру выбрать оформление в соответствии с оформлением на уровне ОС. Если на уровне ОС установлена темная тема, будет выбрано оформление dark
, и наоборот.
С одним аргументом она ограничивает использование цветовой схемы. Если указать так:
:root {
color-scheme: light;
}
То при изменении темы на уровне ОС, ui никак реагировать не будет, а оформление всегда будет light
. Пример тут https://codepen.io/s5604/pen/vEErMvL
Код из моего примера этим манипулирует:
:root:has(#theme:checked) {
color-scheme: dark;
}
:root:has(#theme:not(:checked)) {
color-scheme: light;
}
В этом случае оформление будет зависеть от состояния чекбокса, а при изменении темы на уровне ОС, ui реагировать не будет. Пример тут https://codepen.io/s5604/pen/jEEKoLQ
Для интереса откройте DevTools на странице https://codepen.io/s5604/pen/jEEKoLQ.
Далее, Rendering. Там есть опция Enable automatic dark mode. В случае если галочки нет на чекбоксе Change Theme, то при включении режима dark mode, цветовая палитра все-таки изменится (белый фон станет черным, текст белым и т.д.).
Поэтому я не совсем согласен, что оформление всегда будет light.
Так это ведь девтулзы, там много чего можно принудительно включить/выключить, чтобы потестить какое-то поведение. Как только девтулзы закрываются, это больше не работает.
Ну, может быть Вы и правы, что это дело в devtools. Я как-то потратил время, чтобы заставить все работать как надо даже при включенных тулзах, потому что думал, что где-то это вылезет потом в виде бага.
Вот тут можно глянуть пример: https://supercat1337.github.io/color-scheme/example/, библиотека тут https://www.npmjs.com/package/@supercat1337/color-scheme. Использую при разработке веб-приложений.
Идея библиотеки в том, что работу со схемами можно разделить на три части:
Ловить событие смены системной цветовой схемы.
Установление и сохранение постоянных настроек пользователя приложения (используется localStorage). Предпочтения auto, dark, light.
И есть возможность переключать схему для текущей сессии работы в приложении, без запоминания, пока открыто окно (используется sessionStorage). Тут уже dark или light. При этом если произошла смена цветовой схемы в системе, а постоянная настройка пользователя auto, то текущая тема изменится.
Ну и самое главное, что состояние чекбокса и настроек будет синхронизировано с настройками пользователя.
(используется localStorage)
Из чего неизбежно следует ослепление юзера белым экраном в момент начала загрузки страницы, пока значение из localStorage ещё не прочиталось — ваш пример больно бьёт по глазам
Нет, не следует. Для того чтобы страница начала загружаться с использованием текущей системной схемы, добавляется
<meta name="color-scheme" content="dark light">
Пример обновлен.
Не помогло, пример продолжает бить по глазам даже при включенной тёмной теме в настройках браузера
Вы точно кэш отчистили? Потому что я проверяю у себя, даже включаю режим загрузки в 3g. И все отлично.
Включен в системе темный режим.
Как только начинается загрузка страницы - темный экран. А далее поведение в зависимости от того, что там в настройках localstorage.
Хм, Firefox ведёт себя странно: при F5 моргает белым, а при Ctrl+F5 моргает чёрным. Ладно, буду считать это багом Firefox)
Но реализацию через JS и localStorage я всё равно осуждаю: если выбранная мной тема отличается от системной, страница всё равно будет моргать (например, чёрным) даже в Chrome
Под морганием мной подразумевается быстрое чередование цветов "белое - черное - белое" или же "черное - белое - черное". Может быть вы о чем-то другом говорите?
Потому что даже асинхронная загрузка библиотеки не вызывает никакого моргания.
Кейс 1. Светлая тема в системе, темная в настройках. Белая страница, потому что все приложения в светлом режиме, далее применяется темная тема из настроек, контент при этом продолжает загружаться в нужном цветовом оформлении.
Кейс 2. Темная тема в системе, темная в настройках. Темная страница при загрузке, далее применяется сохраненная темная тема. Ничего не моргает.
Кейс 3. Темная тема в системе, светлая в настройках. Темная страница при загрузке, далее применяется сохраненная светлая тема. Приложение себя ведет как планировал пользователь.
Кейс 4. В настройках пользователя стоит режим auto. Опять же и в этом случае не будет никаких морганий.
У вас какой кейс?
Потому что даже асинхронная загрузка библиотеки не вызывает никакого моргания.
Только потому что ваш пример очень маленький и ничего моргнуть в принципе не успевает.
Если же представить, что, например, скрипт на сервере обновился и нужно заново скачать его из интернета —
Всё замечательно моргает

Разбираем.
У вас светлая тема. При первом запросе к файлу html, на стадиях "Queuing and connection" и "Request sent and waiting", всегда будет отображение белого прямоугольника под страницу (браузер кстати тоже в светлом оформлении).
Когда системная тема темная, то и место в браузере под страницу будет черной сначала в любом случае.
Это нативное поведение браузера. Ничего с этим не поделать.
А вот когда уже начинается "Сontent downloading" и парсинг html, только тогда что-то вообще можно сделать (сервером сгенерить стиль, скрипт или мета-тэг).
А стоит ли игра свеч, если скрипт библиотеки весит 16 кб и 3.5 кб в gzip? Причем загрузка скрипта происходит с начала html файла, асинхронно, не блокирует основной поток.
То есть борьба за миллисекунды тут полностью неуместна, потому что вы всегда будете видеть дефолтный цвет системной темы при подготовке к загрузке любой страницы.
И еще, термин "бьет по глазам" уместно использовать тогда, когда у вас включен темный режим в системе и вдруг открывается что-то ярко-белое. Тогда да, можно "слепнуть". Но я выше показал, что в моем примере это не так.
При первом запросе к файлу html
Именно поэтому на гифке я захватил второй запрос, а не первый
А стоит ли игра свеч, если скрипт библиотеки весит 16 кб и 3.5 кб в gzip?
Сравните с Хабром: тема хранится в куках и задаётся бэкендом напрямую в html-коде — скрипт весит 0 байт, потому что JS здесь вообще не задействован. А так как браузеры ждут завершения загрузки стилей — никаких мерцаний на Хабре нет
вы всегда будете видеть дефолтный цвет системной темы
На Хабре — не вижу по вышеупомянутой причине
Темная тема на Хабре. Стало интересно, что же там за технология.
<link rel="preload" href="https://assets.habr.com/habr-web/css/theme/dark-v1.css" as="style">
<link id="dark-colors" rel="stylesheet" href="https://assets.habr.com/habr-web/css/theme/dark-v1.css" media="all"/>
Когда включен в системе светлый режим, а на Хабре темный, то при первом и последующих запросах сначала будет белая страница, а потом уже черная, которая является результатом примененного css. В этом можно убедиться при внимательном просмотре вкладке Perfomance, там есть скриншоты по кадрам.

сначала будет белая страница
Нет, не будет.
В моей вкладке Performance никаких белых скриншотов нет и страница всегда чёрная при светлой системной теме
Хотя в Firefox имеется очень интересное сообщение в консоли:
Макет был принудительно применён перед полной загрузкой страницы. Если таблицы стилей ещё не загружены, то это может спровоцировать отображение нестилизованного содержимого.
Видимо, если скрипт успеет загрузиться раньше стиля и стриггерит force reflow — тогда уже появляется шанс увидеть белую страницу. Поэтому не надо говнокодить в скриптах 🙃
Но в Chrome даже такого нет, страница ВСЕГДА чёрная (при всё ещё светлой системной теме)
Скриншоты на вкладке Performance, кстати, врут: они по неизвестной мне причине не захватывают чёрный экран, который я вполне отчётливо вижу
Так что пусть будет ещё одна гифка

Буквально несколько дней назад зашёл на сайт одного стартапа по парсингу Telegram каналов
Админка зацепила взгляд аккуратным оформлением и очень приятным шрифтом (нейтральный, легкочитаемый, привычный)
Через F12 полез смотреть... оказался system-ui
:)
в плане темы и ее цветов есть css-функция light-dark - это еще проще
Поддержка ключевого слова
system-ui
очень хорошая
Нужно еще учитывать особенность Safari, он не применит этот шрифт к некоторым элементам внутри веб-компонентов (если они используются), я обхожу это так:
* {
font-family: "Roboto", system-ui;
}
<input type="password" id="pw" enterkeyhint="send">
<button>Отправить</button>
Почему enterkeyhint у input, а не button?
Удивительно, что несмотря на обилие подобных статей, 99% интерфейсов становятся хуже с примерно каждым обновлением.
В CSS есть ключевое слово
system-ui
. Оно позволяет нам использовать для веб-контента шрифт, который встроен в операционную систему. В большинстве случаев он будет намного красивее.
Или не будет. Вообще, задумка system-ui
в том, что он стилизует элемент страницы под "нативный". Хорошо это или нет - наверное, зависит от конкретной ситуации.
Например, csswg описывает это так:
The purpose of system-ui is to allow web content to integrate with the look and feel of the native OS.
MDN, внезапно, делает фокус на другом аспекте - использовать этот дженерик, если другие не подходят по смыслу (то есть если ваш основной шрифт нельзя отноести строго к serif или sans-serif или другим поддерживаемым дженерикам)
this generic is provided for typefaces that don't map cleanly into the other generics.
Как-то так.
Как фронтендеру сделать интерфейс дружелюбнее к пользователю. Коллекция HTML/CSS лайфхаков