Подключение шрифтов
Иногда в исходниках проектов, даже свежих, можно обнаружить примерно такой код:
Такой сниппет может повторяться для каждого семейства шрифта, толщины и стиля. Сопровождается это папкой
Но подобный сниппет уже устарел, сейчас нет необходимости в таком количестве разных шрифтов. Далее ряд рекомендаций по подключению шрифтов.
1) не используйте
2) достаточно формата
3) указывайте одинаковое имя семейства в
4) указывайте способ отображения шрифта. В
5) не подключайте шрифты с Google Fonts через
6) создавайте подмножества (subsetting) шрифтов в сочетании со свойством
7) подключайте основной шрифт в HTML при помощи
8) предварительно загрузите основной шрифт при помощи
9) используйте вариативные шрифты. Файл с вариативным шрифтом хоть и весит больше, но если вариаций шрифта слишком много, то вариативный шрифт обеспечит выигрыш по размеру.
Также ссылки для чтения:
- Best practices for fonts
- Optimize web fonts
- Статьи Зака Лезермана про шрифты
Иногда в исходниках проектов, даже свежих, можно обнаружить примерно такой код:
@font-face {
font-family: 'Roboto Regular';
font-style: normal;
font-weight: 400;
src: local('Roboto'),
url('roboto-regular.eot?#iefix') format('embedded-opentype'),
url('roboto-regular.woff2') format('woff2'),
url('roboto-regular.woff') format('woff'),
url('roboto-regular.ttf') format('truetype'),
url('roboto-regular.noscript#Roboto') format('noscript');
}Такой сниппет может повторяться для каждого семейства шрифта, толщины и стиля. Сопровождается это папкой
fonts с десятом шрифтов разных форматов. Ноги растут из онлайн-генераторов, например, шрифтобелки. На вход поступают шрифты в формате ttf. Далее происходят тонкие настройки, смысл которых понимают только специалисты по шрифтам. На выходе получается архив с готовым CSS и той самой папкой fonts. Это удобно, потому что руками так делать не хочется.Но подобный сниппет уже устарел, сейчас нет необходимости в таком количестве разных шрифтов. Далее ряд рекомендаций по подключению шрифтов.
1) не используйте
local(). Эта функция пытается найти зарегистрированный в операционной системе шрифт и использовать его. На первый взгляд хорошая идея: экономим трафик, не ходим в сеть, переиспользуем ресурсы, быстрее отображаем текст. На практике же с local() много проблем. Шрифт может быть зарегистрирован под другим названием, на устройстве может быть другая версия шрифта, также локальные шрифты используются для фингерпринтинга.2) достаточно формата
woff2. Времена, когда нужны шрифты разных форматов, уже прошли. Все браузеры умеют работать с woff2. На данный момент это самый эффективный формат шрифта для веба, который должен использоваться по умолчанию. Если нужно поддерживать IE, то к woff2 можно добавить woff. Но не нужно генерировать, хранить и подключать noscript, eot, ttf и другие менее эффективные и старые форматы.3) указывайте одинаковое имя семейства в
font-family и разные значения font-weight и font-style. Не нужно называть шрифт одного семейства разными именами, например 'Roboto Regular' и 'Roboto Bold'. Назовите оба 'Roboto', а в font-weight и font-style отразите различия. Браузер сам определит, какой шрифт применить, без необходимости каждый раз указывать font-family.4) указывайте способ отображения шрифта. В
@font-face укажите свойство font-display со значением swap, optional или fallback, в зависимости от целей. Это важно для увеличения скорости загрузки, предотвращения сдвигов макета и общего восприятия загрузки сайта. 5) не подключайте шрифты с Google Fonts через
<link>. Сгенерируйте шрифт в Google Fonts, скачайте их локально и взьмите сгенерированные сниппеты CSS.6) создавайте подмножества (subsetting) шрифтов в сочетании со свойством
unicode-range. Если язык сайта русский, то нет смысла держать в шрифте многие латинские, японские, китайские и прочие глифы. Для этого шрифт можно разбить на несколько более мелких. В одном оставить кириллицу, цифры и знаки препинания, в другой вынести латиницу и всё остальное. Затем указать это в свойстве unicode-range и браузер скачает только тот шрифт, символы из которого есть на странице. Сам файл при этом будет весить меньше.7) подключайте основной шрифт в HTML при помощи
<style>. Так браузер обнаружит шрифт сразу при получении HTML страницы и не будет ждать загрузки и обработки CSS. Шрифт загрузится и применится раньше. Это позволит избежать вспышек нестилизованного текста (FOUT).8) предварительно загрузите основной шрифт при помощи
<link rel="preload" as="font" format="font/woff2" crossorigin>. Браузер начнёт загрузку шрифта заранее, ещё до того, как фактически обнаружит ссылку. В итоге шрифт частично или полностью будет загружен к моменту его обнаружения. Это также позволяет бороться с FOUT.9) используйте вариативные шрифты. Файл с вариативным шрифтом хоть и весит больше, но если вариаций шрифта слишком много, то вариативный шрифт обеспечит выигрыш по размеру.
Также ссылки для чтения:
- Best practices for fonts
- Optimize web fonts
- Статьи Зака Лезермана про шрифты
🔥6👍2👀2
You don't know HTML: input.showPicker()
Фича из опроса State Of HTML 2023 —
Метод
В примере кода видно, что с помощью
Этот метод позволяет прятать стандартные поля ввода, но вызывать их функции в виде системных пикеров. Особенно это актуально для для разработки кастомных полей для загрузки файлов на основе
#ydkhtml
Фича из опроса State Of HTML 2023 —
input.showPicker(). Это выглядит как JavaScript-метод (так оно и есть), может возникнуть вопрос: причём тут HTML? На самом деле этот метод описан именно в стандарте HTML. Это маленькое, но полезное улучшение для элементов форм.Метод
showPicker() предназначен для программного вызова системных пикеров. Метод доступен у элемента <input> с типами date, month, week, time, datetime-local, color, file, у полей с атрибутом autocomplete, у полей с атрибутом list в сочетании с элементом <datalist> и у <select>. При вызове метода отображается стандартный системный попап для выбора значения, как если бы пользователь нажал на поле самостоятельно.<input type="file">
<button type="button">Upload File</button>
<noscript>
const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
try {
input.showPicker();
} catch (error) {
// Обработка ошибок
}
});
</noscript>
В примере кода видно, что с помощью
try-catch перехватываются исключения. Метод выбросит исключение NotAllowedError, если пользователь как-либо не взаимодействовал со страницей: скролил, кликал. Это сделано из соображений приватности. Если поле нельзя изменять, например оно в состоянии disabled или readonly, будет выброшено исключение InvalidStateError. Если элемент <select> не отображается на экране, будет выброшено исключение NotSupportedError. И если домен не same origin, то выбрасывается исключение SecurityError.Этот метод позволяет прятать стандартные поля ввода, но вызывать их функции в виде системных пикеров. Особенно это актуально для для разработки кастомных полей для загрузки файлов на основе
<input type="file">.#ydkhtml
👍7🔥4
5 правил ARIA
Accessible Rich Internet Application, или же сокращённо ARIA — это расширение HTML, предоставляющее набор атрибутов для расширения семантики HTML и разработки доступных сайтов и приложений.
Существует документ под названием Using ARIA, в котором даны рекомендации и описаны 5 правил использования ARIA.
Первое правило
Используйте встроенные в HTML элементы и атрибуты для передачи нужной семантики вместо использования ARIA. Иными словами: первое правило ARIA — не используйте ARIA.
Второе правило
Не меняйте семантику встроенных элементов без острой необходимости.
Вместо этого:
Лучше сделать так:
Третье правило
Все интерактивные элементы должны управляться с клавиатуры. Если вы создаёте интерактивный компонент, который нажимается, перетаскивается, пролистывается или прокручивается, то должна быть возможность делать это при помощи клавиатуры.
Скрипт должен реагировать на нажатие отдельных клавиш или их сочетаний при взаимодействии с компонентом.
Четвёртое правило
Не используйте
Не делайте так:
Или так:
Или так:
Пятое правило
У всех интерактивных элементов должно быть имя. Это имя должно быть указано одним из доступных способов (
Accessible Rich Internet Application, или же сокращённо ARIA — это расширение HTML, предоставляющее набор атрибутов для расширения семантики HTML и разработки доступных сайтов и приложений.
Существует документ под названием Using ARIA, в котором даны рекомендации и описаны 5 правил использования ARIA.
Первое правило
Используйте встроенные в HTML элементы и атрибуты для передачи нужной семантики вместо использования ARIA. Иными словами: первое правило ARIA — не используйте ARIA.
Второе правило
Не меняйте семантику встроенных элементов без острой необходимости.
Вместо этого:
<h2 role="tab">heading tab</h2>
Лучше сделать так:
<div role="tab">
<h2>heading tab</h2>
</div>
Третье правило
Все интерактивные элементы должны управляться с клавиатуры. Если вы создаёте интерактивный компонент, который нажимается, перетаскивается, пролистывается или прокручивается, то должна быть возможность делать это при помощи клавиатуры.
Скрипт должен реагировать на нажатие отдельных клавиш или их сочетаний при взаимодействии с компонентом.
Четвёртое правило
Не используйте
role="presentation" (синоним role="none") и aria-hidden="true" на интерактивных элементах.Не делайте так:
<button role="presentation">
press me
</button>
Или так:
<button aria-hidden="true">
press me
</button>
Или так:
<div aria-hidden="true">
<button>press me</button>
</div>
Пятое правило
У всех интерактивных элементов должно быть имя. Это имя должно быть указано одним из доступных способов (
<label>, aria-label, aria-labelledby и т.д.)👍6🔥4❤2💯2
Что на счёт элемента <denoscription>?
Таким вопросом задалась Сара Суиден в твиттере. В HTML есть элемент
Почему бы не добавить аналогичную возможность для указания
Элемент создаёт привязку с описанием, которое будет озвучиваться программами чтения с экрана, если эта функция включена. Это позволит следовать правилу "не использовать ARIA".
Таким вопросом задалась Сара Суиден в твиттере. В HTML есть элемент
<label for>, с помощью которого можно задать имя встроенным элементам <input>, <textarea>, <select>, <button>, <meter>, <progress>, <output> и FACE (Form-associated Custom Elements). Если у элементов не заданы атрибуты aria-label и aria-labelledby, то текст из <label> используется как имя.Почему бы не добавить аналогичную возможность для указания
aria-denoscription/aria-describedby? На данный момент нет способа сделать это без ARIA. С новым элементом это может выглядеть так:<label for="password">Пароль</label>
<input type="password" name="password" id="password">
<denoscription for="password">Пароль должен содержать не менее 8 символов, а также включать как минимум одну цифру, одну букву и один символ пунктуации.</denoscription>
Элемент создаёт привязку с описанием, которое будет озвучиваться программами чтения с экрана, если эта функция включена. Это позволит следовать правилу "не использовать ARIA".
👍6🤔1
Classless CSS
CSS-библиотеки почти всегда полагаются на классы. Сразу на ум приходит классический представитель такого подхода — Bootstrap. Есть и другие: Bulma, UIKit, Foundation и т.д.
Но есть подход под названием classless. Идея в том, чтобы стилизовать стандартные элементы и некоторые их сочетания (вложенность, соседство, положение в дереве) с помощью селекторов типа. То есть при таком подходе библиотека не содержит классов вовсе или содержит крайне ограниченное их количество.
На моё удивление, таких библиотек достаточно много. Есть простые реализации, напоминающие улучшенный normalize.css. Они стилизуют базовые элементы HTML, чтобы голая страница выглядела более-менее симпатично, лучше, чем со стандартными стилями браузера.
Есть и продвинутые реализации. Они предлагают базовую раскладку страницы и некоторые компоненты. Например,
Вот два источника с примерами classless библиотек: github-репозиторий и сайт cssbed. Думаю, в интернете можно найти еще что-то подобное.
Вопрос, который может возникнуть: зачем такие библиотеки нужны? Вот несколько примеров использования:
- прототипирование
- создание тестовых, отладочных и служебных страниц
- более красивые демки для образовательных целей
- быстрое создание простого сайта-визитки, портфолио, блога, документации
- создание стилизованных страниц, сгенерированных из Markdown
- альтернатива normalize/reset
- основа для создания своей библиотеки или темы
В общем, применимая штука. Тем более, что для работы достаточно просто вставить
CSS-библиотеки почти всегда полагаются на классы. Сразу на ум приходит классический представитель такого подхода — Bootstrap. Есть и другие: Bulma, UIKit, Foundation и т.д.
Но есть подход под названием classless. Идея в том, чтобы стилизовать стандартные элементы и некоторые их сочетания (вложенность, соседство, положение в дереве) с помощью селекторов типа. То есть при таком подходе библиотека не содержит классов вовсе или содержит крайне ограниченное их количество.
На моё удивление, таких библиотек достаточно много. Есть простые реализации, напоминающие улучшенный normalize.css. Они стилизуют базовые элементы HTML, чтобы голая страница выглядела более-менее симпатично, лучше, чем со стандартными стилями браузера.
Есть и продвинутые реализации. Они предлагают базовую раскладку страницы и некоторые компоненты. Например,
<nav> с нумерованным списком <ol> с ссылками <a> внутри <li> будет выглядеть как хлебные крошки. В таких библиотеках используются более сложные селекторы с комбинаторами и иногда :has(), но всё ещё без классов.Вот два источника с примерами classless библиотек: github-репозиторий и сайт cssbed. Думаю, в интернете можно найти еще что-то подобное.
Вопрос, который может возникнуть: зачем такие библиотеки нужны? Вот несколько примеров использования:
- прототипирование
- создание тестовых, отладочных и служебных страниц
- более красивые демки для образовательных целей
- быстрое создание простого сайта-визитки, портфолио, блога, документации
- создание стилизованных страниц, сгенерированных из Markdown
- альтернатива normalize/reset
- основа для создания своей библиотеки или темы
В общем, применимая штука. Тем более, что для работы достаточно просто вставить
<link> в <head> и всё будет работать. У меня даже возникла идея сделать свою реализацию classless-библиотеки 🤔🔥8👍2
Как я перестал верить технологиям
Рекомендую к просмотру доклад Алексея Симоненко "Как я перестал верить технологиям". Это один из моих любимых докладов. Не смотря на то, что он 2016 года, он всё ещё актуален. Примеры кода из 2016 года могут выглядеть странно, но в этом докладе важен не код, а суть.
Основные тезисы доклада:
- Мы любим решать сложные задачи и не любим доводить дело до конца
- Выбор модных технологий не даёт никаких преимуществ новому продукту
- Самое важное — это продукт, а не технологии
- Делайте продукты для людей, вместо возьни с технологиями
Приятного просмотра!
Рекомендую к просмотру доклад Алексея Симоненко "Как я перестал верить технологиям". Это один из моих любимых докладов. Не смотря на то, что он 2016 года, он всё ещё актуален. Примеры кода из 2016 года могут выглядеть странно, но в этом докладе важен не код, а суть.
Основные тезисы доклада:
- Мы любим решать сложные задачи и не любим доводить дело до конца
- Выбор модных технологий не даёт никаких преимуществ новому продукту
- Самое важное — это продукт, а не технологии
- Делайте продукты для людей, вместо возьни с технологиями
Приятного просмотра!
YouTube
Алексей Симоненко — Как я перестал верить технологиям
Подробнее о конференции HolyJS: https://jrg.su/EM4wwV
— —
Алексей Симоненко Как я перестал верить технологиям
JavaScript конференция HolyJS 2016 Piter
Санкт-Петербург, 05.06.2016
Постоянная смена технологий почему её стоит избегать.
— —
Алексей Симоненко Как я перестал верить технологиям
JavaScript конференция HolyJS 2016 Piter
Санкт-Петербург, 05.06.2016
Постоянная смена технологий почему её стоит избегать.
👍6🔥4
Баги в Chrome
Обычно Chrome выступает в роли эталонного браузера, в котором всё работает. Поэтому сейчас модно жаловаться на Safari и иногда Firefox за баги и отсутствие поддержки некоторых фич.
Но за последние две недели я дважды столкнулся с багами в Chrome, тогда как в других браузерах (Firefox и Safari) все работало как нужно. Ничто не идеально. В таком сложном ПО, как браузеры, есть огромное количество багов. Во всех из них. И браузеры работают сообща над их исправлением в рамках инициативы Interop.
Отдельно хочу сказать про "Safari — новый IE". Кажется, некоторые современные разработчики забывают о таком понятии, как кроссбраузерность. Это всё ещё актуально. Задача разработчика, который делает веб-интерфейс, позаботиться о том, чтобы он выглядел и работал одинаково во всех целевых браузерах.
Кроссбраузерность — это навык, которым должен обладать профессиональный разработчик. Тем более, что сейчас ситуация обстоит намного лучше: есть Can I Use, Baseline, Web Platform Status, уже упомянутый Interop, Browserslist, Autoprefixer и прочие инструменты.
Обычно Chrome выступает в роли эталонного браузера, в котором всё работает. Поэтому сейчас модно жаловаться на Safari и иногда Firefox за баги и отсутствие поддержки некоторых фич.
Но за последние две недели я дважды столкнулся с багами в Chrome, тогда как в других браузерах (Firefox и Safari) все работало как нужно. Ничто не идеально. В таком сложном ПО, как браузеры, есть огромное количество багов. Во всех из них. И браузеры работают сообща над их исправлением в рамках инициативы Interop.
Отдельно хочу сказать про "Safari — новый IE". Кажется, некоторые современные разработчики забывают о таком понятии, как кроссбраузерность. Это всё ещё актуально. Задача разработчика, который делает веб-интерфейс, позаботиться о том, чтобы он выглядел и работал одинаково во всех целевых браузерах.
Кроссбраузерность — это навык, которым должен обладать профессиональный разработчик. Тем более, что сейчас ситуация обстоит намного лучше: есть Can I Use, Baseline, Web Platform Status, уже упомянутый Interop, Browserslist, Autoprefixer и прочие инструменты.
Caniuse
Can I use... Support tables for HTML5, CSS3, etc
"Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.
🔥5❤3🤝3
property и starting-style
Вышел Firefox 128, а вместе с ним во всех стабильных браузерах теперь доступны директивы
property
Директива
Определяется пользовательское свойство
starting-style
Директива
Или с использованием вложенности:
Когда поповер отобразится, свойства
Вышел Firefox 128, а вместе с ним во всех стабильных браузерах теперь доступны директивы
@property и @starting-style.property
Директива
@property позволяет управлять характеристиками пользовательских свойств. А именно: типом, наследованием и значением по умолчанию.@property --width {
syntax: "<length>";
inherit: false;
initial-value: 48px;
}Определяется пользовательское свойство
--width, его значение будет преобразовано к типу <length>, оно не будет наследоваться и по умолчанию будет равно 48px. Это свойство можно будет использовать для анимации в @keyframes. Подробнее о @property.starting-style
Директива
@starting-style даёт возможность задавать стили, которые будут применены при отрисовке элемента, когда значение display меняется с none на другое значение. С помощью этого механизма можно анимировать появление элемента.[popover]:popover-open {
opacity: 1;
transform: scaleX(1);
}
@starting-style {
[popover]:popover-open {
opacity: 0;
transform: scaleX(0);
}
}Или с использованием вложенности:
[popover]:popover-open {
opacity: 1;
transform: scaleX(1);
@starting-style {
opacity: 0;
transform: scaleX(0);
}
}Когда поповер отобразится, свойства
opacity и transform плавно изменят свои значения. Подробнее о @starting-style.Firefox
Firefox 128.0, See All New Features, Updates and Fixes
🔥11
Уточнение про starting-style
В предыдущем посте я писал, что с выходом Firefox 128,
Перечитывая релиз ноуты Firefox 128 я не обнаружил там информации о
В действительности,
На данный момент релиз запланирован на 129 версию, во всяком случае в релиз ноутах беты есть информация о
В предыдущем посте я писал, что с выходом Firefox 128,
@property и @starting-style теперь доступны во всех стабильных браузерах. Я написал об этом на основании того, что видел новость о добавлении @starting-style в Firefox.Перечитывая релиз ноуты Firefox 128 я не обнаружил там информации о
@starting-style, поэтому решил уточнить этот момент.В действительности,
@starting-style доступен с Firefox 127, но за специальным флагом и ещё не до конца реализован. Поэтому эта директива всё ещё не стала кроссбраузерной и она не доступна в Firefox 128.На данный момент релиз запланирован на 129 версию, во всяком случае в релиз ноутах беты есть информация о
@starting-style. Но не всё из беты может попасть в финальный релиз, поэтому на самом деле не известно, когда это заедет.👍5
You don't know HTML: Media Capture
HTML Media Capture — небольшое расширение для форм, которое позволяет использовать аудио/видео устройства для получения данных и их дальнейшей загрузки.
У мобильных устройств есть основная и фронтальная камеры, а также микрофон. Почему бы не использовать эти возможности для получения контента? Например, на сайте есть функция смены аватара пользователя. Можно использовать камеру устройства, чтобы сделать снимок и сразу же его загрузить.
Чтобы захватить данные с аудио/видео устройств, нужно добавить атрибуты
Если нужно захватить видео на основную камеру, то нужно установить
Можно также получить записанный файл из
В общем, небольшая фича, которая может быть полезна в некоторых ситуациях для улучшения пользовательского опыта. Пользователю не придётся сворачивать сайт, включать камеру, выбирать режим, делать фото, возвращаться на сайт и искать фото через диалог выбора файла.
#ydkhtml
HTML Media Capture — небольшое расширение для форм, которое позволяет использовать аудио/видео устройства для получения данных и их дальнейшей загрузки.
У мобильных устройств есть основная и фронтальная камеры, а также микрофон. Почему бы не использовать эти возможности для получения контента? Например, на сайте есть функция смены аватара пользователя. Можно использовать камеру устройства, чтобы сделать снимок и сразу же его загрузить.
<form action="/user/change-avatar" method="post" enctype="multipart/form-data">
<label for="avatar">Take a photo</label>
<input type="file" id="avatar" accept="image/*" capture="user">
<button>Send</button>
</form>
Чтобы захватить данные с аудио/видео устройств, нужно добавить атрибуты
capture и accept для <input type="file">. В примере мы говорим браузеру, что хотим использовать фронтальную камеру устройства (capture="user"), чтобы сделать фото (accept="image/*"). При нажатии на поле, вместо стандартного окна выбора файла, запустится приложение камеры в режиме съемки на фронтальную камеру. После снимка, файл изображения будет помещён в поле выбора файла и форму можно будет отправить на сервер.Если нужно захватить видео на основную камеру, то нужно установить
accept="video/*" capture="environment", для записи аудио — accept="audio/*" capture. Само собой, нужно дать браузеру доступ к камере и микрофону, иначе не заработает.Можно также получить записанный файл из
<input> через Javanoscript и нарисовать его в <canvas>, вставить в <img>, <audio> или <video> для предпросмотра перед отправкой. Можно отправить данные на сервер при помощи Fetch API.В общем, небольшая фича, которая может быть полезна в некоторых ситуациях для улучшения пользовательского опыта. Пользователю не придётся сворачивать сайт, включать камеру, выбирать режим, делать фото, возвращаться на сайт и искать фото через диалог выбора файла.
#ydkhtml
👍13🔥3
Условно адаптивно
Подход к организации стилей, который предложил Вадим Макеев в одном из своих докладов.
Как мы обычно пишем стили:
Это может быть подход Desktop First с
Суть в том, что:
- медиа-запросы каскадно переопределяют все предыдущие
- все стили склеиваются в один бандл, который подключается к странице.
Вадим предлагает другой подход:
- разделить стили по файлам на базовые и под конкретные группы экранов
- ограничить стили под группы экраны так, чтобы не было пересечений
Как это выглядит:
Базовые стили применяются всегда. Атрибут
Стили для мобильных применяются на экранах с шириной до
В итоге стили под разные группы экранов не конфликтуют между собой, потому что
Важно ещё отметить, что такой подход обеспечивает прирост производительности. CSS — ресурс, блокирующий отрисовку. Браузеру нужны стили, чтобы отрисовать страницу. При использовании атрибута
Есть и минусы. Например, если что-то на десктопе выглядит одним образом, а на планшетах и мобильных выглядит другим образом, то придётся дублировать одинаковые стили и для планшетов и для мобильных. Это можно решить выносом таких правил в базовые стили. Также такой подход требует больше ручной работы. Инструментов для автоматизации всего процесса на данный момент нет, только отдельные плагины для PostCSS.
На одном из своих проектов я использовал этот подход и он мне в целом понравился. Рекомендую посмотреть доклад с более подробным объяснением идеи.
Подход к организации стилей, который предложил Вадим Макеев в одном из своих докладов.
Как мы обычно пишем стили:
.element {
/* стили */
}
@media (max-width: 1024px) {
.element {
/* стили для экранов шириной 1024px и меньше */
}
}
@media (max-width: 768px) {
.element {
/* стили для экранов шириной 768px и меньше */
}
}Это может быть подход Desktop First с
max-width или Mobile First с min-width. Всё это может быть написано в одном файле или распределено по разным файлам и склеено в процессе сборки. Это может быть нативный CSS или SCSS. Не важно.Суть в том, что:
- медиа-запросы каскадно переопределяют все предыдущие
- все стили склеиваются в один бандл, который подключается к странице.
Вадим предлагает другой подход:
- разделить стили по файлам на базовые и под конкретные группы экранов
- ограничить стили под группы экраны так, чтобы не было пересечений
Как это выглядит:
<head>
<!-- ... -->
<link rel="stylesheet" href="base.css" media="all">
<link rel="stylesheet" href="mobile.css" media="(width < 768px)">
<link rel="stylesheet" href="tablet.css" media="(768px <= width < 1024px)">
<link rel="stylesheet" href="desktop.css" media="(width >= 1024px)">
<!-- ... -->
</head>
Базовые стили применяются всегда. Атрибут
media="all" можно не указывать, но пусть будет для наглядности. К базовыми стилями относятся те, которые применяются вне зависимости от экрана. Это могут быть директивы @font-face, сбросы, общие стили и т.д.Стили для мобильных применяются на экранах с шириной до
768px. Планшетные стили применяются на экранах шириной от 768px, до 1024px не включая. Десктопные стили применяются на экранах от 1024px и выше. В примере используется Media Query Range Syntax, который уже неплохо поддерживается.В итоге стили под разные группы экранов не конфликтуют между собой, потому что
media взаимоисключающие. Во вкладке Styles в DevTools не будет каскада переопределений, это улучшает читаемость, упрощает отдадку и не заставляет отменять правила. Также всегда понятно, где искать нужные стили в проекте.Важно ещё отметить, что такой подход обеспечивает прирост производительности. CSS — ресурс, блокирующий отрисовку. Браузеру нужны стили, чтобы отрисовать страницу. При использовании атрибута
media у <link>, браузер проверяет медиа-запрос на соответствие. Если он соответствует параметрам, файл загружается как обычно. А вот если не соответствует, то, вопреки ожиданиям, он всё равно загружается, но с более низким приоритетом и, что самое главное, не блокирует отрисовку. В итоге стили загружаются и применяются быстрее, а значит отрисовка тоже происходит быстрее.Есть и минусы. Например, если что-то на десктопе выглядит одним образом, а на планшетах и мобильных выглядит другим образом, то придётся дублировать одинаковые стили и для планшетов и для мобильных. Это можно решить выносом таких правил в базовые стили. Также такой подход требует больше ручной работы. Инструментов для автоматизации всего процесса на данный момент нет, только отдельные плагины для PostCSS.
На одном из своих проектов я использовал этот подход и он мне в целом понравился. Рекомендую посмотреть доклад с более подробным объяснением идеи.
YouTube
Условно адаптивно [ru] / Вадим Макеев
Видео с онлайн-конференции JavaScript fwdays'21, которая прошла с 1-8 июня 2021 года.
Описание доклада:
Кто-то делает сразу два сайта: мобильный и, видимо, стационарный. Принюхивается к браузеру и отдаёт подходящую версию. Что ж. Кто-то делает гибко и отдаёт…
Описание доклада:
Кто-то делает сразу два сайта: мобильный и, видимо, стационарный. Принюхивается к браузеру и отдаёт подходящую версию. Что ж. Кто-то делает гибко и отдаёт…
👍14
Baseline
Инициатива Baseline призвана помочь с определением кроссбраузерной поддержки фич веб-платформы. Baseline охватывает 4 основных браузера:
- Chrome (ПК и Android)
- Edge
- Firefox (ПК и Android)
- Safari (macOS и iOS)
Смысл в том, чтобы показать уровень поддержки фич веб-платформы в этих браузерах и устанавливать некую отметку, начиная с которой фичу можно использовать в проектах.
Данные Baseline можно увидеть на Can I Use, MDN, на ресурсах от производителей браузеров, а также на Web Platform Dashboard.
Каждая фича в рамках Baseline получает один из трёх статусов:
- Limited availability
- Newly available
- Widely available
Limited availability означает, что фича появилась в каком-то из браузеров или в нескольких из них, но не во всех. То есть ещё нет кроссбраузерной поддержки и фичу лучше не использовать в продакшине. Такие фичи помечаются оранжевым крестиком.
Newly available означает, что фича недавно появилась во всех Baseline-браузерах. Фичу можно использовать, при условии поддержки последних версий. Такие фичи помечаются синей галочкой.
Widely available означает, что фича внедрена во все браузеры уже достаточно давно, чтобы считаться широко поддерживаемой. Этот статус присваивается через 30 месяцев (2.5 года) после получения статуса Newly available. По мнению группы WebDX, этого срока достаточно, чтобы фичу можно было использовать без оглядки на её поддержку. Помечаются такие фичи зелёной галочкой.
Инициатива Baseline призвана помочь с определением кроссбраузерной поддержки фич веб-платформы. Baseline охватывает 4 основных браузера:
- Chrome (ПК и Android)
- Edge
- Firefox (ПК и Android)
- Safari (macOS и iOS)
Смысл в том, чтобы показать уровень поддержки фич веб-платформы в этих браузерах и устанавливать некую отметку, начиная с которой фичу можно использовать в проектах.
Данные Baseline можно увидеть на Can I Use, MDN, на ресурсах от производителей браузеров, а также на Web Platform Dashboard.
Каждая фича в рамках Baseline получает один из трёх статусов:
- Limited availability
- Newly available
- Widely available
Limited availability означает, что фича появилась в каком-то из браузеров или в нескольких из них, но не во всех. То есть ещё нет кроссбраузерной поддержки и фичу лучше не использовать в продакшине. Такие фичи помечаются оранжевым крестиком.
Newly available означает, что фича недавно появилась во всех Baseline-браузерах. Фичу можно использовать, при условии поддержки последних версий. Такие фичи помечаются синей галочкой.
Widely available означает, что фича внедрена во все браузеры уже достаточно давно, чтобы считаться широко поддерживаемой. Этот статус присваивается через 30 месяцев (2.5 года) после получения статуса Newly available. По мнению группы WebDX, этого срока достаточно, чтобы фичу можно было использовать без оглядки на её поддержку. Помечаются такие фичи зелёной галочкой.
🔥5
CSS Scroll Snap Module Level 2
23 июля CSSWG опубликовала первый черновик CSS Scroll Snap Module Level 2. Это дальнейшее развитие Scroll Snap.
Напомню, что CSS Scroll Snap — это спецификация про управление привязкой элементов внутри прокручиваемого контейнера. Например, при помощи этой спецификации можно сделать полноэкранную прокрутку страницы, как в плагине fullPage.js. Также при помощи этой спецификации, гридов и небольшого количества JavaScript реализована карусель в библиотеке компонентов Shoelace.
Module Level 2 расширяет спецификацию и добавляет новые возможности.
1) свойство
И разметка:
2) псевдоклассы
3) события
23 июля CSSWG опубликовала первый черновик CSS Scroll Snap Module Level 2. Это дальнейшее развитие Scroll Snap.
Напомню, что CSS Scroll Snap — это спецификация про управление привязкой элементов внутри прокручиваемого контейнера. Например, при помощи этой спецификации можно сделать полноэкранную прокрутку страницы, как в плагине fullPage.js. Также при помощи этой спецификации, гридов и небольшого количества JavaScript реализована карусель в библиотеке компонентов Shoelace.
Module Level 2 расширяет спецификацию и добавляет новые возможности.
1) свойство
scroll-snap-target для указания элемента, который изначально должен быть привязан:.carousel {
overflow-inline: auto;
}
.carousel .origin {
scroll-start-target: auto;
}И разметка:
<div class="carousel">
<img src="img1.jpg">
<img src="img2.jpg">
<img src="img3.jpg" class="origin">
<img src="img4.jpg">
<img src="img5.jpg">
</div>
2) псевдоклассы
:snapped-x, :snapped-y, :snapped-inline и :snapped-block для стилизации привязанных элементов. Однако, принято решение отказаться от них в пользу новых Style Container Queries.3) события
scrollsnapchange и scrollsnapchanging для отслеживания изменений привязанных элементов при прокрутке в JavaScript. Вместе с ними добавляется новый тип события SnapEvent с соответствующим интерфейсом и набором свойств.🔥2❤1
7го августа выступаю на MinskCSS с докладом про Shadow DOM! Приходите, начало в 19:00.
👍6🔥2
Forwarded from MinskCSS/MinskJS
✨ Продолжаем знакомить вас с докладами на MinskCSS Meetup #12.
Наш следующий спикер Алексей Назаренко расскажет про особенности Shadow DOM, связанные с изоляцией и стилями, и покажет, как с этим работать.
Место проведения:
👉 https://youtube.com/live/-s7s_IB2egc 👈
Описание и программа:
https://telegra.ph/MinskCSS-Meetup-12-07-29
Подписывайтесь, чтобы ничего не пропускать: Telegram | Twitter
Наш следующий спикер Алексей Назаренко расскажет про особенности Shadow DOM, связанные с изоляцией и стилями, и покажет, как с этим работать.
Место проведения:
👉 https://youtube.com/live/-s7s_IB2egc 👈
Описание и программа:
https://telegra.ph/MinskCSS-Meetup-12-07-29
Подписывайтесь, чтобы ничего не пропускать: Telegram | Twitter
🔥16
Слайды вчерашнего доклада с MinskCSS. Запись трансляции доступна на YouTube. Спасибо всем, кто присоединился к трансляции ❤️
Через некоторое время организаторы нарежут доклады на отдельные видео, которые будут доступны на том же канале. Также можете посмотреть другой мой доклад "HTML: 25 фич, которые сделают ваш сайт удобнее".
Также напомню, что если у вас есть тема и вы хотите выступить с ней, или попробовать, пишите ребятам из MinskCSS/MinskJS и Accessibility Club Minsk.
И если есть какие-то вопросы по Shadow DOM или веб-компонентам в целом, пишите в личку.
Через некоторое время организаторы нарежут доклады на отдельные видео, которые будут доступны на том же канале. Также можете посмотреть другой мой доклад "HTML: 25 фич, которые сделают ваш сайт удобнее".
Также напомню, что если у вас есть тема и вы хотите выступить с ней, или попробовать, пишите ребятам из MinskCSS/MinskJS и Accessibility Club Minsk.
И если есть какие-то вопросы по Shadow DOM или веб-компонентам в целом, пишите в личку.
🔥12👍4❤1
Глобальная дизайн-система
Брэд Фрост, эксперт в области дизайн-систем, автор книги "Атомарный дизайн", опубликовал в своём блоге статью "Глобальная дизайн-система". В этой статье он призывает сообщество заняться созданием глобальной дизайн-системы для всего мира. Звучит очень амбициозно.
Во многих компаниях мира отдельные команды занимаются созданием дизайн-систем для продуктов. Из раза в раз в дизайн-системах реализуют одни и те же компоненты интерфейса с одним и тем же общим поведением. Аккордеоны, модальные окна, вкладки, выпадающие списки, поля ввода. Огромное количество ресурсов тратится на обсуждения, дизайн, тесты, доступность, документацию, песочницу и дальнейшую поддержку.
Брэд считает, что пришло время сообществу начать работу над Глобальной дизайн-системой. Его основные идеи и тезисы:
- готовые компоненты. Глобальная дизайн-система должна предоставлять набор готовых базовых компонентов, которые есть во многих существующих дизайн-системах.
- двигатель хороших практик. Глобальная дизайн-система должна быть тщательно проработана, включать доступность, использовать современные возможности браузеров и соответствовать другим хорошим практикам.
- кастомизация. Глобальная дизайн-система должна поставляться как headless-решение с минимальными базовыми стилями браузера для возможности реализации конкретного внешнего вида.
- интуитивность. Глобальная дизайн-система должна быть максимально легкой и понятной в использовании, все компоненты, возможности, API должны быть подробно документировны.
- универсальность. Глобальная дизайн-система должна быть независимой от фреймворков и библиотек и иметь возможность встраиваться в них, поэтому веб-компоненты выбраны как способ реализации.
- интернационализация. Глобальная дизайн-система должна учитывать и адаптироваться под разные локальные особенности, такие как язык, направление письма, формат даты и времени, принятые соглашения типографики и т.д.
- расширяемость. Глобальная дизайн-система должны покрывать большинство кейсов использования по правилу 80/20, при этом быть легко расширяемой, чтобы на её основе можно было строить другие дизайн-системы.
- открытость. Глобальная дизайн-система должна разрабатываться под открытой лицензией, с открытым исходным кодом, разработка должна производиться силами сообщества под эгидой некоммерческой организации, например W3C.
Брэд пишет, что получал много положительных откликов на эту идею после рассказов о глобальной дизайн-системе на конференциях. Идею уже подхватили, в группе OpenUI начались обсуждения и встречи по этому поводу. К ним присоединились автор и один из мэнтейнеров библиотеки Shoelace и другие люди.
Лично я нахожу эту инициативу крайне интересной и буду следить за развитием событий.
Брэд Фрост, эксперт в области дизайн-систем, автор книги "Атомарный дизайн", опубликовал в своём блоге статью "Глобальная дизайн-система". В этой статье он призывает сообщество заняться созданием глобальной дизайн-системы для всего мира. Звучит очень амбициозно.
Во многих компаниях мира отдельные команды занимаются созданием дизайн-систем для продуктов. Из раза в раз в дизайн-системах реализуют одни и те же компоненты интерфейса с одним и тем же общим поведением. Аккордеоны, модальные окна, вкладки, выпадающие списки, поля ввода. Огромное количество ресурсов тратится на обсуждения, дизайн, тесты, доступность, документацию, песочницу и дальнейшую поддержку.
Брэд считает, что пришло время сообществу начать работу над Глобальной дизайн-системой. Его основные идеи и тезисы:
- готовые компоненты. Глобальная дизайн-система должна предоставлять набор готовых базовых компонентов, которые есть во многих существующих дизайн-системах.
- двигатель хороших практик. Глобальная дизайн-система должна быть тщательно проработана, включать доступность, использовать современные возможности браузеров и соответствовать другим хорошим практикам.
- кастомизация. Глобальная дизайн-система должна поставляться как headless-решение с минимальными базовыми стилями браузера для возможности реализации конкретного внешнего вида.
- интуитивность. Глобальная дизайн-система должна быть максимально легкой и понятной в использовании, все компоненты, возможности, API должны быть подробно документировны.
- универсальность. Глобальная дизайн-система должна быть независимой от фреймворков и библиотек и иметь возможность встраиваться в них, поэтому веб-компоненты выбраны как способ реализации.
- интернационализация. Глобальная дизайн-система должна учитывать и адаптироваться под разные локальные особенности, такие как язык, направление письма, формат даты и времени, принятые соглашения типографики и т.д.
- расширяемость. Глобальная дизайн-система должны покрывать большинство кейсов использования по правилу 80/20, при этом быть легко расширяемой, чтобы на её основе можно было строить другие дизайн-системы.
- открытость. Глобальная дизайн-система должна разрабатываться под открытой лицензией, с открытым исходным кодом, разработка должна производиться силами сообщества под эгидой некоммерческой организации, например W3C.
Брэд пишет, что получал много положительных откликов на эту идею после рассказов о глобальной дизайн-системе на конференциях. Идею уже подхватили, в группе OpenUI начались обсуждения и встречи по этому поводу. К ним присоединились автор и один из мэнтейнеров библиотеки Shoelace и другие люди.
Лично я нахожу эту инициативу крайне интересной и буду следить за развитием событий.
👍6⚡1🤔1
You don't know HTML: inert
Несколько лет назад в HTML появился глобальный атрибут
Например, модальный диалог согласно рекомендациям должен отображаться поверх страницы, замыкать в себе фокус и не давать взаимодействовать со страницей. Чтобы реализовать такое поведение, нужно изрядно постараться и написать много Javanoscript.
Атрибут
- все дочерние интерактивные элементы становятся недоступными для взаимодействия, как будто для них установлено свойство
- все дочерние интерактивные элементы пропадают из последовательности табуляции, как будто для них установлен атрибут
- элемент вместе со своими дочерними элементами скрывается из дерева доступности, как будто для них установлен атрибут
Таким образом, пользователь не сможет взаимодействовать с инертной частью страницы, а скринридеры не будут её зачитывать.
#ydkhtml
Несколько лет назад в HTML появился глобальный атрибут
inert. Он позволяет делать часть страницы инертной, то есть недоступной для взаимодействия. Это нужно при разработке модальных компонентов.Например, модальный диалог согласно рекомендациям должен отображаться поверх страницы, замыкать в себе фокус и не давать взаимодействовать со страницей. Чтобы реализовать такое поведение, нужно изрядно постараться и написать много Javanoscript.
Атрибут
inert решает задачу более простым способом. Это глобальный атрибут, поэтому его можно добавить к любому элементу. Когда атрибут установлен, происходит следующее:- все дочерние интерактивные элементы становятся недоступными для взаимодействия, как будто для них установлено свойство
pointer-events: none- все дочерние интерактивные элементы пропадают из последовательности табуляции, как будто для них установлен атрибут
tabindex="-1"- элемент вместе со своими дочерними элементами скрывается из дерева доступности, как будто для них установлен атрибут
aria-hidden="true".<main inert>
<p><!-- контент --></p>
<p><a href="/">ссылка</a></p>
<p><!-- контент --></p>
<button type="button">Удалить</button>
</main>
<div role="dialog" aria-modal="true" aria-labelledby="dialog-heading">
<h2 id="dialog-heading">
Вы действительно хотите удалить запись?
</h2>
<button type="button">Да</button>
<button type="button" autofocus>Нет</button>
</div>
Таким образом, пользователь не сможет взаимодействовать с инертной частью страницы, а скринридеры не будут её зачитывать.
#ydkhtml
🔥11👍8
Intent to Prototype: CSS Gap Decoration
Ранее я писал о предложении по добавлению в CSS возможности стилизации gap-ов во flexbox и grid. И вот, команда Microsoft Edge начала разработку прототипа этих функций в Blink (движок в Chromium браузерах). Подробнее с предложением можно ознакомиться в черновике спецификации и эксплейнере.
Другие движки (Webkit и Gecko) пока явно не проявили заинтересованность, но если обкатка прототипа пройдёт успешно, эту спецификацию доработают и примут в CSSWG, а там и другие движки подтянутся. Предложение на самом деле очень полезное и нужное.
Ранее я писал о предложении по добавлению в CSS возможности стилизации gap-ов во flexbox и grid. И вот, команда Microsoft Edge начала разработку прототипа этих функций в Blink (движок в Chromium браузерах). Подробнее с предложением можно ознакомиться в черновике спецификации и эксплейнере.
Другие движки (Webkit и Gecko) пока явно не проявили заинтересованность, но если обкатка прототипа пройдёт успешно, эту спецификацию доработают и примут в CSSWG, а там и другие движки подтянутся. Предложение на самом деле очень полезное и нужное.
Telegram
<divelopers>
Линии во flexbox и grid
Небольшое предисловие. В CSS есть Multi-Columns Layout. Это возможность разбить текст внутри элемента на несколько колонок (фрагментов по умному) и управлять их поведением. Многие об этом не знают, потому что подобные задачи встречаются…
Небольшое предисловие. В CSS есть Multi-Columns Layout. Это возможность разбить текст внутри элемента на несколько колонок (фрагментов по умному) и управлять их поведением. Многие об этом не знают, потому что подобные задачи встречаются…
👍4