Как стать автором
Обновить

Как фронтендеру сделать интерфейс дружелюбнее к пользователю. Коллекция HTML/CSS лайфхаков

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров12K
Всего голосов 78: ↑77 и ↓1+95
Комментарии40

Комментарии 40

Если шрифт 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 г.

По вашим же ссылкам у 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. Я ещё гляну. Интересно же.

так никто не делает, потому что единицам юзеров надо поиграться со схемой сайта.

Если дизайнер сам цвета выставлял, если это не глючное расширение, которое не правильно инвертирует цвета , то юзер для себя решил 1 раз в жизни, что ему надо DARK or LIGHT. И кнопка действительно, только поиграться.

Браузер смотрит на эту строку, и указанный порядок. Работает и "only".

<meta name="color-scheme" content="dark light">

Большинство сайтов без всяких кнопок. В каждом браузере есть кнопка "DARK MODE для сайтов" (и тема для самого браузера, это отдельно)

Уже есть куча сайтов, не самый последних, с простой схемой (adele.com):

<meta name="theme-color" content="#000000" />

<style>

html, body{

background-color:#000;

color:#fff;}

</style>

И никакого интерактива и схем.

27% ? На каком-то сайте был опрос (не мертвая подделка , бери голосуй ).

Результат : DARK MODE = 85%.

Кстати, сам habr.com имеет Светлую Схему ? Я не могу ее включить. И браузер в Светлой Схеме отображает habr.com чуть неверно, пропадает мелочь.

Это лучшая рекомндация. Со LIGHT MODE на Земле можно заканчивать. Время Steve  Jobs ушло.

Буквально несколько дней назад зашёл на сайт одного стартапа по парсингу 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.

Как-то так.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий