Pull to refresh

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

По вашим же ссылкам у Firefox стоит 2022 год, а у «Respects color-scheme inherited from parent» вообще сентябрь 2024 и до сих пор не поддерживается в Safari

В любом случае, у меня до сих пор есть живые пользователи Firefox 56, так что для меня даже сам prefers-color-scheme в пролёте 🙃

Вообще, :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. Использую при разработке веб-приложений.

Идея библиотеки в том, что работу со схемами можно разделить на три части:

  1. Ловить событие смены системной цветовой схемы.

  2. Установление и сохранение постоянных настроек пользователя приложения (используется localStorage). Предпочтения auto, dark, light.

  3. И есть возможность переключать схему для текущей сессии работы в приложении, без запоминания, пока открыто окно (используется 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, кстати, врут: они по неизвестной мне причине не захватывают чёрный экран, который я вполне отчётливо вижу

Так что пусть будет ещё одна гифка

Может и врут картинки на вкладке Performance. Я ещё гляну. Интересно же.

Буквально несколько дней назад зашёл на сайт одного стартапа по парсингу Telegram каналов

Админка зацепила взгляд аккуратным оформлением и очень приятным шрифтом (нейтральный, легкочитаемый, привычный)

Через F12 полез смотреть... оказался system-ui :)

Поддержка ключевого слова system-ui очень хорошая

Нужно еще учитывать особенность Safari, он не применит этот шрифт к некоторым элементам внутри веб-компонентов (если они используются), я обхожу это так:

* {
  font-family: "Roboto", system-ui;
}

Интересно. Тут речь идёт об элементах внутри shadow dom? Или же о текстовых нодах внутри кастомных тегов?

Об элементах внутри shadowDom. Я ловил в элементе label и в плейсхолдеров в инпутах.

    <input type="password" id="pw" enterkeyhint="send">	
    <button>Отправить</button>

Почему enterkeyhint у input, а не button?

Хороший вопрос. Спасибо. У меня нет ответа. Мне кажется, что в моем примере атрибут надо указывать у последнего поля ввода. Я как-то не думал, что его можно к 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.

Как-то так.

Sign up to leave a comment.