Русский
Русский
English
Статистика
Реклама

Веб-дизайн

Перевод Пользовательские CSS-переменные, инверсия светлоты цветов и создание тёмной темы за 5 минут

15.04.2021 12:10:33 | Автор: admin
Вы, наверное, уже знаете о том, что для хранения сведений об отдельных компонентах цвета можно применять пользовательские CSS-переменные. Это позволяет избавиться от необходимости повторения одних и тех же цветовых координат в стилях, описывающих цветовую тему сайта. Возможно, вы даже знаете о том, что одну и ту же переменную можно использовать для настройки нескольких компонентов цвета.



Например тона (hue) и насыщенности (saturation) при использовании цветовой модели HSL:

:root {--primary-hs: 250 30%;}h1 {color: hsl(var(--primary-hs) 30%);}article {background: hsl(var(--primary-hs) 90%);}article h2 {background: hsl(var(--primary-hs) 40%);color: white;}

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


Пример страницы

Пользовательские переменные, в отличие от переменных препроцессора, можно даже локально переопределять, используя их, например, для задания особого акцентного цвета для некоторых блоков:

:root {--primary-hs: 250 30%;--secondary-hs: 190 40%;}article {background: hsl(var(--primary-hs) 90%);}article.alt {--primary-hs: var(--secondary-hs);}



Пример страницы, акцентный цвет одного из блоков которой переопределён

Всё это хорошо, всё это красиво, но лишь до тех пор, пока в игру не вступит тёмная тема. Идея использования пользовательских переменных для упрощения настройки тёмной темы не нова. Но в каждой из встретившихся мне статей, посвящённых этой задаче, предлагается создавать массу пользовательских свойств, по одному для каждого цвета, и переопределять свойства в медиа-запросе.

Это нормальный подход, и вы, вероятно, тоже будете им пользоваться, по крайней мере для настройки некоторой части ваших цветов. Правда, даже у самых дисциплинированных дизайнеров не все цвета представлены в виде CSS-переменных. Разработчики сайтов нередко пользуются встроенными определениями цветов, особенно это касается оттенков серого (в нашем примере такой подход использован для настройки цвета подвала). Это означает, что оснащение сайта тёмной темой превращается в довольно-таки трудоёмкое дело, которое, вполне возможно, отложат на потом, особенно если речь идёт о неких второстепенных проектах.

Тот хитрый приём, который я хочу вам показать, может показаться грубоватым любому, кто достаточно много знает о цветах (прости, Крис!), но он, совершенно точно, поможет вам создать рабочую тёмную тему за считанные минуты. Результат нельзя будет назвать идеальным, и то, что получится, в итоге, для создания качественной тёмной темы, надо будет подстроить (и тёмная тема, кстати, это не только результат замены одних цветов другими), но это лучше чем ничего. То, что получится, может играть роль базы для дальнейшей работы.

Основная идея моего подхода заключается в том, чтобы использовать пользовательские CSS-свойства для хранения сведений о светлоте (lightness) цветов, а не полной информации о цветах. В тёмном режиме эти переменные переопределяются, в них записываются значения, вычисляемые по формуле 100% lightness. Это, в целом, позволяет получить светлые цвета из тёмных цветов, цвета средней светлоты из цветов средней светлоты, и тёмные цвета из светлых цветов. При таком подходе вполне можно пользоваться встроенными определениями цветов, необязательно применять переменные при настройке абсолютно всех цветов проекта. Вот как, учитывая вышесказанное, могут выглядеть стили демонстрационного проекта:

root {--primary-hs: 250 30%;--secondary-hs: 190 40%;--l-0: 0%;--l-30: 30%;--l-40: 40%;--l-50: 50%;--l-90: 90%;--l-100: 100%;}@media (prefers-color-scheme: dark) {:root {--l-0: 100%;--l-30: 70%;--l-40: 60%;--l-90: 10%;--l-100: 0%;}}body {background: hsl(0 0% var(--l-100));color: hsl(0 0% var(--l-0));}h1 {color: hsl(var(--primary-hs) var(--l-30));}article {background: hsl(var(--primary-hs) var(--l-90));}article h2 {background: hsl(var(--primary-hs) 40%);color: white;}footer {color: hsl(0 0% var(--l-40));}

Ниже показан вид страницы этого проекта в светлом и тёмном режимах.


Светлая тема


Тёмная тема

Учитывайте то, что цвета для тёмной темы получены автоматически.

Обратите внимание на то, что мы заменили абсолютно все, без разбора, значения светлоты соответствующими переменными. Но, на самом деле, нет нужды поступать именно так. Например, заголовки статей будут смотреться приятнее и отличаться лучшей контрастностью в том случае, если мы попросту не будем менять их цвет.


Тёмная тема, при применении которой цвет заголовков статей не изменился

При создании этого варианта нашей тёмной темы автоматическая настройка цветов использована не для всех без исключения элементов. А именно, тут оставлен цвет фона и цвет текста для article > h2.

Подобные решения, касающиеся выбора цветов, легко принимать, просматривая CSS-код, заменяя процентные значения светлоты цветов переменными и оценивая новый внешний вид страницы.

Проблема с цветовой моделью HSL


Почему заголовки статей легче читать в том случае, когда они, в тёмной теме, выводятся тем же цветом, что и в светлой, а не цветом, светлота которого инвертирована? Главная причина этого кроется в том, что компонент HSL-цвета, отвечающий за светлоту, на самом деле, не имеет отношения к той светлоте, которую воспринимает человек. В результате одинаковые изменения светлоты могут приводить к очень разным изменениям яркости цветов, воспринимаемой человеком.

Именно это и можно назвать большой проблемой данного подхода: тут предполагается, что HSL-светлота имеет некий реальный смысл, но, и мы уже об этом говорили, на самом деле, это не так. Жёлтый и синий цвета, имеющие одну и ту же HSL-светлоту (50%), выглядят очень по-разному. Кроме того, анализируя HSL-цвета, можно обратить внимание на то, что тёмные цвета имеют меньшие отличия друг от друга, чем светлые цвета, так как цветовая модель HSL не является однородной для восприятия (в отличие от LCH и Lab).

Значит ли это, что предложенная мной методика работы с цветами не подходит ни для чего кроме временных тёмных тем, используемых во время разработки настоящих тёмных тем?

На самом деле всё не так уж и мрачно.

Довольно скоро мы сможем пользоваться в браузерах LCH-цветами. Первая браузерная реализация поддержки таких цветов недавно появилась в Safari, производители других браузеров тоже работают в этом направлении.

Цветовое пространство LCH подходит для реализации моей методики гораздо лучше HSL, так как LCH-светлота далеко не бессмысленный показатель, это не просто разные варианты одного и того же цвета, различающиеся по яркости. LCH-светлота имеет отношение и к тону (hue) цвета, и к его цветности (chroma).

Для того чтобы вживую посмотреть этот пример вам понадобится Safari TP 120+. Сравните два показанных там градиента. Верхний это разные HSL-цвета со светлотой 50%, а нижний это LCH цвета с той же светлотой. В верхней части окна есть слайдер, который позволяет посмотреть градиенты для другой светлоты. Если у вас нет Safari TP 120+ ниже приведён скриншот примера.


HSL- и LCH-цвета с одной и той же светлотой

Обратите внимание на то, что некоторые HSL-цвета (вроде жёлтого и светло-голубого) гораздо светлее других. А вот все LCH-цвета одной светлоты имеют, собственно, одинаковую светлоту.

Тут стоит учитывать то, что компонент Chroma (цветность) модели LCH, на самом деле, не связан напрямую с компонентом Lightness (светлота) модели HSL. Поэтому, даже несмотря на то, что мы устанавливаем их в одинаковые значения, это не приводит к одним и тем же результатам.

Как адаптировать предложенную мной методику создания тёмных тем к работе с LCH-цветами?

Я использовала этот инструмент для преобразования существующих HSL-цветов в LCH-цвета, затем вручную немного подстроила получившиеся значения, так как цвета, после конверсии, не выглядели достаточно хорошо во всех вариантах LCH-светлоты. Обратите внимание на то, что HSL-цвета с одними и теми же тоном и насыщенностью могут иметь различные тон и цветность при их преобразовании к LCH-цветам. Обратное попросту сделало бы использование LCH-цветов бессмысленным!

Вот как результаты применения этого приёма выглядят на практике (для просмотра этого примера нужен браузер Safari TP 120 или более новый). Здесь тёмный режим сгенерирован автоматически путём инверсии значения переменной, отвечающей за светлоту LCH-цветов.


Светлый вариант сайта, созданного с применением LCH-цветов


Тёмный вариант сайта, созданного с применением LCH-цветов

Теперь не только тёмная тема сайта выглядит лучше. Даже его светлый вариант смотрится приятнее. В частности, два цвета, применяемые при стилизации похожих элементов, выглядят более близкими друг к другу из-за того, что имеют одну и ту же LCH-светлоту.


Слева тёмная тема, основанная на модификации HSL-цветов, справа тёмная тема, при создании которой использованы LCH-цвета

А ниже приведено анимированное сравнение этих двух тем.

lea.verou.me/wp-content/uploads/2021/03/hsl-dm.png

Анимированное сравнение тёмных тем

Обратите внимание на то, что в реальных проектах, до тех пор, пока LCH-цвета не будут как следует поддерживаться во всех браузерах, при использовании этих цветов нужно предусматривать запасной план действий с применением @supports. Но тут, для краткости, я не включила в пример соответствующий код.

Автоматизация генерирования переменных, хранящих сведения о светлоте цветов


Если вы пользуетесь препроцессором, который поддерживает циклы, например Sass, это значит, что вы можете автоматизировать генерирование переменных, хранящих сведения о светлоте цветов. При таком подходе легко создать набор переменных, хранящих значения светлоты, изменяющиеся с небольшим шагом, например 5%:

:root {@for $i from 0 through 20 {--l-#{$i * 5}: #{$i * 5}%;}}@media (prefers-color-scheme: dark) {:root {@for $i from 0 through 20 {--l-#{$i * 5}: #{100 - $i * 5}%;}}}

Можно ли сделать работу с переменными, хранящими сведения о светлоте, лучше соответствующей принципу DRY?


Кому-то из вас может не понравиться повторение значений. Например, нам нужно объявить переменную --l-40 и, для использования в светлом режиме, записать в неё 40%, а потом, при переходе в тёмный режим, в неё нужно записать 60%. Можно ли как-то получить это значение, просто вычитая уже имеющееся у нас значение из 100%?

Тот, у кого есть опыт в программировании, может попробовать нечто вроде этого:

--l-40: calc(100% - var(--l-40));

Но работать эта конструкция не будет. CSS это не императивный язык программирования. Тут нет неких этапов вычислений, не выполняются какие-то шаги, когда переменные имеют разные значения до и после выполнения такого шага. Здесь нет концепции времени все имеющиеся объявления вступают в силу одновременно. Работа CSS больше похожа на реактивное вычисление значений ячеек электронной таблицы с формулами, чем на вычисления, которые выполняют в JavaScript и в других языках программирования (есть универсальные реактивные языки программирования, но они не особенно широко известны). В результате объявления, похожие на то, которое показано выше, считаются циклическими: переменная --l-40 не может ссылаться сама на себя поэтому возникает ошибка. При исправлении этой ошибки в дело вступает механизм, который устанавливает переменную --l-40 в её исходное значение (это происходит из-за того, что CSS не выбрасывает ошибок).

Итак, есть ли способ избежать двойного объявления переменных для хранения сведений о светлоте цвета, то есть одной переменной для светлой темы, а второй для тёмной?

Такой способ есть, но я не рекомендовала бы пользоваться им. Он ухудшает читабельность и понятность кода, не давая при этом особых преимуществ. Но, ради того, чтобы немного поупражняться в интеллектуальных задачах, я опишут тут этот метод.

Вместо того, чтобы записывать в --l-40 значение 40%, мы запишем в эту переменную значение, выражающее отличие необходимого нам значения от 50%. То есть -10%. В результате конструкция calc(50% + var(--l-40)) даст нам 40%, а конструкция calc(50% var(--l-40)) даст 60%. Это именно те значения, которые нам и нужны. А значит мы можем объявить единственную переменную, которая равняется -1 в тёмном режиме и 1 в светлом. Потом мы просто будем умножать соответствующие значения на эту переменную.

Вот фрагмент кода, созданного с учётом вышеприведённых рассуждений:

:root {--dm: 1;/* Пример объявления переменной: */--l-40: -10%;}@media (prefers-color-scheme: dark) {:root {--dm: -1;}}/* Пример использования имеющихся переменных: */footer {color: hsl(0 0% calc(50% + var(--dm) * var(--l-40));/* Некрасиво! */}

Надеюсь, теперь вам понятна причина, по которой я не рекомендовала бы пользоваться этим приёмом. Он сильно усложняет работу, а взамен мы получаем небольшое приближение к идеалам DRY за счёт избавления от нескольких переменных. Это пример навязчивого стремления к DRY, которое программисты, в конце концов, признают вредящим продуктивности их работы.

Как вы создаёте светлые и тёмные темы для своих проектов?

Подробнее..

Перевод Контейнерные запросы в CSS

28.04.2021 18:07:33 | Автор: admin

Как фронтенд-дизайнер я за последние 6 лет не был так взволнован новой CSS-функцией, как сейчас. Благодаря усилиям Мириам Сюзанны и других умных людей прототип контейнерных запросов можно включить в Chrome Canary

О контейнерных запросах запомнилось много шуток, но они, наконец, здесь. В этой статье я расскажу, зачем нам нужны контейнерные запросы, как они облегчат нашу жизнь, и, самое важное, ваши компоненты и макеты станут мощнее. Если вы взволновались так же, как и я, давайте углубимся в тему. Вы готовы?


Проблема с медиазапросами

Веб-страница состоит из разных разделов и компонентов, которые мы делаем отзывчивыми при помощи медиазапросов CSS. В этом нет ничего плохого, но есть ограничения. Например, мы можем написать медиазапрос, чтобы показать минимальную версию компонента на мобильном или настольном компьютере. Часто отзывчивый веб-дизайн не имеет отношения к видовому экрану или к размеру экрана. Он касается размера контейнера. Рассмотрим такой пример:

Вот очень типичный макет с компонентом карточкой. И два варианта:

  • Стопкой (смотрите aside).

  • Горизонтально (смотрите main).

Реализовать такое на CSS можно несколькими способами, вот самый распространённый: нам нужно создать базовый компонент, а затем написать его вариации.

.c-article {  /* The default, stacked version */}.c-article > * + * {  margin-top: 1rem;}/* The horizontal version */@media (min-width: 46rem) {  .c-article--horizontal {    display: flex;    flex-wrap: wrap;  }  .c-article > * + * {    margin-top: 0;  }  .c-article__thumb {    margin-right: 1rem;  }}

Обратите внимание, что мы описали класс .c-article--horizontal для работы с горизонтальной версией компонента. Если ширина видового экрана больше 46rem, компонент должен переключаться на горизонтальную версию. Это не плохо, но каким-то образом заставляет ощущать себя ограниченным. Хочется, чтобы компонент реагировал на ширину своего родительского компонента, а не на видовой экран браузера или размер экрана.

Считайте, что мы хотим использовать стандартную .c-c-card в разделе main. Что произойдёт? Ну, карта расширится до ширины своего родителя и, следовательно, окажется слишком большой. Посмотрите на рисунок:

Это проблема, и мы можем решить её при помощи контейнерных запросов. (Есть! наконец-то!) До погружения в тему давайте взглянем на результат.

Нам нужно сообщить компоненту, что, если непосредственная ширина родительского элемента больше 400 пикселей, ему нужно переключиться на горизонтальный стиль. CSS будет выглядеть так:

<div class="o-grid">  <div class="o-grid__item">    <article class="c-article">      <!-- content -->    </article>  </div>  <div class="o-grid__item">    <article class="c-article">      <!-- content -->    </article>  </div></div>
.o-grid__item {  contain: layout inline-size;}.c-article {  /* The default style */}@container (min-width: 400px) {  .c-article {    /* The styles that will make the article horizontal**        ** instead of a card style.. */  }}

Как помогут контейнерные запросы?

Предупреждение: контейнерные запросы CSS пока поддерживаются только в Chrome Canary с экспериментальным флагом.

При помощи контейнерных запросов CSS мы можем решить вышеуказанную проблему и создать растягиваемый компонент. Это означает, что мы можем вложить компонент в узкий родительский элемент, и он превратится в версию "стопкой", а в широком родительском компоненте в горизонтальную версию. Опять же все элементы не зависят от ширины видового экрана.

Вот как я представляю себе это:

Фиолетовый контур это ширина родительского компонента. Обратите внимание, как компонент адаптируется к большему размеру своего родительского компонента. Разве это не потрясающе? Вот мощь контейнерных запросов CSS.

Как работают контейнерные запросы

С контейнерными запросами теперь можно поэкспериментировать в Chrome Canary. Чтобы включить их, перейдите в chrome://flags, найдите чекбокс "container queries" и отметьте его.

Сначала добавим свойство contain. Компонент будет адаптироваться под родительскую ширину, поэтому нужно сказать браузеру, чтобы он перерисовал не всю страницу, а только её изменяемую область. Заранее сообщить об этом браузеру мы можем при помощи свойства contain.

Значение inline-size означает, что компонент реагирует только на изменения ширины родительского элемента [прим. перев. в случае языков с вертикальным направлением, возможно, речь идёт о высоте]. Я попытался задействовать block-size, но это свойство ещё не работает. Пожалуйста, поправьте меня, если я ошибаюсь.

<div class="o-grid">  <div class="o-grid__item">    <article class="c-article">      <!-- content -->    </article>  </div>  <div class="o-grid__item">    <article class="c-article">      <!-- content -->    </article>  </div>  <!-- other articles.. --></div>
.o-grid__item {  contain: layout inline-size;}

Это первый шаг. Мы определили элемент .o-grid__item как родительский для .c-article. Следующий шаг добавить желаемые стили, чтобы контейнерные запросы работали.

.o-grid__item {  contain: layout inline-size;}@container (min-width: 400px) {  .c-article {    display: flex;    flex-wrap: wrap;  }  /* other CSS.. */}

@container это элемент .o-grid__item, а min-width: 400px его ширина. Мы даже можем пойти дальше и добавить больше стилей. На видео показано, чего можно добиться от компонентов:

У нас есть следующие стили:

  1. По умолчанию (вид карточки).

  2. Горизонтальная карточка с маленьким предпросмотром.

  3. Горизонтальная карточка с большим предпросмотром.

  4. Если родительский компонент слишком большой, стиль будет похож на стиль раздела hero, указывая, что это избранная статья.

Давайте углубимся в примеры применения контейнерных запросов.

Случаи применения контейнерных запросов CSS

Контейнерные запросы и CSS-грид с auto-fit

В некоторых случаях применение auto-fit в CSS-гриде приводит к неожиданным результатам. Например, компонент оказывается слишком широким, и его содержимое трудно читается. Дам немного контекста: вот визуальный элемент, показывающий разницу между auto-fit и auto-fill в гриде CSS:

Обратите внимание, что при использовании auto-fit элементы расширяются, чтобы заполнить доступное пространство. Однако в случае автоматического заполнения `` элементы грида не будут разрастаться, вместо этого у нас будет свободное пространство (пунктирный элемент в крайнем правом углу).

Возможно, вы сейчас думаете, как этот факт относится к контейнерным запросам. Каждый элемент грида это контейнер, и, когда он расширяется (то есть когда мы используем auto-fit), нам нужно, чтобы компонент изменился, опираясь на это расширение.

<div class="o-grid">  <div class="o-grid__item">    <article class="c-article"></article>  </div>  <div class="o-grid__item">    <article class="c-article"></article>  </div>  <div class="o-grid__item">    <article class="c-article"></article>  </div>  <div class="o-grid__item">    <article class="c-article"></article>  </div></div>
.o-grid {  display: grid;  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));  grid-gap: 1rem;}

Когда элемента четыре, результат должен выглядеть примерно так:

Что произойдёт, когда количество статей уменьшится? Чем меньше у нас будет элементов, тем они будут шире. Так происходит потому, что мы используем auto-fit. Первый выглядит хорошо, но последние два (2 на ряд, 1 на ряд) не очень: они слишком широкие:

Что делать, если каждый компонент статьи изменяется в зависимости от ширины родительского компонента? Если так, auto-fit будет очень хорошим преимуществом. Вот что нужно сделать: если ширина элемента грида превышает 400 пикселей, статья должна переключиться на горизонтальный стиль, а добиться этого можно так:

.o-grid__item {  contain: layout inline-size;}@container (min-width: 400px) {  .c-article {    display: flex;    flex-wrap: wrap;  }}

Кроме того, если статья единственный элемент в гриде, хочется отобразить её с разделом hero.

.o-grid__item {  contain: layout inline-size;}@container (min-width: 700px) {  .c-article {    display: flex;    justify-content: center;    align-items: center;    min-height: 350px;  }  .card__thumb {    position: absolute;    left: 0;    top: 0;    width: 100%;    height: 100%;    object-fit: cover;  }}

Вот и всё. У нас есть компонент, реагирующий на ширину родительского компонента, и он работает в любом контексте. Разве это не потрясающе? Посмотрите демо на CodePen.

aside и main

Часто нам нужно настроить компонент, чтобы он работал в контейнерах небольшой ширины, таких как <aside>. Идеальный пример раздел новостей. Когда ширина маленькая, нужно, чтобы её элементы складывались, а когда места достаточно, нужно горизонтальное расположение элементов.

Как видно на рисунке, мы работаем с разделом новостей в двух разных контекстах:

  • Раздел aside.

  • Раздел main.

Такое невозможно без контейнерных запросов, если у нас нет класса вариаций в CSS, например .newsletter--stacked или чего-то в этом роде.

Я знаю, что мы можем сказать браузеру, чтобы элементы были обтекающими в случае, когда flexbox не хватает пространства, но этого недостаточно. Мне нужно гораздо больше контроля, чтобы делать кнопку во всю ширину и прятать определённые элементы:

.newsletter-wrapper {  contain: layout inline-size;}/* The default, stacked version */.newsletter {  /* CSS styles */}.newsletter__title {  font-size: 1rem;}.newsletter__desc {  display: none;}/* The horizontal version */@container (min-width: 600px) {  .newsletter {    display: flex;    justify-content: space-between;    align-items: center;  }  .newsletter__title {    font-size: 1.5rem;  }  .newsletter__desc {    display: block;  }}

Вот видео с результатом.

Посмотрите демоверсию на CodePen.

Пагинация

Я обнаружил, что контейнерные запросы хорошо подходят для пагинации. Сначала у нас могут быть кнопки Previous и Next; если пространства достаточно, можно скрыть кнопки и показать всю нумерацию страниц. Посмотрим на рисунок ниже:

Чтобы справиться с приведёнными выше состояниями, сначала нужно поработать над стилем по умолчанию (кнопками в виде стопки), а затем над двумя другими состояниями.

.wrapper {  contain: layout inline-size;}@container (min-width: 250px) {  .pagination {    display: flex;    flex-wrap: wrap;    gap: 0.5rem;  }  .pagination li:not(:last-child) {    margin-bottom: 0;  }}@container (min-width: 500px) {  .pagination {    justify-content: center;  }  .pagination__item:not(.btn) {    display: block;  }  .pagination__item.btn {    display: none;  }}

Посмотрите демоверсию на CodePen.

Карточка профиля

Вот ещё один пример применения: контейнерные запросы идеально работают в нескольких контекстах. Состояние малого размера работает при маленьких видовых экранах и в контекстах вроде сайдбара. Состояние большого размера работает при гораздо больших контекстах, таких как размещение в гриде из двух колонок.

.p-card-wrapper {  contain: layout inline-size;}.p-card {  /* Default styles */}@container (min-width: 450px) {  .meta {    display: flex;    justify-content: center;    gap: 2rem;    border-top: 1px solid #e8e8e8;    background-color: #f9f9f9;    padding: 1.5rem 1rem;    margin: 1rem -1rem -1rem;  }  /* and other styles */}

При помощи этого кода теперь мы видим, как компоненты работают в разных контекстах без единого медиазапроса.

Посмотрите демоверсию на CodePen.

Элементы формы

Я ещё не углублялся в случаи применения контейнерных запросов для форм, но в голове держу переключение с горизонтальных меток на метки в стопку.

.form-item {  contain: layout inline-size;}.input-group {  @container (min-width: 350px) {    display: flex;    align-items: center;    gap: 1.5rem;    input {      flex: 1;    }  }}

Посмотрите демо на CodePen.

Тестирование компонентов

Теперь, когда мы рассмотрели несколько случаев, когда контейнерные запросы могут быть полезны, возникает вопрос: как протестировать компонент? К счастью, мы можем сделать это с помощью свойства родительского компонента resize.

.parent {  contain: layout inline-size;  resize: horizontal;  overflow: auto;}

Об этом методе я узнал из этой замечательной статьи Брамуса Ван Дамма.

Легко ли отлаживать контейнерные запросы в DevTools?

Короткий ответ нет. Вы не увидите чего-то вроде @container (min-width: value). Я думаю, что это дело времени, поддержка такой отладки появится.

А запасной вариант для браузеров без контейнерных запросов?

Да! Конечно. Определённым образом можно предоставить альтернативу. Вот две замечательные статьи с объяснением, как это сделать:

Заключение

Мне понравилось изучать контейнерные запросы в CSS и играть с ними в браузере. Я знаю, что они ещё официально не поддерживаются, но сейчас для этого самое время. Часть нашей работы как фронтендеров заключается в том, чтобы тестировать функции браузеров и помогать работающим над их реализацией людям. Чем лучше протестирована экспериментальная функциональность, тем меньше проблем мы увидим, когда она станет поддерживаться во всех основных браузерах.

Если вы уже имеете некоторые навыки работы с CSS, но всё ещё не можете сказать, что разбираетесь во фронтенде можете обратить внимание на наш курс-профессию Frontend-разработчик, где вы сможете научиться создавать адаптивные веб-сайты сиспользованием CSS, Flexbox, разрабатывать интерактивные веб-сайты иприложения на JS иHTML, а также писать сложные компоненты на React и интерфейсы с авторизацией и с подключением к бэкенду.

Ну а если фронтенд для вас давно родная стихия пора смотреть в сторону Fullstack-разработчика, настоящего универсала веб-разработки, которому будут рады в любом крупном проекте.

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

Другие профессии и курсы
Подробнее..

Перевод Примеры применения переменных CSS на практике

30.04.2021 14:04:59 | Автор: admin

Когда я впервые попробовал использовать переменные CSS, у меня не было полного представления об их возможностях. Правильное их использование позволяет существенно сократить время и трудозатраты на решение определённых задач в CSS.


Если вы ещё не работали с переменными CSS, рекомендую прочитать эту статью, чтобы познакомиться с ними. Как только вы их освоите, работа станет намного проще. Цель этой статьи сосредоточить внимание на разных случаях практического использования переменных CSS помимо их применения для создания маркеров дизайна, таких как цвета.

Вы готовы? Тогда вперёд!

В чём основная проблема?

Если вы используете переменные CSS так же, как и препроцессоры CSS (например в Sass), то вы не полностью реализуете все их преимущества. Рассмотрите следующий пример:

:root {    --brand-primary: #7777e9;    --brand-secondary: #c96fde;}.title {    color: var(--brand-primary);}

И тут нет никакой разницы с нижеприведённым примером в Sass:

$brand-primary: #7777e9;$brand-secondary: #c96fde;.title {    color: $brand-primary;}

Да, применение переменных CSS в качестве переменных цвета ни в коей мере не является ошибкой. Но это всё равно, что покупать Apple MacBook M1 для посещения интернет-сайтов, хотя с этим и так хорошо справляется ваш старый настольный ПК, собранный в 2012 году. Какой смысл покупать ультрасовременный компьютер и делать на нём то же самое, никак не используя весь спектр его возможностей? Как вы понимаете, примерно так я и думаю об использовании переменных CSS для сохранения информации о цветах.

Цель этой статьи познакомить с различными вариантами практического применения, где полностью раскрываются возможности переменных CSS. Приступаем!

Примеры и случаи практического использования

Полные формы записи свойств

В некоторых сценариях может потребоваться настройка полной версии записи свойства. Например, свойство внутреннего отступа может быть различным для разных компонентов. Вместо того чтобы заново переписывать полную форму записи этого свойства, мы можем использовать переменную CSS для изменяемого компонента, после чего она будет переопределяться вариациями классов в CSS.

<!-- Base component --><header class="page-header">    <h2>...</h2>    <p>...</p></header><!-- Component variation --><header class="page-header page-header--compact">    <h2>...</h2>    <p>...</p></header>
.page-header {    --padding-start: 2.5rem;    --padding-block: 2rem;    padding: var(--padding-block) 1rem var(--padding-block) var(--padding-start);}.page-header--compact {    --padding-start: 1.5rem;    --padding-block: 1rem;}

Обратите внимание, для изменения заполнения нам потребуется всего лишь изменить значение переменной CSS. Без неё нам было бы необходимо вручную вводить полную форму записи свойства внутреннего отступа padding, чтобы изменить только одно значение в нём.

.page-header {    padding: 2rem 1rem 2rem 1.5rem;}.page-header--compact {    padding: 1rem 1rem 1rem 2.5rem;}

Всё вышесказанное применимо и для свойства внешнего отступа margin.

Свойства CSS background

Что касается свойств CSS для работы с фоном, то и здесь переменные CSS помогают сократить объём создаваемого нами кода. И даже больше того: благодаря их применению сам код CSS легче читать.

Хранение значений URL

При работе с интерфейсом пользователя вам может потребоваться добавить какое-либо изображение в декоративных целях. В таком случае хорошим решением будет использование элементов <div> и background-image. Если интерфейс должен быть динамическим, то значения для изображения нужно подставлять с помощью JavaScript.

Без применения переменных CSS соответствующий код HTML будет выглядеть так:

<section     class="newsletter"     style="background-image: url('/assets/ui/decoraitve/newsletter-lg-aj1891101.svg')"></section>

Но вместо того, чтобы напрямую изменять свойство background-image, мы можем сделать следующее.

<section     class="newsletter"     style="--thumb:url('/assets/ui/decoraitve/newsletter-lg-aj1891101.svg')"></section>
.newsletter {    background-image: var(--thumb);    background-size: cover;    background-position: 100% 50%;}

Обратите внимание, что необходимо включить элемент url() без переменной CSS.

Положение фонового изображения

В приведённом выше примере фоновое изображение помещается справа. Для макетов с направлением текста справа налево (RTL) положение фона следует перевернуть.

.newsletter {    --pos: 100% 50%;    background-image: var(--thumb);    background-size: cover;    background-position: 100% 50%;}html[dir="rtl] .newsletter {    -background-position: 0% 50%;}

Чтобы упростить эту задачу, мы можем воспользоваться переменными CSS.

.newsletter {    /* other styles */    background-position: var(--pos);}html[dir="rtl] .newsletter {    --pos: 0% 50%;}

Угловой градиент: часть 1

Угловой градиент также можно применять при создании макетов для нескольких языков. По умолчанию он может быть равен 45deg, и, возможно, потребуется изменить его на -45deg для макетов RTL.

.element {    --angle: 90deg;    background: linear-gradient(var(--angle), #4088vb, #C05858);}html[dir="rtl] .element {    --angle: -90deg;}

Угловой градиент: часть 2

В случае с угловым градиентом использование переменных CSS с радиальными градиентами действительно существенно упрощает настройку положения. В следующем примере положение градиента изменяется при помощи переменной --pos.

А здесь показано, как можно сделать то же самое без переменных CSS.

.card {    background: radial-gradient(        circle 200px at center top,        rgba(64, 136, 203, 0.5),        #f7f7f7    );}

Теперь предположим, что у нас есть какой-то вариант карточки .card-2 и он должен находиться в другом положении. Необходимо написать следующий код:

.card-2 {    background: radial-gradient(        circle 200px at center top,        rgba(64, 136, 203, 0.5),        #f7f7f7    );}

Таким образом, переписывается всё определение градиента. Можно ли сделать лучше? Определённо. Обратите внимание, что единственным настраиваемым значением для этого варианта является переменная --pos.

.card {    --pos: center top;    background: radial-gradient(        circle 200px at var(--pos),        rgba(64, 136, 203, 0.5),        #f7f7f7    );}.card-2 {    --pos: left top;}

Свойство clip-path

Весьма полезным случаем использования переменной CSS является изменение с её помощью значений clip-path: polygon() при переходе с настольных на мобильные устройства.

На показанном выше рисунке необходимо изменить положение вершин многоугольника. С помощью переменных CSS сделать это намного проще.

.hero {    --first: 4% 7%;    --second: 80% 0;    --thrid: 100% 95%;    --fourth: 10% 100%;    clip-path: polygon(var(--first), var(--second), var(--thrid), var(--fourth));}@media (min-width: 40rem) {    .hero {        --second: 96% 0;        --thrid: 92% 82%;    }}

Если вы хотите узнать больше о свойстве CSS clip-path, здесь вы найдёте статью за авторством вашего покорного слуги.

Элемент флажка

Великолепный пример использования переменных CSS это применение их в сочетании с функцией определения цветов hsla(). Таким образом мы можем создавать динамические компоненты, которые затем можно менять, корректируя одну или несколько переменных CSS.

Первое, что я сделал, это определил значения hsla() для корневого элемента компонента.

.form-item {    --primary-h: 240;    --primary-s: 56%;    --primary-l: 63%;    --primary-alpha: 100%;}

Теперь я могу использовать эти свойства в функции определения цветов hsla().

/* The circle that appears on hover */.form-item__label:after {    --primary-alpha: 0;    background-color: hsla(        var(--primary-h),        var(--primary-s),        var(--primary-l),        var(--primary-alpha)    );}.form-item__label:hover:after {    --primary-alpha: 15%;}

Код SVG, встроенный в CSS

Когда-то я работал над пользовательским интерфейсом для проекта одного клиента и столкнулся с такой ситуацией. У нас был раздел с двумя лентами (одна сверху, а вторая снизу). Мне необходимо было изменить цвет, угол поворота и размер этих лент, не создавая отдельный код CSS для каждой из них. Спасением стали переменные CSS!

Прежде всего я подготовил требуемый код SVG в Adobe Illustrator. Я разделил каждую ленту на три слоя:

  • светлые области;

  • тёмные области;

  • базовый слой.

Затем я экспортировал этот код SVG и поместил его в элементах <defs> так, чтобы легко можно было использовать его повторно. Обратите внимание, я также добавил ключевое слово currentColor! Это и есть то самое магическое значение, которое заставит всё работать.

Наконец, теперь нам необходимо определить размер и угол поворота в CSS.

.tape {    width: var(--size);    transform: rotate(var(--angle));}
<svg class="tape" style="--angle: 10deg; color: red; --size: 120px;" aria-hidden="true" focusable="false" viewBox="0 0 123 47">  <use href="#tape"></use></svg>

Готово. Мы создали собственный код SVG, который можно настраивать по мере необходимости. Впечатляет, не правда ли?

Создание миксинов (примесей-шаблонов), таких, как в Sass

Об этой интересной возможности я узнал из рекомендуемого мною к просмотру выступления Ли Веру (Lea Verou). Идея состоит в том, чтобы установить исходные переменные CSS для определённого свойства, а затем переопределять их, когда это понадобится.

Здесь показан пример, как мы можем использовать эту возможность. Очень часто мне необходимо, чтобы враппер был центрирован, для чего можно добавить margin: 0 auto к соответствующему элементу враппера. В тех случаях, когда необходимо отцентрировать какой-то свой элемент, мы можем выполнить следующее:

<div class="featured-section u-center"></div>
.u-center {  --mx: initial;  --my: initial;  margin: var(--my) var(--mx);}.featured-section {  --mx: auto;  --my: 2rem;}

Во-первых, я создал служебный класс .u-center с заданными по умолчанию значениями для горизонтальных и вертикальных внешних отступов. Я могу добавить этот класс к элементу и затем переопределить переменные CSS. Это может оказаться очень полезным, например, если элементу нужны определённые внешние отступы только с верхней и нижней сторон.

Использование функции calc()

Функция calc() в сочетании с переменными CSS может очень пригодиться. Мы можем создать какой-то базовый размер для компонента, а затем, меняя только одну переменную, можем делать его больше или меньше.

Это может оказаться полезным в самых разных случаях применения. Давайте предположим, что нам необходимо создать несколько вариантов для аватара пользователя.

.c-avatar {  width: calc(var(--size, 32) * 1px);  height: calc(var(--size, 32) * 1px);}

Обратите внимание, я использовал функцию var(--size, 32). Если переменная --size не определена, то значение 32 будет использовано как резервное значение. Важно указать 1px, чтобы добавить px к результирующему числу.

Таким образом, мы можем создавать вариации классов, просто добавляя переменную CSS --size.

.c-avatar--medium {    --size: 64;}.c-avatar--large {    --size: 128;}

Псевдоэлементы

С помощью переменных CSS можно изменять свойство псевдоэлемента, поскольку оно наследуется от родительского элемента. Рассмотрите следующий пример:

В заголовке раздела содержится декоративная фиолетовая линия, которая является псевдоэлементом. Мы можем передать переменную CSS данному заголовку, и этот псевдоэлемент унаследует её.

.section-title {    --dot-color: #829be9;}.section-title:before {    content: "";    background-color: var(--dot-color);}

Но, кроме того, мы также можем имитировать изменение цвета псевдоэлемента с помощью Javascript.

Встроенные стили

Другим примером полезного применения переменных CSS является использование их в качестве встроенных стилей. И тут открывается множество возможностей для настройки какого-либо компонента путём изменения одной или нескольких переменных.

Рассмотрите следующий пример.

.o-grid {    display: grid;    grid-template-columns: repeat(auto-fit, minmax(var(--item-width, 200px), 1fr);    grid-gap: var(--gap);}

У нас есть настроенный грид и заданное по умолчанию для ширины элемента грида значение 200px. В коде HTML мы можем переопределить его, переустановив значение для переменной CSS.

<!-- Example 1 --><div class="o-grid" style="--item-width: 250px;">     <div></div>     <div></div>     <div></div></div><!-- Example 2 --><div class="o-grid" style="--item-width: 350px;">     <div></div>     <div></div>     <div></div></div>

Ну разве это не полезно? Если вы хотите узнать больше о переменных CSS со встроенными стилями, я уже писал об этом более подробно.

Заключение

Как вы могли убедиться, существует множество примеров использования переменных CSS помимо определения цветов с их помощью. Уверен, то что я показал, это лишь самые поверхностные варианты их применения. Если вы придумали какой-то свой уникальный вариант использования поделитесь им в комментариях!

Если фронтенд-разработка для вас давно родная стихия можно уже задуматься о грейде доFullstack-разработчика, настоящего универсала веб-разработки, которому будут рады в любом крупном проекте. На нашем курсе, помимо современной программы, вас ждет много практики в разных форматах от преподавателей с опытом коммерческой разработки. Приходите учиться, будет сложно, но интересно!

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

Другие профессии и курсы
Подробнее..

Перевод Почему стоит использовать тег ltpicturegt вместо ltimggt

05.05.2021 10:13:29 | Автор: admin
image

Использование изображений и анимаций в интерфейсах пользователя стало распространённой практикой в современных веб-приложениях. Хотя эти примеры современного дизайна делают упор на повышение удобства работы с приложениями, если изображения не адаптируются ко всем устройствам, то могут возникать проблемы.

Мы, разработчики, должны удовлетворять потребностям пользователей. Но чаще всего мы упускаем мелочи, способные быть очень важными из-за того, что мы ищем решения на более высоких уровнях.

Выбор между тегами picture и img может показаться мелким решением, но сделав правильный выбор, вы сможете повысить и удобство для пользователя, и производительность.

В этой статье мы расскажем о различиях между тегами picture и img и объясним, почему тег picture более совершенен, чем img.

Когда в следующий раз вы будете создавать компонент изображения на React, то воспользуйтесь полученными в этой статье знаниями. Возвращайте подходящий тег в соответствии с полученными свойствами и обрабатывайте все необходимые альтернативы. Благодаря этому вы получите супероптимизированнй компонент изображения, который можно использовать во всех веб-проектах.

Почему тега img недостаточно для современных веб-приложений?


Как все мы знаем, тег Img в течение длительного периода времени был одним из фундаментальных элементов HTML, и никто не сомневался в его простоте и применимости.

Однако с появлением устройств, имеющих разные размеры экрана, разрешения и сложные требования, начали возникать вопросы об отзывчивости этого тега и возможности его использования в приложениях, рассчитанных на множество различных устройств.

Все эти вопросы можно сгруппировать в две большие категории:

  1. Смена разрешения проблема передачи изображений меньшего размера для устройств с маленькими экранами.
  2. Ориентация графики проблема отображения различных изображений при разных размерах экрана.

Давайте посмотрим, как решаются эти проблемы и узнаем о дополнительных возможностях тега picture.

Смена разрешения при помощи атрибутов srcset и sizes


Как говорилось выше, современные веб-дизайнеры для привлечения пользователей часто используют изображения высокого разрешения. Но мы, разработчики, должны внимательно выбирать подходящий HTML-элемент.

Допустим, вы используете простой тег Img для изображений высокого разрешения. В таком случае при запуске приложения одно и то же изображение будет использоваться на каждом устройстве, что приведёт к проблемам с производительностью в устройствах с низким разрешением экрана, например, в мобильных телефонах.

Это может привести к более долгой загрузке изображений и частичной загрузке изображений сверху вниз.


Проблема загрузки изображения сверху вниз

Эту проблему можно легко решить тегом picture при помощи атрибутов srcset и sizes.

<picture>   <source      srcset="small-car-image.jpg 400w,              medium-car-image.jpg 800w,              large-car-image.jpg 1200w"      sizes="(min-width: 1280px) 1200px,             (min-width: 768px) 400px,             100vw">   <img src="medium-car-image.jpg" alt="Car"></picture>

Атрибут srcset может принимать несколько изображений с соответствующей шириной в пикселях, а браузер использует эти значения для выбора между указанными изображениями. В показанном выше примере есть три версии одного и того же изображения в трёх разных размерах.

Атрибут sizes задаёт пространство, которое изображение будет занимать на экране. В показанном выше примере изображение займёт до 1200px, если минимальная ширина экрана равна 1280px.

Тем не менее, рекомендуется не использовать тег Picture только для смены разрешения, потому что ту же задачу можно решить с помощью новой версии тега Img (имеющей поддержку большего количества браузеров).

<img srcset="small-car-image.jpg 400w,             medium-car-image.jpg 800w,             large-car-image.jpg 1200w"     sizes="(min-width: 1280px) 1200px,            (min-width: 768px) 400px,            100vw"          src="medium-car-image.jpg" alt="Car">

Однако в большинстве случаев нам нужно решать проблему и смены разрешения, и ориентации графики, и лучшим решением для этого является тег picture.

Поэтому давайте посмотрим, как можно решить проблему ориентации графики с помощью тега picture.

Ориентация графики при помощи атрибута media


Основной принцип ориентации графики показ различных изображений на основании размера экрана устройства. В большинстве случаев, изображение замечательно выглядящее на больших экранах, оказывается обрезанным или очень мелким при просмотре на мобильном устройстве.

Мы можем решить эту проблему, создав различные версии изображения для разных размеров экрана. Эти разные версии могут быть альбомными, портретными или любыми другими изменёнными версиями того же изображения.

С помощью тега picture мы можем легко обеспечить смену разрешения, воспользовавшись несколькими тегами source внутри тега picture.

<picture>      <source ....>   <source ....>   <source ....></picture>

Затем можно использовать атрибут media для задания различных условий среды, в которых будут использоваться эти источники. Также можно использовать атрибуты srcset и sizes аналогично тому, о чём мы говорили в предыдущем разделе.

В показанном ниже примере демонстрируется полная реализация ориентации графики и смены разрешения при помощи тега picture.

<picture>        <source media="(orientation: landscape)"                   srcset="land-small-car-image.jpg 200w,              land-medium-car-image.jpg 600w,              land-large-car-image.jpg 1000w"                   sizes="(min-width: 700px) 500px,             (min-width: 600px) 400px,             100vw">        <source media="(orientation: portrait)"                   srcset="port-small-car-image.jpg 700w,              port-medium-car-image.jpg 1200w,              port-large-car-image.jpg 1600w"                   sizes="(min-width: 768px) 700px,             (min-width: 1024px) 600px,             500px">        <img src="land-medium-car-image.jpg" alt="Car"></picture>

Если экран находится в альбомной ориентации, то браузер будет отображать изображения из первого набора, а если в портретной, то из второго набора. Кроме того, можно использовать атрибут media с параметрами max-width и min-width:

<picture>     <source media="(max-width: 767px)" ....>     <source media="(min-width: 768px)" ....></picture>

Последний тег img используется для обратной совместимости с браузерами, не поддерживающими теги picture.

Использование с частично поддерживаемыми типами изображений


Благодаря быстрому развитию технологий ежедневно появляется множество современных типов изображений. Некоторые из них, например webp, svg и avif, обеспечивают большее удобство для пользователей.

С другой стороны, у некоторых браузеров существуют ограничения в обработке этих современных типов изображений, и если не использовать совместимые типы изображений, это может вызвать проблемы.

Но мы можем с лёгкостью решить эту проблему при помощи тега Picture, поскольку он позволяет нам указать внутри несколько источников.

<picture>  <source srcset="test.avif" type="image/avif">  <source srcset="test.webp" type="image/webp">  <img src="test.png" alt="test image"></picture>

В показанный выше пример включены три типа изображений в форматах avif, webp и png. Сначала браузер попробует формат avif, если не получится, то попробует webp. Если браузер не поддерживает ни один из них, то использует изображение png.

Ситуация с тегом picture стала ещё интереснее, когда разработчики Chrome объявили о том, что во вкладке Rendering инструментов DevTools появится две новые эмуляции для эмулирования частично поддерживаемых типов изображений.

Начиная с Chrome 88 и далее можно использовать Chrome DevTools для проверки совместимости браузера с типами изображений.


Использование Chrome DevTools для эмулирования совместимости изображений

В заключение


Хоть мы и говорили о том, насколько лучше тег picture по сравнению с тегом img, я уверен, что img не умер и умрёт ещё не скоро.

Если мы будем с умом использовать имеющиеся у него атрибуты srcset и size, то можем выжать из тега img максимум. Например, можно решить проблему смены разрешения при помощи одного только тега img.

С другой стороны, можно использовать тег picture, чтобы решить проблемы и смены разрешения, и ориентации графики с помощью запросов условий среды и других атрибутов.

Среди прочих достоинств тега picture способность работать с частично поддерживаемыми типами изображений и поддержка Chrome DevTools.

Однако оба эти элемента имеют свои плюсы и минусы. Поэтому нам нужно обдумывать и выбирать наиболее подходящий к нашим требованиям элемент.



На правах рекламы


Эпичные серверы это VDS для размещения сайтов от маленького интернет-магазина на Opencart до серьёзных проектов с огромной аудиторией. Создавайте собственные конфигурации серверов в пару кликов!

Подписывайтесь на наш чат в Telegram.

Подробнее..

Перевод Взгляд на Tailwind CSS

23.05.2021 18:15:00 | Автор: admin

В этом году я видел много шумихи вокруг популярного фреймворка CSS, Tailwind CSS. И подумал, что поделюсь некоторыми мыслями и опасениями по поводу этого фреймворка UI. Я приобрёл небольшой опыт написания CSS с подходом utility-first (полезность прежде всего), когда начал свою карьеру в разработке интерфейсов, несколько лет назад.

К старту курса о Frontend-разработке делимся статьёй, автор которой решил, возможно, несколько изменить то, как воспринимается Tailwind, рассказать как о положительных, так и об отрицательных сторонах фреймворка, особенно в контексте работы с мультиязычными сайтами.


Вещи, которые я считаю интересными

Вам не нужно закрывать файл с HTML

Основной заголовок на официальном сайте Tailwind гласит:

Быстрое создание современных веб-сайтов, даже не покидая HTML.

Я согласен, что писать код в одном месте может быть быстрее, чем переключаться между разными файлами. Однако оставить в стороне свой HTML для меня не проблема. Это может помочь переключить контекст между разметкой и стилями. Разделение файлов HTML и CSS может помочь мне лучше сосредоточиться на выполнении поставленной задачи. Однако, когда разметка и стили смешиваются, когда вы работаете над сложным, многоязычным, отзывчивым сайтом и пользовательским интерфейсом с темами, всё может пойти наперекосяк.

Когда я работаю с Tailwind, это похоже на то, как если бы я держал две ручки: одну для набросков, а другую для раскрашивания. Одновременное написание разметки и CSS напоминает мне эти две ручки.

Tailwind сильно отличается тем, что у цветной ручки есть ограничения или сдерживающие факторы. Другими словами, можно раскрашивать только предустановленными цветами. По мне так лучше сосредоточиться на написании доступной, семантической разметки, а затем отдельно работать со стилизацией.

Проектные ограничения

В дизайн-системе мы обычно определяем цвет, интервал, размер и другие свойства. Работа разработчика сильно упрощается, когда есть пределы тому, что он может сделать. Tailwind накладывает хорошие ограничения. Идея определения пользовательских конфигурационных файлов очень полезна.

Именование классов CSS

О названиях классов CSS думать не нужно и это может ускорить реализацию макетов в вебе. Я нахожу это полезным в случае, когда ваш босс пишет вам, что есть срочный лендинг, который должен быть сделан сегодня, и у вас только 3 часа, чтобы написать его. Tailwind может помочь быстро достичь результата.

Однако, если вы придерживаетесь разделения разметки и стилей, разработка займёт гораздо больше времени. Ещё одно полезное применение Tailwind это соревнование или хакатон. Самое главное на таких событиях сделать работу и что-то получить за неё. Никому не будет дела до того, как вы написали CSS, верно?

То, с чем я не согласен

Tailwind не фреймворк utility-first

Подзаголовок на их веб-сайте сообщает, что CSS Tailwind:

Прежде всего утилитарный CSS-фреймворк, содержит такие классы, как...

Из увиденного я сделал вывод, что Tailwind это только утилитарный (utility-only) фреймворк. Может быть, название "только утилитарный" повлияет на то, как его воспримут новички? Я редко вижу какой-то сайт, использующий Tailwind и применяющий концепцию utility-first.

Длинный список классов может запутать

Обратите внимание на то, что я знаю о методе @apply. Рассмотрим пример из документации Tailwind:

<input  class="block appearance-none bg-white placeholder-gray-600 border border-indigo-200 rounded w-full py-3 px-4 text-gray-700 leading-5 focus:outline-none focus:border-indigo-400 focus:placeholder-gray-400 focus:ring-2 focus:ring-indigo-200"  placeholder="jane@example.com"/>

Это поле ввода с 17 классами CSS. Что проще: читать классы один за одним горизонтально или сканировать их сверху вниз? Вот так поле будет выглядеть стиль этого поля в файле CSS:

.c-input {  display: block;  appearance: none;  background-color: #fff;  @include placeholder(grey);  border: 1px solid rgba(199, 210, 254, var(--tw-border-opacity));  border-radius: 0.25rem;  padding: 0.75rem 1rem;  line-height: 1.25rem;  color: rgba(55, 65, 81, var(--tw-text-opacity));}.c-input:focus {  /* Focus styles.. */}

Я могу прочитать и понять, какие стили содержит это поле ввода, гораздо быстрее, чем в ситуации, когда сканирую HTML. Возможно, существуют плагины для редакторов кода, которые автоматически форматируют HTML-классы так, чтобы каждый из них располагался отдельно [на отдельной строке], но в DevTools браузера этого нет.

Я знаю о методе @apply, но каждый раз, когда я думаю о нём, я прихожу к выводу, что он противоречит основной концепции Tailwind. Вот тот же пример (поле ввода):

.c-input {  @apply block appearance-none bg-white placeholder-gray-600 border border-indigo-200 rounded w-full py-3 px-4 text-gray-700 leading-5 focus:outline-none focus:border-indigo-400 focus:placeholder-gray-400 focus:ring-2 focus:ring-indigo-200;}

Посмотрите на длину списка классов. Если в Tailwind в приоритете полезность, то почему в официальной документации Tailwind или в Tailwind UI мы редко видим @apply? Опять же, я вижу Tailwind как только утилитарный фреймворк.

Всегда нужно давать имена элементам

В дизайн-системе трудно обсуждать конкретный компонент, не договорившись о его названии. Причина вот в чём: вы не отправите своему коллеге сообщение вроде такого:

Привет, есть новости о bg-white w-full py-3 px-4?

На самом деле фраза будет такой:

Есть новости о дизайне поляризованной карты?

В конце дня вам нужно будет сесть и подумать об уникальном, выразительном названии для каждого компонента проекта, который вы пытаетесь разработать. Это применимо, конечно, к ситуации, когда вы хотите масштабировать и поддерживать проект в течение длительного времени. Некоторое время назад я шутил с другом вот о чём: что, если мы отложим традиционное именование в сторону и будем называть себя не традиционными именами, а как в коде ниже:

<person class="hair-brown length-[175] face-rounded"></person>

Код выше бессмыслица. Гораздо лучше такой код:

<person class="ahmad"></person>

Некоторые классы запутывают

Когда я только начинал использовать Tailwind, мне нужно было добавить класс, который отвечает за свойство align-items: center. Моей первой мыслью было воспользоваться align-center, но это не сработало.

Я посмотрел в документацию и впал в замешательство. Класс items-center добавит CSS-свойство align-items: center, где класс align-middle будет содержать vertical-align: middle. Чтобы запомнить их, требуется немного мышечной памяти.

Опытные веб-разработчики могут легко адаптироваться к этому, и это не будет для них большой проблемой. Но самое интересное для новичка в CSS. Изучение Tailwind без уверенного знания CSS может привести к недопониманию в будущем. Например, если разработчик начал свою карьеру только с Tailwind, то, когда его попросят написать CSS с нуля, он не сможет этого сделать. Я не говорю, что это невозможно, но это потребует времени и усилий.

Tailwind затрудняет настройку дизайна в браузере

Я занимаюсь как дизайном, так и frontend-разработкой, поэтому редактирование в браузере с помощью DevTools для меня крайне важно. С Tailwind работа в DevTools может стать сложнее. Скажем, например, я хочу изменить отступы для компонента. Когда я изменяю значение класса py-3, это влияет на каждый использующий его элемент страницы.

Единственный способ убрать его открыть меню .cls в DevTools, после чего класс можно будет переключить. Однако это не решает проблему. Что я могу сделать в этом случае? Добавить встроенный стиль через DevTools, а это мне не нравится. Проблема решится, если просто давать элементам названия. Добавлю к этому факт: общий размер файла полной сборки Tailwind составляет 12 МБ. Редактирование CSS в DevTools будет очень медленным.

Это означает, что разработка в браузере неэффективна. Недавно команда Tailwind выпустила компилятор JIT (just in time), удаляющий неиспользуемый CSS. Это мешает всей идее дизайна в браузере.

Я набрал back и получил длинный список всех доступных классов CSS. При JIT-компиляции таких подсказок не будет.

Tailwind неудобен для многоязычных сайтов

Чтобы вы больше понимали, добавлю: я работаю над веб-сайтами, которые должны работать как на английском (с направлением слева направо, LTR), так и на арабском (с направлением справа налево, RTL). Рассмотрим такой код:

/* LTR: left to right */.c-input {  padding-left: 2rem;}

В отдельном файле CSS для RTL стиль будет выглядеть так:

/* RTL: Right to left */.c-input {  padding-left: 0;  padding-right: 2rem;}

В приведённом выше примере padding следует развернуть в зависимости от направления страницы (слева направо или справа налево). Для этого уже есть плагины, но они решают проблему только с внешней стороны. Первый найденный мной делает следующее:

html[dir="rtl"] .ml-2 {   margin-right: 1rem; }

Для меня это не очень хорошее решение. Второй найденный плагин немного отличался от первого:

[dir="rtl"] .rtl\:text-2xl {  font-size: 1.5rem;  line-height: 2rem;}

Такой код может очень быстро выйти из-под контроля. Исследуя один веб-сайт, я заметил более 30 классов CSS.

Это пример того, как Taillwind может выйти из-под контроля, особенно у новичков. Тридцать классов для компонента кнопки это слишком много. В таком случае я лучше поработаю со встроенными (inline) стилями.

Чтобы помочь в создании многоязычного веб-сайта, сейчас я использую Bi-App Sass. Вот пример:

.elem {  display: flex;  @include margin-left(10px);  @include border-right(2px solid #000);}

Код скомпилируется в два разных файла CSS. Файл ltr:

/* LTR Styles */.elem {  display: flex;  margin-left: 10px;  border-right: 2px solid #000;}

Подробнее о стилизации RTL читайте в этом руководстве от вашего покорного слуги.

Я не всегда работаю с шаблонами

Одна из проблем Tailwind заключается в том, что, если у вас есть список карточек и вы хотите изменить определённый набор классов, вам придётся вручную просматривать их в редакторе кода. Это не будет проблемой, если вы используете в своём продукте частичные файлы CSS (partial) или компоненты. Вы можете один раз написать HTML, и любое изменение будет отражено везде, где используется этот компонент.

Это не всегда так. Я работаю над простыми страницами index.html, где усилия в разделении на части или компоненты себя не оправдывают. В этом случае работа с Tailwind и редактирование CSS могут стать процессом, чреватым ошибками, поскольку вы даже не можете использовать функцию "Найти и заменить": она может пропустить некоторые другие элементы на странице.

Tailwind делает веб-сайты похожими

Команда Tailwind создала набор продуманных компонентов под названием Tailwind UI, которые легко настраиваются и готовы к использованию в вашем проекте.

Внешний вид и функциональность компонентов приятные, и мне это нравится. Хотя есть проблемы, если сайт использует Tailwind UI, есть большая вероятность, что я предскажу использовать его.

Обычно, когда вы работа Tailwind UI, это означает, что у вас нет времени на создание индивидуального дизайна, поэтому вам нужно что-то, что можно быстро запустить, верно? И это хороший вариант применения, за исключением одной детали: применение Tailwind приведёт к тому, что многие сайты будут выглядеть похожими друг на друга, подобно тому, что было много лет назад с Bootstrap.

Некоторые свойства или особенности CSS использовать невозможно

К примеру, не включено свойство clip-path, и я полностью понимаю причину. Предположим, мы хотим включить его как компонент. Где мы должны написать код? Здесь:

<article class="block appearance-none bg-white placeholder-gray-600 border border-indigo-200 rounded w-full py-3></article>

Либо примерно так включить его в конфигурацию Tailwind:

// tailwind.config.jsmodule.exports = {  theme: {    clipPath: {      // Configure your clip-path values here    }  }};

Или же сделать следующее:

.card {  @apply block appearance-none bg-white placeholder-gray-600 border border-indigo-200 rounded w-full py-3;  clip-path: inset(20px 20px 50px 20px);}

Заключительные мысли

Может ли Tailwind оборачивать CSS в свои классы во время компиляции?

Представьте себе, что Tailwind появляется только во время компиляции. То есть вы пишете обычный CSS с именованием и всё такое, а умный компилятор преобразует ваш CSS в утилитарные классы. Это было бы воплощением мечты.

Утилитарные классы мощный инструмент, если не перестараться

В своих текущих проектах я использую комбинацию утилитарных классов и обычного CSS. Для меня это идеальное сочетание. Я не теряю возможности утилитарных классов и в то же время использую их, не загромождая HTML.

Фронтенд довольно часто выбирают как точку входа в IT. Но фронтенд это не только внешнее оформление сайтов, но и работа с базами данных, а также внешними API. Фронтенд требует системной, комплексной подготовки. Если вам или вашим знакомым интересно это направление разработки можете присмотреться к нашему курсу о Frontend-разработке, где мы касаемся не только вышеупомянутых тем, но и разработки отзывчивых сайтов при помощи flexbox, работаем с методологией БЭМ и затрагиваем другие аспекты фронтенда.

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

Другие профессии и курсы
Подробнее..

Перевод Самая серьёзная проблема HTML? Разработчики, разработчики, разработчики

27.05.2021 12:14:32 | Автор: admin
image

Мы можем насмехаться над Баллмером за этот полубезумный нервный срыв, но его месседж попал в цель. Если не дать разработчикам инструменты и знания, которые необходимы для работы с вашей системой, они не только будут испытывать трудности, но и не смогут развивать то, над чем вы работаете!

Увы, на практике мы видим, что в этом отношении сами разработчики могут быть своими худшими врагами. Они выбирают ужасные фреймворки, заставляющие их трудиться больше, а не продуманней, или намеренно бравируют своим незнанием фундаментальных основ и копируют чужой код в надежде, что он выполнит нужную задачу.

Ни в одной области это так не очевидно, как в высокомерном, пофигистском, а то и откровенно презрительном отношении к HTML. Нет пределов для бесконечных благоглупостей и ошибочных заявлений от тех, кто не способен написать ни одной строки на этом языке.

Если в двух словах, разработчики воспринимают HTML недостаточно серьёзно, но что произойдёт, если вы укажете им на их слабость? В ответ мы дождёмся только бесконечный поток бессмысленных оправданий того, почему их нельзя отвлекать на его правильную реализацию!

Список слабых оправданий


HTML это ненастоящий язык программирования

Это последовательность команд, которым следуют компьютеры для выполнения задачи. Если и есть другое определение языка программирования, то за четыре десятка лет написания ПО я его не слышал. Является ли от Тьюринг-полным? Нет но тем не менее он сообщает компьютеру, как передать грамматическое и структурное значение контента в машинонезависимом виде. Есть правила по использованию его тэгов, порядка и синтаксиса.

Никого не волнует код, если для пользователя он выглядит правильно

Ровно до того момента, как вы не столкнётесь с незрячими пользователями. HTML это не только то, как выглядит страница Нет! Исправлюсь HTML вообще не о том, как что-то выглядит. HTML нужен для того, что сообщить, какими должны быть элементы с точки зрения грамматики и структуры, чтобы user-agent мог передать это значение пользователю. Поэтому для описания того, как должны выглядеть элементы, у нас есть CSS. Если любой из ваших тэгов, id или классов сообщает о том, как элементы должны выглядеть, то вы выбрали неподходящий код, исходя из неверных предпосылок.

Скринридеры (ПО для чтения страницы вслух), электронные книги со шрифтом Брайля, TTY всё это невизуальные целевые объекты; и не забывайте, что у поисковых движков тоже нет глаз. Им нет ни малейшей разницы, как выглядит ваша страница.

Кроме того, людям важно, что ваша страница медленнее или её хостинг обходится дороже, или она нарушает правила доступности для людей с ограничениями, или она забивает весь доступный канал. Несемантическая разметка, бесконечные и бессмысленные DIV, не делающие ничего, presentational classes все они складываются и влияют на результат!

Вы будете слышать те же оправдания для множества других аспектов веб-разработки, и почти всегда это ложь. Будь то плохая/поломанная семантика, проблемы с доступностью для людей с ограничениями, раздутый необязательный JS, использование технологий веб-приложений для того, что приложением быть не должно, и т.д., и т.п.

Очень часто при использовании всего этого пользователь понимает, что что-то не так, но не может этого объяснить. Пользователи не программисты, они не знают, в чём ошибка и кто в ней виноват, но они ощущают, что что-то не так, всё вкривь и вкось.

А как насчёт следующего несчастного неудачника, которому придётся поддерживать результат вашего труда, в котором собраны все ошибки из списка, как НЕ нужно использовать HTML? Люди всегда болтают о том, как их ужасный поломанный фреймворк должен помогать в совместной работе. Как в два или десять раз больший объём кода, не соответствующий базовым правилам HTML и нарушающий само предназначение этого языка, может улучшить совместную работу?

Но примеры во фреймворках работают именно так, а их писали специалисты

Они не специалисты в веб-разработке. Скорее, специалисты в маркетинге, пропаганде и обмане. Разметка в примерах таких систем, как Bootstrap и Tailwind это кошмарные практики HTML. Они воняют ужасной смесью заявлений я не хочу изучать HTML и CSS и я скучаю по разметке 1990-х, отказываясь от двадцати с лишним лет прогресса. Только потому, что их используют миллионы сайтов (большинство не может ошибаться), а самозванные эксперты поют им хвалебные оды (апелляция к авторитету), не делает их или подобные практики хорошими.

С ванильным кодом работать сложнее

Сложным делаете его вы. В том-то и проблема: игнорируя семантические правила структурирования и весь смысл предназначения HTML, вы усложняете работу с ним. Способствует этому и то, что приманки для нубов наподобие W3Schools (aka W3fools) переполнены неточной информацией, вульгарными упрощениями и полным отсутствием большинства из базовых концепций HTML.

Контент должен определять разметку, контент + разметка + целевая среда/возможности user-agent должны определять структуру. Следуя базовой семантике и благодаря постепенному совершенствованию и использованию правильного разделения функциональности, вы в конечном итоге получите набор инструкций, позволяющий с лёгкостью создавать простые в поддержке страницы. Если у вас возникают с этим проблемы и вы считаете, что эти фреймворки HTML/CSS упрощают вашу жизнь, значит, вы недостаточно хорошо знаете HTML или CSS для выполнения хоть каких-то задач.

Вообще, Tailwind проще, чем ванильные HTML/CSS, достаточно просто выучить более 500 классов, 90% из которых уже существуют в виде свойств CSS, а затем игнорировать почти все правила того, как должен использоваться HTML!

Если вы не поняли, это был сарказм.

Вы придаёте слишком большую важность HTML



Я постоянно слышу эту чушь, и меня раздражает её недальновидность!

Это как говорить, что я уделяю слишком много внимания почве под стройплощадкой или материалам, используемым для создания фундамента. Если вы пренебрегаете такими деталями, то не удивляйтесь, что потом всё непонятным образом обвалится или будет затянуто в карстовую воронку!

HTML это фундамент и краеугольный камень. Если им пренебречь, то не удивляйтесь, что результаты будут полной катастрофой.

И в самом деле, многие заблуждения, которыми веб-разработчики убеждают себя не беспокоиться о будущем, не отличаются от тех, которые приводят ко всем инженерным катастрофам. Экономия на качестве, игнорирование спецификаций или конечного пользователя, подпитывание собственного эго; к тому же многие совершают фатальную ошибку путают искусство с проектированием.

Последняя ошибка приводит к возникновению зданий, ослепляющих людей отражённым их окнами солнечным светом: некто, возомнивший себя художником, убеждает людей в костюмах потратить миллиарды на проект, в котором форма важнее функции.

Но HTML не даёт нам инструментов, которые нужны для обеспечения UX

Это оправдание имеет множество разных версий, но в целом они подразумевают написанное выше. Говорящие это почти всегда относятся к поклонникам веб-приложений или одностраничных приложений, они пытаются использовать JavaScript везде, они не заботятся о доступности для людей с ограничениями и настаивают, что пользователям почему-то нужны все их модные причиндалы для улучшения user experience.

Но если быть предельно честным, эти клоуны знают об UX столько же, сколько знают о дизайне художники, впавшие в иллюзию того, что они являются веб-дизайнерами.

И результаты их работы вы УЖЕ СЕЙЧАС видите во всей нашей отрасли: хрупкие, распухшие, медленные решения, которые способен улучшить скриптинг, настолько затормаживают системы корзин интернет-магазинов, что многие из них даже неспособны поддерживать аптайм (привет, Zotac); при этом пользователи ожесточённо жмут на F5, надеясь, что им всё-таки удастся купить видеокарту. Из-за перезагрузки всей страницы целиком и повторного запуска скрипта все функции приложения приводят только к УМЕНЬШЕНИЮ скорости загрузки страницы. И ещё сильнее это проявляется, если вы плюёте на разметку, пользуясь presentational classes.

А поскольку скрипты можно отключать, и генерируемый скриптами контент сложнее для скринридеров, электронных книг со шрифтом Брайля, и так далее, одностраничные приложения (single-page application, SPA) нарушают правила доступности для людей с ограничениями.

Я не говорю, что SPA и им подобные не имеют разумных способов применения, но если вы не можете создать простую корзину или банковский портал с быстрой загрузкой, который мало теряет от отключения скриптов, то вам, вероятно, не стоит заниматься работой на какой бы то ни было бизнес. Веб-приложения НЕ должны использоваться для чего-то столь смехотворно простого, как корзина на веб-сайте!

И если вы думаете, что использование скриптинга для этого действительно улучшает user experience, то вы, очевидно, не тестировали систему на реальных пользователях и реальном трафике! По крайней мере, не выполняли реального сравнения разделения задач с использованием кэша в загрузках нормальных страниц и на страницах с новомодными скриптами.

То есть во всём виноват веб-разработчик?


Ни в коем случае. Вернёмся к началу статьи и к крикам Баллмера разработчики, разработчики, разработчики.

Когда он разыгрывал свою небольшую сценку, она была призвана решить проблему того, что в конце 90-х Windows ни в коем случае не была на первом месте, потому что разработчики часто не использовали предоставляемые компанией Microsoft инструменты. Лучшую документацию по Windows API напечатала Borland. Люди использовали инструменты не от Microsoft, потому что визуальные языки считались игрушками. Они так сильно отставали от технологий веб-разработки, то можно сказать, что они и сейчас пытаются их догнать!

У W3C и WhatWG есть похожие проблемы с тем что так называемые спецификации попросту написаны не для людей, которые пишут веб-сайты. Позвольте мне повторить: спецификация языка, используемого для написания веб-сайтов, предназначена не для людей, которые на самом деле пишут веб-сайты. Она написана для людей, которые пишут user-agents! Браузер это user-agent, но UA не всегда браузер.

На самом деле, это такой абсурд, что идиотическая версия динамичного документа WhatWG ссылается на MDN, чтобы её могли понять простые смертные.

Примечание: я даже не буду начинать рассуждения о том, насколько тупой является сама идея динамичного документа (living document), особенно потому что в реальных HTML-документах отсутствует отслеживание версий. HTML 5, который был валиден в прошлом году, становится сегодня невалидным HTML 5, а сегодняшний валидный HTML 5 может стать невалидным завтра? Отличный способ сделать валидацию совершенно бесполезной!

Простой факт: для получения описаний значений тэгов на простом английском приходится обращаться к сторонним источникам, многие из которых даже не согласуются друг с другом. Более того, W3C стала совершенно беззубой, она слепо соглашается со всем, что говорит WhatWG, даже несмотря на то, что WhatWG многократно доказала, что она не имеет достаточной квалификации для создания потомка HTML 4 Strict. Принятие EMBED в качестве валидного тэга, создание и/или поддержка тэгов, избыточных относительно OBJECT, больше не поддерживаемый (к счастью) тэг HGROUP, показавший, что они даже не понимают, для чего нужны нумерованные заголовки и как их использовать По признанию многих, кто над ним работал, задача HTML 5 на самом деле никогда не заключалась в создании спецификации или стандарта, говорящего нам, как создавать полезные веб-сайты! Она заключалась в документировании того, делают ли сегодня люди правильно или неправильно, и того, что браузеры могут поддерживать, но не того, что они должны поддерживать! Учитывая то, что во время разработки HTML 5 большинство разработчиков всё ещё вбивало HTML 3.2 и набрасывало поверх него извращённый doctype HTML 4, к чему удивляться, что всё оказалось таким скоплением плохих, устаревших и старомодных практик?

Если уж разработчики не воспринимают HTML достаточно серьёзно, то обвинять в этом стоит тех, кто разрабатывал его как спецификацию; даже назвать подобное именем HTML 5 было таким серьёзным преступлением против веб-разработки Как преступлением против музыки стало вручение Грэмми Билли Эйлиш за её бесталанные творения.

W3C и WhatWG даже не воспринимаются серьёзно другими организациями по стандартизации, и на то есть причина.

Каким же должно быть решение?


Неплохо бы для начала добиться от разработчиков, чтобы они не воспринимали HTML как недоразвитого ребёнка от мира языков программирования. В частности, заставить их практиковать семантическую разметку с разделением представления от контента, что сильно повысит юзабилити, доступность и эффективность.

Кроме того, мы сами как разработчики должны сказать своё слово и озадачить W3C за то, что её работа в качестве органа сертификации катастрофически провалилась. Нам нужно потребовать более простую и чистую документацию языка от официального источника. Никак нельзя оправдать то, что документ, описывающий столь простую вещь, как HTML, в пять-десять раз длиннее конституций большинства развитых стран. Само то, что спецификация языка, используемого для создания веб-сайтов, написана не для людей, которые используют язык для создания веб-сайтов, является вотумом недоверия.

Но нам нужна не просто улучшенная официальная документация, необходимо урезать язык, сделать его более ориентированным на задачи. Возродить многие идеи, которые содержались в HTML 5 до того, как W3C выкинула их на помойку и приняла версию WhatWG. Тот факт, что Microsoft потратила десятки лет на то, чтобы IE препятствовал нам использовать OBJECT ещё не причина не только сохранять тэг IMG, но и добавлять множество новых тэгов без нужды (VIDEO, AUDIO). Просто потому, что художники и жулики от маркетинга любят открывать для пользователя новые окна, нравится ему это или нет, ещё не причина того, чтобы в спецификации было TARGET="_BLANK".

Более того, ЯВНОЕ использование и значения тэгов необходимо поместить в центр спецификации, а может быть, даже в отдельное руководство по использованию для тех, кто по-прежнему живёт в 1997 году.

Создание более простой, чистой и полезной версии HTML, которая станет руководством для нас всех не такая уж сложная задача.

Кроме того, нам полезно будет, если при её создании меньший вес будут иметь разработчики браузеров. Microsoft, Mozilla, Apple и Google имеют огромное влияние на W3C и WhatWG, и это совершенно неэтично. Их вес в процессе принятия решений противоречит самой концепции свободного и открытого веба.



На правах рекламы


Эпичные серверы это VDS для размещения сайтов от маленького интернет-магазина на Opencart до серьёзных проектов с огромной аудиторией. Создавайте собственные конфигурации серверов в пару кликов!

Присоединяйтесь к нашему чату в Telegram.

Подробнее..

EasyUI действительно easy?

31.05.2021 12:16:05 | Автор: admin

В этой статье я хочу поделиться опытом избавления от жуткой головной боли, возникшей при разработке веб-приложения для одного маленького, но весьма могучего устройства. Но сначала несколько слов об источнике этой боли о дизайне.

Дизайн сегодня один из необходимых компонентов любого продукта, а для сайтов и веб-приложений это самая важная часть. Всё, что находится под капотом, скрыто от глаз клиента. Пользователя не интересует гениальность исполнения движка или уникальность архитектуры: подразумевается само собой, что программа должна работать надежно и безопасно. Современному пользователю необходим стильный графический интерфейс.

Раньше создание такого интерфейса вызывало серьёзную головную боль у программистов, но теперь для избавления от неё выпущено большое количество различных фреймворков и библиотек. Казалось бы ура, проблема решена! Однако, теперь перед нами встаёт другой вопрос: какой препарат выбрать пенталгин или панадол?

Вопрос нелёгкий, и решать, в итоге, вам. Я же расскажу о своём лекарстве: библиотеке EasyIU, предназначенной для создания полноценных одностраничных веб-приложений (SPA) и основанной на jQuery, Angular, Vue и React.

Моё знакомство с EasyUI началось около двух лет назад, когда наша команда приступила к разработке софта для системы управления питанием и его интеллектуального распределения между потребителями. Управляющее устройство имело на борту Linux и кроме распределения питания должно было обмениваться данными с различными периферийными устройствами, уметь контролировать их, а также принимать показания от большого количества (до нескольких сотен) датчиков. Правила управления могли изменяться, позволяя пользователю настроить работу всего комплекса для выполнения необходимых задач.

Настройка и мониторинг устройства могли вестись через различные протоколы: ssh, snmp, redfish, BACnet, но основным способом общения с ним был http, то есть всем комплексом можно было управлять через обыкновенный веб-браузер. Это широко используемое решение, и оно не сулило никаких проблем. Однако, дьявол всё же основательно порылся в деталях.

Веб-страница должна была отражать состав комплекса, его внутренние и внешние компоненты и их содержимое в виде дерева разнотипных объектов. Показания датчиков должны были выводиться в виде таблицы (как в Excel'е, безмятежно улыбался заказчик), причём часть данных (показания, состояния датчиков и т.п.) требовалось непрерывно обновлять, а часть могла изменяться пользователем непосредственно в таблице. Для настройки комплекса было необходимо использовать многоуровневое меню и большое количество модальных диалоговых окон.

Всё это выглядело достаточно сложно, тем более что веб-сервис был лишь тем самым капотом, под которым прятался движок, и который мы также должны были написать. Проекту был необходим полноценный графический интерфейс. Bootstrap в нашем случае требовал значительной настройки и обвески кодом, и мы решили поискать другие фреймворки. Существует большое количество библиотек, реализующих отдельные элементы графического интерфейса или их небольшие совокупности. Их использование также не было целесообразно, поскольку не обеспечивало для элементов интерфейса ни общего стилевого оформления, ни единообразных методов управления ими.

В итоге наших поисков, фреймворк EasyUI показался нам наиболее подходящим для решения наших задач. Несколько забегая вперёд, я могу сказать, что это был хороший выбор, несмотря на обнаруженные в ходе реализации проекта недостатки этой библиотеки.

Итак, что же такое такое EasyUI?

Как я уже упоминал выше, EasyIU представляет собой набор компонентов пользовательского интерфейса, основанных на jQuery, Angular, Vue и React. Мы использовали библиотеку, базирующуюся на jQuery.

С самого начала мне понравилась возможность создания макета приложения без программирования на javascript. EasyUI для jQuery имеет встроенный парсер, который расширяет HTML-разметку и ассоциирует её с библиотечным кодом. Для этого в классе HTML-элемента достаточно указать наименование компонента, который необходимо применить.

Например, эта разметка создаст на странице приложения пять зон: шапку и подвал высотой 100 пикселей, и разделённую на три колонки среднюю часть. Левая и правая колонки имеют ширину 100 пикселей, а центральная часть имеет серый фон и занимает всё оставшееся место. Кроме этого, высоту шапки и подвала, ширину левой и правой колонок можно изменять мышью во время работы приложения. Для этого EasyUI создаст на странице приложения специальные разделители.

<body class="easyui-layout">  <div data-options="region:'north',title:'North Title',split:true"       style="height:100px;"></div>  <div data-options="region:'south',title:'South Title',split:true"       style="height:100px;"></div>  <div data-options="region:'east',title:'East',split:true"       style="width:100px;"></div>  <div data-options="region:'west',title:'West',split:true"       style="width:100px;"></div>  <div data-options="region:'center',title:'center title'"       style="padding:5px;background:#eee;"></div></body>

Конечно, EasyUI позволяет сделать то же самое при помощи javascript:

$('body').layout({fit: true}).layout('add', {  region: 'north', title: 'North Title', split: true, height: 100}).layout('add', {  region: 'south', title: 'South Title', split: true, height: 100}).layout('add', {  region: 'east', title: 'East Title', split: true, width: 100}).layout('add', {  region: 'west', title: 'West Title', split: true, width: 100}).layout('add', {  region: 'center', title: 'сenter Title', split: true, widht:100,  style: {padding: 5, background: '#eee'}});

В результате EasyUI создаст вот такую страницу:

Пока всё easy, не так ли? Мы можем создать предварительный макет без написания javascript кода, что очень удобно на начальных этапах проектирования приложения.

А что ещё она умеет?

Для беглой оценки возможностей EasyUI, достаточно посмотреть на её конструктор тем:

Здесь показаны не все возможности EasyUI, но для первого впечатления вполне достаточно и этого: разметка (layout), панели (panel), многоуровневое меню (menu, menubutton), вкладки (tab), аккордеоны (accordion), календарь (calendar), таблица (datagrid), набор конфигурационных параметров (propertygrid), список (datalist), дерево (tree), диалоги (dialog), формы (form) и их элементы (validatebox, textbox, passwordbox, maskedbox, combobox, tagbox, numberbox, datetimebox, spinner, slider, filebox, checkbox, radiobutton) и этот перечень далеко не полон. При более глубоком погружении в возможности библиотеки выясняется, что эти компоненты можно расширять и создавать на их основе новые. На сайте проекта есть раздел Extention, на котором представлены некоторые расширения, например, всем известная лента (Ribbon):

Для демонстрации всех компонентов, реализованных EasyUI, на странице проекта есть специальный раздел с демонстрацией их работы.

И снова о дизайне

EasyUI поддерживает изменение стиля оформления пользователем из набора готовых тем прямо во время выполнения приложения. На сайте проекта предлагается собственная коллекция стилей. К сожалению, решение из такого набора не всегда может удовлетворить заказчика. Это, скорее, набор стилей для начала работы, который впоследствии потребует корректировки. Для этого на сайте проекта имеется конструктор тем. Разумеется, всегда можно настроить тему приложения в соответствующей таблице стилей, которые находятся в каталоге themes проекта. Для нашего проекта поддержка возможности изменения темы приложения не требовалась, однако, таблицы стилей были существенно переработаны, чтобы UI соответствовал корпоративному стилю заказчика.

Создание диалога при помощи EasyUI

В качестве примера использования библиотеки в проекте я хочу привести код (под катом) для создания диалога настроек HTTP. Параметром функции открытия диалога является иконка, назначенная тому пункту меню, из которого вызывается диалог.

Код для создания диалога настроек HTTP
(function($) {   $.fn.httpConfDlg = function(icon) {     var title = _("HTTP Configuration"), me;     var succ = _(       "HTTP properties have been changed. " +       "You need to re-connect your browser " +       "according to the new properties."     );     var errcode = "System returned error code %1."     var errset = _(       "Can't set HTTP configuration. " + errcode     );     var errget = _(       "Can't get HTTP configuration. " + errcode     );     var allowed = $.SMR_PRIVILEGE.CHECK(       $.SMR_PRIVILEGE.CHANGE_NETWORK_CONFIGURATION     );     var buttons = [];     if (allowed) {       buttons.push({         okButton: true,         handler: function() {           var ho = $(this.parentElement).api({             fn: $.WAPI.FN_SET_HTTP_PROPERTIES,             param: {               httpPort: parseInt($('#httpPort').textbox('getValue')),               httpsPort: parseInt($('#httpsPort').textbox('getValue')),               forceHttps: $.HpiBool($('#forceHttp')[0].checked)             },             before: function() {               $('body').css('cursor', 'wait');             },             done: function() {               $('body').css('cursor', 'default');               me.dialog('close');             },             error: function(err) {               if (err.RC == $.WAPI.RC_BAD_RESPONSE) {                 $.messager.alert(                   title,                   $.fstr(errset, err.IC),                   'error'                 );                 return false;               } else if (err.RC == 1003) {                 ho.api('drop');                 $.messager.alert(title, succ, 'info', function() {                   $('#sinfo').session('logout');                 });                 return false;               }               return true;             }           });         }       });     }     buttons.push({cancelButton: true});     return this.each(function() {       document.body.appendChild(this);       me = $(this).append(         '<div id="httpSetting" style="padding: 10px 30px">' +         $.fitem('httpPort', _("HTTP port")) +         $.fitem('httpsPort', _("HTTPS port")) +         $.fcheck('forceHttp', _("Force HTTPS for Web Access")) +         '</div>'       );       $('#httpPort').textbox({         type: 'text', width: 60, disabled: !allowed       });       $('#httpsPort').textbox({         type: 'text', width: 60, disabled: !allowed       });       if (!allowed) $('#forceHttp').attr('disabled', 'disabled');         me.mdialog({           title: title,           iconCls: icon,           width: 320,           height: 180,           modal: true,           buttons: buttons,           onOpen: function() {             var ho = $(this).api({               fn: $.WAPI.FN_GET_HTTP_PROPERTIES,               receive: function(res) {                 $('#httpPort').textbox('setValue', res.httpPort);                 $('#httpsPort').textbox('setValue', res.httpsPort);                 if (res.forceHttps == 1) {                   $('#forceHttp').attr('checked', 'checked')                 } else {                   $('#forceHttp').removeAttr('checked')}               },               error: function(err) {                 if (err.RC == $.WAPI.RC_BAD_RESPONSE) {                   $.messager.alert(                     _("HTTP"),                     $.fstr(                       errget,                       err.IC                     ),                   'error'                 );                 me.dialog('close');                 return false;               }               me.dialog('close');               return true;             }           });         }       });     });   }; })(jQuery); 

Поскольку компоненты EasyUI реализованы в виде коллекций jQuery (в нашем случае это $('div').httpConfDlg(http_icon)), инициализация диалога производится через метод this.each().

В начале активируются кнопки диалога: OK и Cancel. Это можно сделать непосредственно при инициализации диалога, но кнопка OK создается только для обеспечения привилегированного доступа. Таким образом, для пользователя, не имеющего достаточных прав для изменения параметров HTTP протокола, диалог будет отображать только кнопку Cancel (Конечно, EasyUI допускает установку и снятие запрета нажатия на кнопки во время инициализации диалога, а также во время его работы кнопка при запрете использования изменяет стиль и не реагирует на нажатия. Однако, для сохранения общего стиля, неиспользуемые кнопки в диалогах нами не отображаются). Обработчик кнопки Cancel по умолчанию закрывает окно диалога без дополнительных действий. У кнопки OK есть обработчик, который выполняет AJAX-запрос. В качестве параметра запросу передаётся JSON структура, содержащая номер функции для бэкенда, набор параметров для самой функции и обработчики результатов выполнения (callback).

Затем родительский элемент, переданный через параметр this, заполняется контентом: двумя полями для указания номеров портов и одного флажка, устанавливающего принудительное использование защищённого протокола. Далее поля активируются как EasyUI textbox компоненты. Если пользователь не имеет привилегий для их изменения, текстовые поля и флажок будут недоступны для изменения.

И наконец, производится активация самого диалога: устанавливаются его размеры, заголовок, иконка, модальный режим, активируются кнопки диалога и их обработчики (указанные явно или по умолчанию). После открытия диалога запускается функция, выполняющая AJAX запрос для получения текущих параметров HTTP. Если при выполнении запроса происходит ошибка, генерируется сообщение об ошибке и диалог закрывается. Если запрос выполнен успешно, текстовые поля и флажок устанавливаются в соответствии с полученными результатами запроса.

При нажатии на кнопку OK вызывается функция-обработчик, которая считывает текущие значения текстовых полей и состояние флажка, формирует соответствующий AJAX-запрос и выполняет его. При любом результате выполнения этого запроса производится закрытие окна диалога (параметр done). В случае возникновения ошибки, в зависимости от её типа, выдаётся сообщение об ошибке. В нашем случае, даже при успешном выполнении запроса происходит ошибка, поскольку изменение настроек протокола приводит к разрыву соединения. Для его восстановления производится закрытие сеанса и вызов процедуры новой регистрации.

Несколько, пояснений к коду.

  • Вызов $.fitem('httpPort', _("HTTP port")) создаёт набор связанных HTML элементов, реализующих типовое для нашего приложения поле ввода с идентификатором httpPort и меткой (label) HTTP port. Функция _() обеспечивает использование языка, указанного пользователем в настройках. Последующий вызов компонента EasyUI $('#httpPort').textbox({type: 'text', width: 60, disabled: !allowed}); регистрирует поле ввода как EasyUI textbox. Вызов $('#httpPort').textbox('setValue', res.httpPort); устанавливает значение для текстового поля в соответствие результату AJAX запроса. И наконец, parseInt($('#httpPort').textbox('getValue')) в обработчике OK-кнопки возвращает текущее значение текстового поля.

  • Компонент mdialog() является нашим собственным расширением от базового компонента EasyUI dialog() для автоматического закрытия диалога при наступлении определённых событий, а также для создания типовых кнопок с обработкой нажатия по умолчанию. В данном случае это кнопка Cancel, которая создаётся короткой инструкцией buttons.push({cancelButton: true});

  • Функция $.messager вызывает окно предупреждения, которое также является компонентом EasyUI, производным от компонента Dialog.

В итоге диалог выглядит так:

EasyUI диалог для настройки HTTPEasyUI диалог для настройки HTTP

Ложка дёгтя

Как видно из приведенного выше примера, для создания диалога требуется довольно много кода. Большое количество диалогов и их компонентов (например, выпадающих списков с одинаковым содержимым) ощутимо раздуло наш проект однообразными велосипедными конструкциями.

Часть их удалось сократить с помощью создания собственных расширений, благо EasyUI позволяет сделать это, но всё-таки код во многих местах до сих пор кажется мне избыточным. И это, пожалуй, самый серьёзный недостаток EasyUI, который на мой взгляд, с лихвой компенсируется надёжностью библиотеки и простотой её использования.

И всё-таки, почему EasyUI?

Работа с большими массивами данных, представленными в виде таблиц и деревьев это та фишка, которая определила выбор EasyUI.

Для нас критически важно было отображать большой и постоянно обновляемый набор данных как в виде иерархической структуры, так и в виде таблицы. И EasyUI предоставила нам такую возможность. Для этого в составе библиотеки есть специальные компоненты: tree и datagrid.

EasyUI tree отображает иерархические данные в виде древовидной структуры. Узлы дерева можно наполнять различной информацией и извлекать её по событиям, разворачивать, сворачивать, перетаскивать, изменять стиль оформления по содержимому или другим условиям.

Компонент datagrid отображает данные в табличном формате и предлагает богатую поддержку для выбора, сортировки и группировки данных. Слияние ячеек, многоколоночные заголовки, замороженные столбцы и нижние колонтитулы вот лишь некоторые из его особенностей. Кроме этого, для datagrid есть специальные расширения: datagrid-scrollview, которое манипулирует полным набором данных, сохраняя в DOM-е лишь отображаемую их часть (а это существенно повышает скорость работы приложения), и datagrid-filter позволяющее накладывать фильтры на используемый набор данных.

И tree, и datagrid поддерживают асинхронную загрузку и редактирование данных непосредственно по месту положения элемента, имеют динамически настраиваемое оформление и свободно подключаемые иконки для элементов компонента, а также возможность отображения данных в виде чекбоксов.

Именно сочетание всех этих возможностей позволило нашей команде реализовать сложный интерфейс, полностью удовлетворяющий заказчика, не отвлекаясь на построение сложных DOM-конструкций и разработку CSS с нуля.

В завершение хочу ещё раз сказать, что библиотека EasyUI обеспечивает все потребности пользовательского интерфейса, оставаясь при этом лёгкой в использовании. Я думаю, эта библиотека может быть интересна разработчику веб-приложений, ориентированных на управление различными устройствами. В этой нише её использование, на мой взгляд, может быть предпочтительнее Bootstrap-а. По крайней мере, это хорошая альтернатива панадолу.

Подробнее..

Перевод Переход к Meta GSAP поиски идеальной бесконечной прокрутки

12.05.2021 18:04:50 | Автор: admin

Уже послезавтра, 14 мая, стартует новый поток курса Python для веб-разработки, поэтому мы решили поделиться переводом о не совсем очевидной, но интересной области разработки сайтов анимации анимации. Автор не просто даёт готовый рецепт, но шаг за шагом показывает, как сделать анимацию прокрутки плавной и приятной. Эта статья больше о концепции, которая поможет вам по-другому взглянуть на вашу анимацию. Так случилось, что этот конкретный пример демонстрирует бесконечную прокрутку, в частности, идеальную бесконечную прокрутку колоды карт без дублирования какой-то из них.


Зачем я здесь? Ну, всё началось с твита, заставившего меня задуматься о разметке и боковой прокрутке контента.

Я взял эту концепцию и использовал её на своем сайте. На момент написания статьи она всё ещё актуальна.

Затем я задумался над тем, какие бывают галереи и какие концепции боковой прокрутки существуют. Мы включили прямую трансляцию и решили попробовать сделать что-то вроде старого шаблона Apple Cover Flow. Помните его?

Первое, о чём я подумал, мне нужно сделать так, чтобы не был задействован JavaScript, как это делается в демоверсии выше, и чтобы я смог использовать прогрессивное улучшение". Я схватил Greensock и ScrollTrigger, и дело пошло.

Эта работа привела меня к разочарованию. Я что-то сделал, но я не смог заставить бесконечную прокрутку работать так, как я хотел. Кнопки Далее и Назад не хотели работать вместе. Вы можете увидеть результат ниже, и в моей реализации используется горизонтальная прокрутка.

Итак, я открыл новую тему на форуме Гринсока. Я и не подозревал, что вот-вот открою себя для серьёзного обучения! Мы решили проблему с кнопками. Но, оставаясь верным себе, я должен был спросить, можно ли как-то ещё улучшить моё решение. Был ли чистый способ сделать бесконечную прокрутку? Я пробовал что-то на стриме, но безуспешно. Мне было любопытно. Я пробовал технику, которую написал для релиза ScrollTrigger, в песочнице ниже.

Первый ответ на форкме был о том, что сделать это довольно сложно:

Сложность бесконечной прокрутки в том, что полоса прокрутки ограничена, а желаемый эффект нет. Таким образом, вам нужно либо зациклить позицию прокрутки, как в разделе демонстраций ScrollTrigger, либо напрямую подключиться к связанным с прокруткой событиям навигации (например к событию колёсика мыши) вместо использования фактической позиции прокрутки.

Я подумал, что это действительно так, и был рад оставить всё как есть. Прошло два дня, и Джек написал ответ, который поразил меня, когда я начал копаться в нём. И теперь, после того, как я нашёл решение, я здесь, чтобы поделиться с вами методом из ответа.

Анимируйте что угодно

Одна вещь, которую часто упускают из виду с GSAP, это то, что с её помощью можно анимировать практически всё. Часто этот факт упускается потому, что при размышлении об анимации на ум приходят визуальные эффекты реальное физическое движение чего-либо. Наша первая мысль не о том, чтобы вывести этот процесс на метауровень и анимировать с шага назад.

Подумайте об анимации в более крупном масштабе, а затем разбейте её на слои. Например, вы проигрываете мультик. Мультик представляет собой сборник композиций. Каждая композиция это сцена. У вас есть возможность просматривать эту коллекцию композиций с помощью пульта дистанционного управления, будь он на YouTube или будь он вашим пультом от телевизора и т. д. В происходящем есть почти три уровня.

И в этом состоит трюк, который нам нужен для создания различных типов бесконечных циклов. Это основной принцип. Мы анимируем положение заголовка воспроизведения на временной шкале при помощи временной шкалы. И затем мы можем очистить эту временную шкалу, устанавливая позицию прокрутки; ничего страшного, если это звучит запутанно. Мы разберёмся.

Переход к "мета"

Начнём с примера. Мы собираемся создать анимацию движения, которая перемещает некоторые поля слева направо. Вот она:

Десять контейнеров, которые перемещаются слева направо. С Greensock это довольно просто. Здесь мы используем fromTo и repeat для анимации движения. Но у нас есть пробел в начале каждой итерации. Мы также используем stagger, чтобы выделить движение, и это сыграет важную роль в дальнейшем.

gsap.fromTo('.box', {  xPercent: 100}, {  xPercent: -200,  stagger: 0.5,  duration: 1,  repeat: -1,  ease: 'none',})

Теперь самое интересное. Давайте приостановим анимацию движения и назначим её переменной. Затем создадим анимацию движения, которая будет воспроизводить это. Это делается увеличением totalTime, что позволяет нам получить или установить промежуточную анимацию воспроизведения, учитывая при этом повторы и задержки повтора.

const SHIFT = gsap.fromTo('.box', {  xPercent: 100}, {  paused: true,  xPercent: -200,  stagger: 0.5,  duration: 1,  repeat: -1,  ease: 'none',})const DURATION = SHIFT.duration()gsap.to(SHIFT, {  totalTime: DURATION,  repeat: -1,  duration: DURATION,  ease: 'none',})

Это наша первая мета-анимации движения. Выглядит точно так же, но мы добавили новый уровень контроля. Мы можем изменить что-либо на этом слое, не затрагивая исходный слой. Например, мы могли бы изменить анимации ease на power4.in. Это полностью меняет анимацию, но не влияет на её основу. Мы как будто защищаем себя с помощью резервного варианта.

Мало того, мы можем выбрать повторение только определённой части временной шкалы. Мы могли бы сделать это с другим fromTo, например:

Код для этого 'эффекта будет примерно таким:

gsap.fromTo(SHIFT, {  totalTime: 2,}, {  totalTime: DURATION - 1,  repeat: -1,  duration: DURATION,  ease: 'none'})

Вы видите, к чему всё идёт? Посмотрите на эту анимацию движения. Хотя цикл повторяется, числа меняются при каждом повторении. Но контейнеры находятся в правильном положении.

Достижение идеального цикла

Если мы вернёмся к нашему исходному примеру, между каждыми повторениями будет заметный промежуток.

Вот и вся хитрость. Здесь ключ к проблеме. Нам нужно сделать идеальный цикл.

Начнём с того, что повторим шаг трижды. Это равносильно использованию repeat: 3. Обратите внимание, что мы удалили repeat: -1 из анимации движения.

const getShift = () => gsap.fromTo('.box', {  xPercent: 100}, {  xPercent: -200,  stagger: 0.5,  duration: 1,  ease: 'none',})const LOOP = gsap.timeline()  .add(getShift())  .add(getShift())  .add(getShift())

Мы превратили начальную анимацию движения в функцию, которая возвращает анимацию движения, и трижды добавляли её на новую временную шкалу. И это дало нам следующее.

Хорошо. Но пробел всё же есть. Теперь мы можем ввести параметр позиции для добавления и позиционирования этих анимаций. Хочется, чтобы всё было гладко. Это означает вставку каждого набора промежуточных кадров до окончания предыдущего. Это значение зависит от stagger и количества элементов.

const stagger = 0.5 // Used in our shifting tweenconst BOXES = gsap.utils.toArray('.box')const LOOP = gsap.timeline({  repeat: -1})  .add(getShift(), 0)  .add(getShift(), BOXES.length * stagger)  .add(getShift(), BOXES.length * stagger * 2)

Если мы обновим нашу временную шкалу, чтобы она повторялась, и понаблюдаем за ней (при регулировке stagger, чтобы увидеть, как это влияет на ситуацию)

Вы заметите, что посередине есть окно, которое создаёт бесшовный цикл. Вспомните те навыки, которые мы применили ранее, когда мы манипулировали временем? Вот что нам нужно сделать здесь зациклить окно времени, в котором цикл является бесшовным.

Мы могли бы попробовать изменить totalTime через это окно цикла.

const LOOP = gsap.timeline({  paused: true,  repeat: -1,}).add(getShift(), 0).add(getShift(), BOXES.length * stagger).add(getShift(), BOXES.length * stagger * 2)gsap.fromTo(LOOP, {  totalTime: 4.75,},{  totalTime: '+=5',  duration: 10,  ease: 'none',  repeat: -1,})

Здесь мы ставим totalTime анимации движения от 4,75 и добавляем к нему длину цикла. Длина цикла равна 5. И это среднее окно временной шкалы. Для этого мы можем использовать изящный оператор из GSAP +=, который даёт нам следующее:

Найдите минутку, чтобы понять, как это работает. Это, может быть, самая сложная часть, которую нужно осмыслить. Мы вычисляем временные окна на нашей шкале времени. Такое сложно визуализировать, но я попробовал.

Вот демонстрация часов, в которых стрелки повернутся один раз за 12 секунд. Они зацикливаются бесконечно с помощью repeat: -1, а затем мы используем fromTo для анимации определённого временного окна с заданной продолжительностью. Если вы уменьшите временное окно, скажем, на 2 и 6, а затем измените продолжительность на 1, стрелки переместятся с 2 часов на 6 часов при повторении. Но мы никак не тронули базовую анимацию.

Попробуйте поиграть со значениями, чтобы увидеть, как она влияет на объекты.

На этом этапе было бы неплохо составить формулу позиции нашего окна. Мы также могли бы использовать переменную для продолжительности перехода каждого окна.

const DURATION = 1const CYCLE_DURATION = BOXES.length * STAGGERconst START_TIME = CYCLE_DURATION + (DURATION * 0.5)const END_TIME = START_TIME + CYCLE_DURATION

Вместо использования трех составных таймлайнов мы могли бы трижды перебирать наши элементы, при этом нам не нужно вычислять позиции. Визуализация этого в виде трёх составных временных шкал отличный способ разобраться в концепции и хороший способ, чтобы помочь понять основную идею.

Давайте изменим нашу реализацию, чтобы с самого начала создать одну большую временную шкалу.

const STAGGER = 0.5const BOXES = gsap.utils.toArray('.box')const LOOP = gsap.timeline({  paused: true,  repeat: -1,})const SHIFTS = [...BOXES, ...BOXES, ...BOXES]SHIFTS.forEach((BOX, index) => {  LOOP.fromTo(BOX, {    xPercent: 100  }, {    xPercent: -200,    duration: 1,    ease: 'none',  }, index * STAGGER)})

Такое проще собрать, а результат одно и то же окно. Но нам не нужно думать о математике. Теперь мы перебираем три набора контейнеров и располагаем каждую анимацию в соответствии с шагом.

Как такое может выглядеть, если мы отрегулируем смещение? Это сожмёт контейнеры ближе друг к другу.

Но это ломает окно, потому что нет totalTime. Окно нужно перерассчитать. Сейчас хороший момент, чтобы применить вычисленную ранее формулу.

const DURATION = 1const CYCLE_DURATION = STAGGER * BOXES.lengthconst START_TIME = CYCLE_DURATION + (DURATION * 0.5)const END_TIME = START_TIME + CYCLE_DURATIONgsap.fromTo(LOOP, {  totalTime: START_TIME,},{  totalTime: END_TIME,  duration: 10,  ease: 'none',  repeat: -1,})

Починили!

Мы могли бы даже ввести смещение, если бы захотели изменить начальную позицию.

const STAGGER = 0.5const OFFSET = 5 * STAGGERconst START_TIME = (CYCLE_DURATION + (STAGGER * 0.5)) + OFFSET

Теперь наше окно начинается с другой позиции.

Но всё же это не очень хорошо, так как даёт нам эти неудобные стопки на каждом конце. Чтобы избавиться от этого эффекта, нужно подумать о физическом окне для наших контейнеров. Или о том, как они появляются и исчезают с экрана.

Мы воспользуемся document.body в качестве окна для нашего примера. Давайте обновим анимацию движения контейнеров, чтобы они были отдельными шкалами времени, где блоки увеличиваются при появлении и уменьшаются при исчезновении. Мы можем использовать yoyo и repeat: 1, чтобы добиться появления и исчезновения.

SHIFTS.forEach((BOX, index) => {  const BOX_TL = gsap    .timeline()    .fromTo(      BOX,      {        xPercent: 100,      },      {        xPercent: -200,        duration: 1,        ease: 'none',      }, 0    )    .fromTo(      BOX,      {        scale: 0,      },      {        scale: 1,        repeat: 1,        yoyo: true,        ease: 'none',        duration: 0.5,      },      0    )  LOOP.add(BOX_TL, index * STAGGER)})

Почему мы используем временную шкалу длительностью в 1? Так проще отслеживать её. Мы знаем, что время равняется 0,5, когда контейнер находится посередине.

Стоит отметить, что ease не будет иметь того эффекта, о котором мы обычно думаем. Фактически ease будет играть роль в том, как располагаются поля. Например, при перемещении контейнеры справа сбиваются в кучу, прежде чем они переместятся. Код выше даёт этот эффект.

Почти готово, но наши контейнеры на время исчезают посередине. Чтобы исправить это, давайте введём свойство immediateRender. Оно действует как animation-fill-mode: none в CSS. Мы сообщаем GSAP, что не хотим сохранять или предварительно записывать какие-либо установленные для контейнера стили.

SHIFTS.forEach((BOX, index) => {  const BOX_TL = gsap    .timeline()    .fromTo(      BOX,      {        xPercent: 100,      },      {        xPercent: -200,        duration: 1,        ease: 'none',        immediateRender: false,      }, 0    )    .fromTo(      BOX,      {        scale: 0,      },      {        scale: 1,        repeat: 1,        zIndex: BOXES.length + 1,        yoyo: true,        ease: 'none',        duration: 0.5,        immediateRender: false,      },      0    )  LOOP.add(BOX_TL, index * STAGGER)})

Это небольшое изменение решает наши проблемы! Обратите внимание, что мы начали прописывать z-index: BOXES.length. Эта строка должна защитить нас от любых проблем с z-index.

Вот оно! Наш первый бесконечный бесшовный цикл. Никаких повторяющихся элементов. Мы изменяем время!

Если хочется увидеть больше контейнеров одновременно, мы можем повозиться со временем, stagger и ease. Здесь у нас stagger 0,2, а также мы добавили opacity.

Ключевой момент: мы можем использовать repeatDelay, чтобы переход opacity выполнялся быстрее, чем масштаб. Затухание более 0,25 секунды. Ожидание 0,5 секунды. Исчезание через 0,25 секунды.

.fromTo(  BOX, {    opacity: 0,  }, {    opacity: 1,    duration: 0.25,    repeat: 1,    repeatDelay: 0.5,    immediateRender: false,    ease: 'none',    yoyo: true,  }, 0)

Круто! Мы можем делать всё, что захотим, с появлением и исчезновением контейнеров. Главное здесь у нас есть окно времени, которое даёт нам бесконечный цикл.

Подключение для скроллинга

Теперь, когда у нас есть бесшовный цикл, давайте используем его для скроллинга. Для этого мы можем задействовать ScrollTrigger из GSAP. Это потребует дополнительной анимации движения, чтобы очистить наше окно цикла. Обратите внимание на то, как теперь мы реализовали приостановку цикла.

const LOOP_HEAD = gsap.fromTo(LOOP, {  totalTime: START_TIME,},{  totalTime: END_TIME,  duration: 10,  ease: 'none',  repeat: -1,  paused: true,})const SCRUB = gsap.to(LOOP_HEAD, {  totalTime: 0,  paused: true,  duration: 1,  ease: 'none',})

Уловка здесь состоит в том, чтобы использовать ScrollTrigger для очистки головной части воспроизведения цикла, обновляя totalTime из SCRUB. Есть несколько способов настроить такой скролл.

Мы могли расположить его горизонтально или привязать к контейнеру. Но мы собираемся обернуть наши поля в элемент .boxes и закрепить его в области просмотра. (Это фиксирует его положение во вьюпорте.) Мы также будем придерживаться вертикальной прокрутки. Посмотрите пример, чтобы увидеть стили для .boxes, которые устанавливают размер окна просмотра.

import ScrollTrigger from 'https://cdn.skypack.dev/gsap/ScrollTrigger'gsap.registerPlugin(ScrollTrigger)ScrollTrigger.create({  start: 0,  end: '+=2000',  horizontal: false,  pin: '.boxes',  onUpdate: self => {    SCRUB.vars.totalTime = LOOP_HEAD.duration() * self.progress    SCRUB.invalidate().restart()  }})

Важная часть находится внутри onUpdate. Здесь мы устанавливаем totalTime анимации движения в зависимости от прогресса прокрутки. Вызов invalidate сбрасывает все внутренние записанные позиции для SCRUB. Затем перезапуск устанавливает позицию на новое значение totalTime, которое мы установили.

Мы можем перемещаться вперёд и назад по временной шкале и обновлять позицию.

Разве это не впечатляет? Мы можем покрутить, чтобы прокрутить временную шкалу, которая очищает временную шкалу окно временной шкалы. Уделите секунду, чтобы переварить: именно это здесь и происходит.

Путешествие во времени для бесконечной прокрутки

До сих пор мы манипулировали временем. А теперь отправимся в путешествие во времени! Для этого мы собираемся использовать некоторые другие утилиты GSAP, и мы больше не будем очищать totalTime LOOP_HEAD, вместо этого обновив его через прокси. Это ещё один отличный пример перехода на мета-GSAP. Начнём с прокси-объекта, отмечающего положение точки воспроизведения.

const PLAYHEAD = { position: 0 }

Теперь мы можем обновить SCRUB, чтобы обновить position. В то же время мы можем использовать утилиту GSAP wrap, которая заворачивает значение position в продолжительность LOOP_HEAD. Например, если длительность равна 10 и мы предоставим значение 11, то вернёмся к 1.

const POSITION_WRAP = gsap.utils.wrap(0, LOOP_HEAD.duration())const SCRUB = gsap.to(PLAYHEAD, {  position: 0,  onUpdate: () => {    LOOP_HEAD.totalTime(POSITION_WRAP(PLAYHEAD.position))  },  paused: true,  duration: 1,  ease: 'none',})

И последнее, но не менее важное: нам нужно пересмотреть ScrollTrigger, чтобы он обновлял правильную переменную в SCRUB position, а не totalTime.

ScrollTrigger.create({  start: 0,  end: '+=2000',  horizontal: false,  pin: '.boxes',  onUpdate: self => {    SCRUB.vars.position = LOOP_HEAD.duration() * self.progress    SCRUB.invalidate().restart()  }})

На данный момент мы перешли на прокси и не увидим никаких изменений.

Нам нужен бесконечный цикл при прокрутке. Наша первая мысль может заключаться в том, чтобы прокрутить до начала, когда мы завершим прокрутку. И он сделает именно это прокрутит назад. Хотя это именно то, чего мы хотим, мы не хотим, чтобы ползунок перемещался в обратном направлении. Вот тут-то и приходит на помощь totalTime. Помните? Он получает или устанавливает положение точки воспроизведения в соответствии с totalDuration, которая включает любые повторы и задержки повтора.

Например, предположим, что продолжительность заголовка цикла была 5 и мы дошли до этого значения, мы не будем очищать его до 0. Вместо этого продолжим очистку головной части цикла до 10. Если мы продолжим, он перейдёт к 15 и так далее. Между тем мы будем отслеживать переменную iteration, потому что она сообщает нам, где мы находимся в scrub. Мы также позаботимся о том, чтобы обновлять итерацию только при достижении пороговых значений выполнения. Начнём с переменной iteration:

let iteration = 0

Теперь давайте обновим нашу реализацию ScrollTrigger:

const TRIGGER = ScrollTrigger.create({  start: 0,  end: '+=2000',  horizontal: false,  pin: '.boxes',  onUpdate: self => {    const SCROLL = self.scroll()    if (SCROLL > self.end - 1) {      // Go forwards in time      WRAP(1, 1)    } else if (SCROLL < 1 && self.direction <; 0) {      // Go backwards in time      WRAP(-1, self.end - 1)    } else {      SCRUB.vars.position = (iteration + self.progress) * LOOP_HEAD.duration()      SCRUB.invalidate().restart()     }  }})

Обратите внимание, как мы теперь учитываем итерацию при расчёте position. Помните, что это оборачивается скраббером. Мы также определяем, когда достигаем пределов прокрутки, и там точка для WRAP.

Функция ниже устанавливает соответствующее значение iteration и устанавливает новую позицию прокрутки.

const WRAP = (iterationDelta, scrollTo) => {  iteration += iterationDelta  TRIGGER.scroll(scrollTo)  TRIGGER.update()}

У нас бесконечная прокрутка! Если у вас есть одна из этих причудливых мышек с колёсиком прокрутки, которую вы можете отпустить, чтобы оно крутилось само, попробуйте! Это весело!

Вот демонстрация, которая отображает текущую итерацию и прогресс:

Привязка прокрутки

При работе с такой функцией всегда есть что-то хорошее. Начнём с привязки к прокрутке. GSAP упрощает это, поскольку мы можем использовать gsap.utils.snap без каких-либо других зависимостей. Это даёт привязку к моментам, где мы указали точки. Объявляем шаг от от 0 до 1 ч десятью полями, то есть подойдёт Snap 0,1.

const SNAP = gsap.utils.snap(1 / BOXES.length)

SNAP возвращает функцию, которую мы можем использовать для привязки нашего значения position.

Мы хотим сделать привязку только после того, как прокрутка закончилась. Для этого мы можем использовать прослушиватель событий на ScrollTrigger. Когда прокрутка закончится, мы перейдём к определённому значению position.

ScrollTrigger.addEventListener('scrollEnd', () => {  scrollToPosition(SCRUB.vars.position)})

А вот scrollToPosition:

const scrollToPosition = position => {  const SNAP_POS = SNAP(position)  const PROGRESS =    (SNAP_POS - LOOP_HEAD.duration() * iteration) / LOOP_HEAD.duration()  const SCROLL = progressToScroll(PROGRESS)  TRIGGER.scroll(SCROLL)}

Что мы тут делаем?

  1. Расчёт момента времени для привязки

  2. Расчёт текущего прогресса. Допустим, LOOP_HEAD.duration() равно 1 и мы установили 2,5. Это даёт нам прогресс 0,5, в результате чего iteration равна 2, где 2,5 - 1 * 2/1 === 0,5. Мы рассчитываем прогресс так, чтобы он всегда был между 1 и 0.

  3. Расчёт конечной точки прокрутки. Эту часть дистанции может преодолеть ScrollTrigger. В примере мы установили расстояние 2000, и нам нужна его часть. Напишем новую функцию progressToScroll для её расчета.

const progressToScroll = progress =>  gsap.utils.clamp(1, TRIGGER.end - 1, gsap.utils.wrap(0, 1, progress) * TRIGGER.end)

Эта функция принимает значение прогресса и сопоставляет его с наибольшим расстоянием прокрутки. Но мы используем ограничение, чтобы гарантировать, что значение никогда не может быть 0 или 2000. Это важно. Мы защищаемся от привязки к этим значениям, так как это может поставить нас в бесконечный цикл.

Есть кое-что, что нужно сделать. Посмотрите эту демонстрацию, которая показывает обновлённые значения для каждой привязки.

Почему всё намного шустрее? Изменены продолжительность и сглаживание очистки. Меньшая продолжительность и более резкое сглаживание дают нам привязку.

const SCRUB = gsap.to(PLAYHEAD, {  position: 0,  onUpdate: () => {    LOOP_HEAD.totalTime(POSITION_WRAP(PLAYHEAD.position))  },  paused: true,  duration: 0.25,  ease: 'power3',})

Но если вы поиграли с этой демоверсией, вы заметите проблему. Иногда, когда мы оборачиваемся внутри оснастки, ползунок прыгает. Мы должны учитывать это, проверяя, что мы оборачиваем, когда щёлкаем, но только тогда, когда это необходимо.

const scrollToPosition = position => {  const SNAP_POS = SNAP(position)  const PROGRESS =    (SNAP_POS - LOOP_HEAD.duration() * iteration) / LOOP_HEAD.duration()  const SCROLL = progressToScroll(PROGRESS)  if (PROGRESS >= 1 || PROGRESS < 0) return WRAP(Math.floor(PROGRESS), SCROLL)  TRIGGER.scroll(SCROLL)}

И теперь у нас есть бесконечный скролл с привязкой!

Что дальше?

Мы создали основу для создания надёжного бесконечного скролла. Можно воспользоваться ею, чтобы добавить элементы управления или функциональность клавиатуры. Например, таким образом можно связать кнопки Далее и Назад и элементы управления с клавиатуры. Всё, что нам нужно делать, это управлять временем, верно?

const NEXT = () => scrollToPosition(SCRUB.vars.position - (1 / BOXES.length))const PREV = () => scrollToPosition(SCRUB.vars.position + (1 / BOXES.length))// Left and Right arrow plus A and Ddocument.addEventListener('keydown', event => {  if (event.keyCode === 37 || event.keyCode === 65) NEXT()  if (event.keyCode === 39 || event.keyCode === 68) PREV()})document.querySelector('.next').addEventListener('click', NEXT)document.querySelector('.prev').addEventListener('click', PREV)

Код может дать нам что-то вроде этого.

Мы можем использовать нашу функцию scrollToPosition и увеличивать значение по мере необходимости.

Вот оно!

Видите это? GSAP может анимировать не только элементы! Здесь мы изгибали время и управляли им, чтобы создать почти идеальный бесконечный слайдер. Никаких повторяющихся элементов, никакого беспорядка и хорошая гибкость. Подведём итоги. В этой статье мы рассмотрели, как:

  • Анимировать анимацию.

  • Манипулируя временем, рассматривать его как на инструмент позиционирования.

  • Использовать ScrollTrigger для прокрутки анимации через прокси.

  • Использовать некоторые замечательные утилиты GSAP для обработки логики за нас.

Теперь вы можете управлять временем!Эта концепция перехода на мета GSAP открывает множество возможностей. Что еще можно было оживить? Аудио? Видео? Что касается демо Cover Flow, то вот к чему мы пришли!

Если вы хотите научиться работать с JavaScript и стеком веб-технологий в целом, а после превзойти автора этой статьи, обратите внимание на особенный, авторский курс Frontend-разработчик, созданный опытными разработчиками. На нем вы сделаете 5 проектов на JavaScript и научитесь писать сложные компоненты на React и интерфейсы с авторизацией и с подключением к бекенду. Смотрите программу курса, сравнивайте и выбирайте подходящее для себя.

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

Другие профессии и курсы
Подробнее..

Как создают и поддерживают веб-страницы tinkoff.ru

22.04.2021 14:23:53 | Автор: admin

Всем привет! Меня зовут Сергей Михайлов, в Тинькофф я работаю руководителем интерфейсов: занимаюсь внутренними сервисами, а также отвечаю за дизайн-составляющую Отдела привлечения клиента. Расскажу, как мы быстро собираем страницы с помощью нашего конструктора.

Как это работает сейчас

В Тинькофф около 2000 страниц с разным дизайном и за все эти страницы отвечает отдел привлечения. Он состоит из подразделений, которые отвечают за карточные продукты, депозиты, инвестиции, страхование, мобайл, путешествия и так далее.

Все наши страницы состоят из блоков. Например, на главной странице есть шапка, блоки с главным баннером, с заголовком и с карточкой продуктов.

Макет блока в FigmaМакет блока в Figma

Страницы собираются из блоков в нашем Конструкторе.

Конструктор страницКонструктор страниц

Вот пример такого блока с карточками:

Блок Продуктовые карточкиБлок Продуктовые карточки

В него уже вшита логика с отступами, возможность выключить заголовок или изменить стиль кнопки. Также в блок уже вшита логика растягивания. На примере блок для экрана 1024, а при разрешении 1360 блок растянется. Так у нас работают все блоки.

Конструктор, в котором собираются страницы, это часть нашей CMS. Главное преимущество админки возможность быстро и безрелизно вносить правки на страницу, настраивать аналитику и персонализацию.

Экран собранных страниц и черновиковЭкран собранных страниц и черновиков

Мы тестируем много страниц и иногда для теста создаём новые блоки. Раньше создание нового блока занимало у команды разработки до 2 недель. При этом если если тест не проходит, то от блока отказываемся.

Поэтому, чтобы экономить время, мы можем собрать в Конструкторе блок, сразу его протестировать и, если тест успешен отдать его в команду разработки для добавления в библиотеку блоков.

Также в Конструкторе мы отдельно собираем десктопную и мобильную версии страницы. Например, есть страница, на ней два одинаковых блока, но выглядят они совершенно по-разному.

Десктоп и мобильная версия страницы Тинькофф ПлатинумДесктоп и мобильная версия страницы Тинькофф Платинум

На мобильных версиях мы обычно делаем меньше текста, меньше изображений и тем самым разгружаем трафик пользователя. С помощью тестов мы выяснили, что конверсия не проседает. Однако так было не всегда.

Как было раньше

Вернемся на пять лет назад и посмотрим, как у нас был выстроен процесс создания страниц.

В 2016 году аналитики и разработчики задались вопросом: У нас же большая часть страниц продающие лендинги. Почему бы не сделать сервис, который обрабатывал бы все эти страницы?.

Тогда придумали систему, назовем ее версия 0. К сожалению, ее скриншоты не сохранились. Вся страница выглядела как один большой блок с формой. Даже такой подход всех устроил, его стали активно использовать и сделали админку с Конструктором версии 1.0.

Конструктор версии 1.0Конструктор версии 1.0

У старой админки еще не было интерфейса, в котором можно было собирать лайв-превью страниц, не было превью блоков, но она уже обладала рядом функций, которые всех устраивали. Функционала становилось все больше, добавилась, например, возможность просматривать историю публикаций и изменений, появилась сложная настройка блоков. Админка превратилась в версию 2.0.

Конструктор версии 2.0.Конструктор версии 2.0.

Дизайнеров у нас в команде конструкторов тогда не было, админку собрали на Material Design. Большим минусом стало то, что из-за сложности системой могли пользоваться только наши контент-менеджеры, которые умели собирать страницы и настраивать сложные блоки. Было бы неплохо сделать нормальную систему, с которой смогли бы работать все пользователи.

Сформулировали цели для новой админки:

  • Уменьшить порог вхождения новых пользователей. Нам было важно, чтобы не только контент-менеджеры могли собирать страницы, но и дизайнеры, заказчики и менеджеры.

  • Сделать понятный процесс сборки страниц, а процесс подготовки пользователя не занимал больше одного дня. Важно, что человек, более или менее знакомый с любым конструктором типа Тильды, мог сразу же собирать страницы и в нашей админке.

  • Сократить время выпуска новых страниц.

Собрали команду из аналитика, дизайнера, контент-менеджера и разработчика. У нас не было привычного флоу, когда дизайнеры и аналитики придумывают интерфейс и отдают разработчикам. Вместо этого мы с самого начала собирались всей командой, проводили дважды в неделю встречи, на которых составляли разные фреймворки, писали сценарии по User Story Mapping. То есть все участники процесса имели слово и вместе собирали админку.

Результатом стала админка версии 3.0.

Конструктор версии 3.0.Конструктор версии 3.0.

Новая админка сократила сроки выпуска: если раньше любой релиз можно было вносить раз в две недели, потому что у каждой команды был свой график релизов, то теперь, благодаря админке, это время сократилось до пяти минут. Пользователи заходят на нужную страницу, вносят правки (например, меняли процентную ставку) и нажимают кнопку Опубликовать и страница тут же была на продакшене. Таким образом мы закрыли одну проблему. Однако вместе с этим появилась другая проблема.

Проблема с блоками

Например, у нас есть команда страхования, в которой есть свой дизайнер, контент-менеджер, разработчик и аналитик. Им понадобился новый блок карточка с иконкой и кнопкой. Они разрабатывают карточку и вносят ее в библиотеку блоков админки. И вроде бы все хорошо, только они не знали, что вместе с ними параллельно еще две команды делали точно такой же блок.

На таком уровне не было синхронизации, и, например, одна команда сделала блок с большой иконкой, другая с маленькой, кто-то добавил две кнопки, кто-то убрал бейдж.

Все три команды добавили блоки в админку. Во-первых, непонятно, какой блок использовать. Во-вторых, у каждого продукта свое приложение для отрисовки страниц и это порождало проблему: если одна команда сделает блок под себя, то у другой команды, взявшей этот блок к себе на страницу, полетит вся верстка.

Какие у этого минусы::

  • Затраты на разработку. Разные команды делают одно и то же.

  • Много одинаковых блоков.

  • Один и тот же блок выглядит по-разному на разных страницах, из-за этого у нас нет консистентности.

Тогда мы приняли решение создать команду для разработки и поддержки блоков, которая экономила бы нам ресурсы и отвечала за то, чтобы новые блоки могли использовать все. Например, если команда инвестиций прибегает и говорит: Нам нужен блок, то команда админки уже делает так, чтобы этот блок могли использовать и другие команды, а также следит за тем, чтобы лишних блоков не было, а в новых учитывались дополнительные кейсы.

Например, команда продукта нарисовала блок с двумя карточками и хотят его разработать Команда админки, уже учитывая свой опыт, понимает, что такой же блок может понадобиться другой команде, но они захотят сделать не две, а три карточки. Для этого не надо делать новый можно добавить функционал в текущий. А может, кому-то понадобится большее число карточек, и тогда можно сделать карусель. Такими задачами занималась команда админки.

Проблема с процессом сборки страниц

Из-за того, что админка настолько всем зашла, все хотели ею пользоваться, но у нас не было унифицированного флоу, по которому бы все работали. Появилось много новых пользователей, которые сами придумали себе процесс работы.

Давайте посмотрим на средний состав участников процесса создания страниц:

  • Заказчик человек, которому нужна страница, чаще всего это product owner.

  • Копирайтер пишет текстовый прототип страницы.

  • Дизайнер собирает макет.

  • Разработчики подключаются, когда нужна разработка нового блока.

  • Контент-менеджеры все еще специалисты нашей админки, которые настраивают сложные блоки (футер, шапку, формы с различными шагами).

  • Аналитики вносят свои настройки в страницу.

Например, заказчик мог пойти в админку, собрать и опубликовать страницу. Либо он мог отдать задачу на создание текстового прототипа копирайтеру. Копирайтер все это передает контент-менеджеру, а контент-менеджер в админке собирает страницу. Либо заказчик ставит задачу дизайнеру, дизайнер в Figma собирает макет, контент-менеджер по макету из Figma собирает в админке страницу. Таких процессов у нас было очень много, но усредненно процесс выглядел так:

Заказчик ставит задачу копирайтеру, копирайтер отдает текстовый прототип дизайнеру, дизайнер собирает в Figma макет, контент-менеджер по figma-макету собирает в админке страницу, все ребята его согласовывают. Если нужен блок, ставят задачу разработчикам и затем передают аналитику для окончательной настройки, после чего страница запускается.

Минусы такого подхода:

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

  • Блоки в макетах не соответствуют реальности. Помимо сторибука, где хранятся все наши блоки, эти же блоки есть и в Figma, откуда их берут дизайнеры. Бывало так, что дизайнер собирая страницу может добавить новый элемент в блок, не зная, как он на самом деле работает. Впоследствии, когда контент-менеджер начинал собирать страницу по figma-макетам, ставил блок из админки и понимал, что блок так не работает. В итоге много времени уходило на разбирательство, как поступить в этой ситуации.

  • Новый блок для страницы ждем долго. Как я упомянул выше, мы очень поздно предупреждали разработчиков о том, что нам нужен новый блок. Разработчики не успевали его подготовить либо, очень злясь на нас, были вынуждены готовить его быстро, но говорили, что это в последний раз.

  • Нет консистентности. Разные участники собирают страницы, шаблонов нет, многое каждый делает по-своему из-за этого страницы могут выглядеть по-разному.

  • Нет понимания зон ответственности и результатов работы.

  • Увеличивается срок выпуска страниц.

Решение

Столкнувшись с вышеописанными проблемами, мы решили:

  • Описать правильный и понятный процесс выпуска страниц, потому что у ребят уже были свои чек-листы, гайды и так далее.

  • Описать зоны ответственности. Собрать все вместе и превратить в нормальный процесс.

  • Дизайнеры собирают страницы в Конструкторе. Перевести всех дизайнеров со сборки страниц в Figma в наш Конструктор, чтобы они понимали, как работают блоки, и из них составляли страницы.

  • Все команды подключаются на старте.

Что мы для этого сделали? Для начала я нарисовал весь процесс работы из тех чек-листов, которые у нас были. По этому процессу заказчик по шаблону заводит эпик и прилинковывает задачи копирайтеру, ставит задачи дизайнеру, контент-менеджеру и аналитику. То есть ребята уже заранее знают, что понадобится страница, понимают, что им предстоит делать, и планируют свое время соответственно.

Копирайтер может использовать артефакты: он может пойти в сторибук, посмотреть, как работают блоки, если ему так проще составлять прототип; может пойти в Figma либо в Конструктор. Результатом его работы будет текстовый прототип (на самом деле не только текстовый прототип может быть собран в PDF или в Figma, и это будет результатом работы).

Затем этот прототип передается дизайнеру. Дизайнер может по-прежнему использовать сторибук, Figma, гайд по сборке страниц, который у нас есть, но все равно результатом его работы будет ссылка на десктопную и мобильную версии страницы.

Но бывает проблема: уже в процессе сборки страницы дизайнер понимает, что ни один из текущих блоков не подходит и понадобится новый блок. Тогда он заводит задачу для разработчиков, и те уже начинают его создание.

Как создают новые блоки?

Дизайнер рисует мобильную версию страницы и в процессе понимает, что ему нужен блок (карточка с иконкой), которого у нас еще нет. Согласно процессу, он идет в команду дизайна и говорит: Нам нужен новый блок. Ребята понимают, что это многофункциональный блок, который может понадобиться всем, его можно встраивать и на другие страницы. Тогда задача передается в команду админки, у которой есть два варианта:

  1. Команда админки видит, что есть похожий блок, но без иконки это просто текстовая карточка со своим набором полей. Они решают дополнить эту карточку иконкой и добавить новые настройки. После миграции все могут использовать этот блок и нет необходимости создавать и поддерживать новый.

  2. Нужного блока нет, и похожего тоже нет. Тогда дизайнер идет в Figma и там собирает макет для разработчиков, отрисовывает все состояния и, когда макет собран, он передается в команду админки, которая создает схемы и UI блока. То есть команда админки решает, какие опции должны быть в настройках карточки. Команда блоков верстает и тестирует этот блок.

Макет блока для вёрсткиМакет блока для вёрстки

При разработке блоков используют инструмент Multistory, который разработала команда блоков.

Multistory показывает все возможные варианты и состояния этого блока, все текстовые стили, все варианты его поведения, при которых мы понимаем, все ли мы учли в макете, можем отследить возможные проблемы и решить их.

MultiStoryMultiStory

Когда блок уже сделан, он попадает в библиотеку блоков нашего Конструктора, где его могут все использовать.

Библиотека блоков в КонструктореБиблиотека блоков в Конструкторе

Для отслеживания поведения блоков команда блоков разработала инструмент RealStory. Например, есть карточка с картинкой (заголовком, кнопкой), и мы можем в реальном времени посмотреть, на каких страницах сейчас эта карточка присутствует и как она выглядит. Это позволяет дизайнерам и разработчикам отслеживать поведение блока: как он работает и нет ли в нем ошибок.

RealStoryRealStory

Вернемся к процессу

Когда дизайнер сделал десктопную и мобильную версии страницы, задача попадает к контент-менеджеру, и он идет настраивать блоки через Конструктор. Он настраивает шапку и футер для блока, делает сложные настройки и затем передает задачу аналитику. На самом деле чаще всего контент-менеджер и аналитик могут работать параллельно, а иногда контент-менеджер уже знает настройки аналитики и заполняет их самостоятельно.

Если, например, контент-менеджер не настроил аналитику сам, то задача аналитика настроить эти блоки: какие блоки надо трекать, настройки шеринга либо настройки оптимизации и персонализации. После задача попадает обратно в эпик.

Я нарисовал схему, как ее представлял, и пошел по всем участникам процесса. Стал рассказывать, что мы хотим ввести новый единый процесс, по которому могли бы все работать, и все восприняли это с энтузиазмом, стали помогать, у нас собралась большая команда.

После я перенес схему в Notion, где каждый мог оставлять комментарии, мы что-то перерабатывали, а результатом стала как раз та схема, которую я показал выше. Сейчас этот новый процесс на этапе реализации.

Процесс в NotionПроцесс в Notion

Что будет дальше?

Во-первых, из-за того, что у нас много команд и они большие, нельзя просто взять и сказать: Теперь вы будете делать так, как мы решили. Конечно, так нас просто пошлют. Для начала мы решили протестировать на небольших процессах, на сборке шаблонных страниц, и процесс начал себя показывать достаточно хорошо. Конечно, есть нерешенные проблемы (например, на какой стадии подключать команды), но процесс двигается хорошо. Более того, команда блоков уже работает по новому процессу, и это экономит много ресурсов и времени.

Всегда думайте о том, что можно улучшить в ваших процессах. Если у вас есть предложения и идеи, всегда привлекайте членов команды для участия в процессах на самом деле каждому человеку есть что рассказать и так может получиться крутой проект. И будьте активнее: чем активнее вы собираете команду, тем больше людей будут вовлекаться в ваш процесс и его можно улучшать, не дожидаясь кого-то. Вряд ли кто-нибудь выступит против конечно, все с удовольствием будут улучшать процесс.

Подробнее..

Перевод Чему я научился, прожарив 200 лендингов за 12 месяцев

17.05.2021 20:19:35 | Автор: admin


200 стартапов


За последние двенадцать месяцев я прожарил лендинги (посадочные страницы проектов) 200 стартапов. Лендинги инди-проектов, лендинги сейлапов, финансируемых венчурным капиталом, и лендинги прибыльных корпораций, лендинги из различных отраслей и для разной аудиторий. В среднем 25 минут прожарки это больше 3,5 полных дней прожарки страниц для увеличения конверсии.

Что такое прожарка


Каждая прожарка это персонализированный 20-минутный видео-обзор лендинга, где я определял исправления, которые позволят превратить больше посетителей в клиентов.


Все это основано на передовом опыте, результатах тестирования и моей работе в качестве эксперта по оптимизации коэффициента конверсии.

Но что я узнал о лендигах с высокой конверсией? А о ведении бизнеса? И чему вы можете научиться у меня? Получается, довольно многому

Почему я запустил Roast My Landing Page


Roast My Landing Page начинался как побочный проект, связанный с пандемией, чтобы позволить мне поддерживать стартапы на ранних стадиях и одновременно генерировать второй поток дохода помимо моей внештатной маркетинговой работы. В итоге я получил более 70 000 фунтов стерлингов, более 2 000 подписчиков по электронной почте и постоянно растущий список инсайтов о страданиях и проблемах предприятий на ранней стадии и об удивительных людях, которые ими руководят.

Все дело в фаундерах


И это действительно сводилось к фаундерам. У каждого человека своя история, страсть и идеи. Они стремились узнать, как отдать должное своему продукту, услуге или списку рассылки и продемонстрировать это миру в виде лендинга с высокой конверсией.

Этот пост для каждого основателя, который поблагодарил меня, бросил мне вызов и (в редких случаях) боролся со мной. Это было круто. Итак, вот что я узнал

9 самых распространенных (и легко исправляемых) вещей, которые упускают из виду фаундеры



Одна цель


У 50% фаундеров была одна четкая цель для своей посадочной страницы зарегистрироваться, загрузить лид-магнит или заказать демо. У остальных 50% было несколько призывов к действию, зачастую с одинаковым приоритетом. Это часто приводит к параличу анализа и замешательству посетителя.

Как исправить: сфокусируйте свой лендинг на одной цели конверсии.

Акцент на УТП


После заказа прожарки клиентам Roast My Landing Page предлагается заполнить небольшую анкету. Один из вопросов: Что делает ваш бизнес уникальным? Почти каждый основатель смог изящно изложить УТП (уникальное торговое предложение) своего продукта или бизнеса в форме, но только одного из пяти что-то подобное было изложено на их посадочной странице.

Один из ключевых моментов вашего лендинга: что делает вас уникальным. Если покупатель находится на стадии рассмотрения (сравнения решений), ваше УТП это то, что заставит их вспомнить вас и решить, подходите ли вы лучше всего для их нужд.

Как исправить: сравните свой продукт с конкурентами и текущими методами работы.

Четкое и релевантное социальное доказательство


Отзывы, рейтинги, награды или количественные оценки, подтверждающие, что другие люди используют ваш продукт и любят его. Только около у 40% лендингов это находилось в верхней части страницы (то, что люди видят, когда впервые попадают на вашу страницу). И из них только около 50% использовали отзывы, которые описывали боль и преимущества, перечисленные в другом месте лендинга.

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

Простой язык


Примерно 1 из 8 лендингов, которые я прочитал, я не смог понять при первом прочтении. Потребовалось несколько попыток, чтобы просто понять эти целевые страницы. Только у меня был денежный стимул попытаться разобраться в происходящем, а у посетителей лендига нет.

Как исправить: избегайте технических терминов и сокращений, пишите простым языком. Помните, что вы разговариваете с человеком, даже если он покупатель B2B. Спросите себя, может ли 12-летний ребенок понять вашу целевую страницу.

Реальная боль


PAS (боль волнение решение) распространенный метод копирайтинга, используемый для увеличения конверсии. Большинство лендингов касались той боли, к которой они обращались, но только 1 из 15 старались взволновать или усилить переживания посетителя эмоциональным языком и яркими образами. Те, кто сделал это хорошо, создали гораздо более мощные лендинги, которые побудили меня изучить решение.

Как исправить: взволнуйте вашего посетителя, нарисовав яркую картину боли, используя эмоциональный язык, истории и визуальные эффекты.

Ясные преимущества и юзкейсы


На многих лендингах подробно рассказывается о функциях продукта, но игнорируются преимущества и варианты использования. Исследования неизменно показывают более высокую конверсию при использовании языка, основанного на преимуществах. Посетителю приходилось думать, как продукт принесет ему пользу или конкретно решит их проблему.

Как исправить: посетителям не нужно думать, как и почему продукт принесет им пользу. Расскажите и покажите понятным им языком преимущества и примеры использования.

Заметный призыв к действию


На многих целевых страницах был призыв сделать что-то, без четких указаний что именно. Да, они собирались зарегистрироваться, но сколько времени это займет? На что они соглашались? Сколько это будет стоить? Какая технический сетап была задействован?

Как исправить: добавьте контекст в ваш призыв к действию, чтобы посетитель знал, чего ожидать.

Спросить вместо чрезмерного обдумывания


3 из 5 основателей упомянули разочарование из-за того, что не знали, что происходило до прожарки. Они не понимали, почему их лендинг не конвертирует посетителей в клиентов. Однако очень немногие действительно спрашивали об этом своих посетителей.

Как исправить: зарегистрируйтесь в GetSiteControl и добавьте на свою целевую страницу опрос о намерениях выхода. Узнавайте, почему они уходят. Учитывайте эти причины на своей странице.

Знание своей статистики


Только 2/5 основателей могли рассказать мне о текущей конверсии своего лендинга. В большинстве случаев эти люди даже не знали, есть ли у них проблема с конверсией на странице, но все равно заказали прожарку. У большинства основателей была установлена система Google Analytics, но у них были ограниченные возможности отслеживания целей или они не просматривали отчеты в течение нескольких месяцев.

Как исправить: настройте аналитику и отслеживание событий. Найдите базовый уровень конверсии для будущих экспериментов.

7 (чуть больше) продвинутых идей для повышения эффективности лендингов


Приблизительно 1 из 4 заказов был прожаркой лендигов скейлапов, где явно использовали высокий уровень экспертизы и навыков для создания посадочной страницы. У этих бизнесов все еще были проблемы с конверсией, которые в основном приходились на следующие 7 областей.

Не сформирована ниша


Я видел это снова и снова, и меня часто спрашивали об этом. Я должен ориентироваться на большую или на меньшую аудиторию? Конечно, чем больше рынок, тем лучше? Мой совет всегда был одним и тот же. Создайте лендинг для максимально узкой аудитории, пока не найдете первых клиентов. Позже создайте больше посадочных страниц.

Посадочные страницы, ориентированные на несколько персон и вариантов использования, почти всегда конвертируют хуже. Выбирайте ниши, расширяйте позже.

Вы предлагаете слишком много или слишком рано


Никто не зарегистрируется, не понимая своей проблемы, вашего решения и ваших цен. И очень немногие люди платят корпоративному SaaS, не посоветовавшись предварительно с менеджером по работе с клиентами. Помните о том, что вы предлагаете в своем призыве к действию. Слишком рано на странице или в цикле покупки, конвертация не произойдет.

Напишите список того, что посетитель должен знать, прежде чем зарегистрироваться. Убедитесь, что эта важная информация находится перед вашим первым призывом к действию.

Вы рассказываете людям то, что можете им показать


На многих страницах использовались большие блоки текста для объяснения чего-то, что можно было яснее и убедительнее продемонстрировать в виде простого снимка продукта, таблицы, визуализации, примера, демонстрации, иллюстрации или абстракции.

Показывай, не говори.

Вы не обращаете внимания на сомнения


При посещении вашего лендинга ваш потенциальный покупатель будет мысленно задавать вопросы. С увеличением количества этих неотвеченных вопросов шансы на конверсию уменьшаются. Узнайте, что это за вопросы, и рассмотрите их в тексте или в FAQ (модуле часто задаваемых вопросов).

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

Вам нужно использовать более качественные изображения


Около 65% проверенных мной лендингов использовали изображения из популярных коллекций лендингов: фотографии, значки и иллюстрации. Хотя эти изображения были рабочими и даже иногда уместными, они редко передавали тот же смысл визуально.

Работайте усерднее, чтобы найти или создать выразительные изображения для лендинга.

Вы не знаете свою статистику


Даже люди, которые были чрезвычайно умны и знали эффективность своей целевой страницы, не измерили всю свою воронку от источника маркетингового канала до регистрации аккаунта. Т.е. что у них могла быть фантастическая целевая страница, но не было полной измеренной воронки регистрации.

Настройте воронки в Google Analytics или других инструментах, чтобы вы могли отслеживать переходы по всей воронке, а не только на целевой странице.

Вам необходимо регулярно тестировать конверсию


И наконец. Возможно, у вас уже есть лендинг с высокой конверсией, но без регулярного тестирования вы ничего не узнаете. Ни у одного заказчика не было регулярного графика тестирований. В лучшем случае они последний раз проверяли производительность после перезапуска своего сайта несколькими месяцами ранее.

Цикл постоянных экспериментов увеличивает ваши знания о клиентах и увеличивает доход. Продолжайте тестирования.

Что я узнал о построении бизнеса


Как зарабатывать деньги


  • Я получил около 20 000 фунтов стерлингов от прожарки и еще 50 000 фунтов стерлингов в виде внештатной маркетинговой работы от клиентов, которые нашли меня через прожарку.
  • Я потратил около 7 000 фунтов стерлингов на платную рекламу производства и около 3000 фунтов стерлингов на инструменты и другие бизнес-расходы.
  • Недавно я добавил дополнительные услуги переписывание рекламных текстов, перестройка лендинга, внедрение аналитики конверсии. Примерно 1 из 4 моих клиентов по прожарке заказали вторую услугу.
  • Примерно каждый шестой клиент предлагает мне внештатную маркетинговую работу.


Фаундеры и конверсия


  • Наиболее частой причиной заказов: фаундер получил чье-то мнение, основанное на ощущении, что их лендинг не работает или их позиционирование неправильное.
  • Большинство фаундеров не знали о конверсии своего лендинга в моменте, даже если у них была аналитика.
  • Почти каждый фаундер использовал Google Analytics для измерения аналитики сайта, большинство из них установили цели, но многие фактически не анализировали их эффективность.
  • 95% прожарки было заказано фаундерами-мужчинами.
  • Наиболее распространенными типами лендингов были приложения и инструменты SaaS, электронная торговля и B2C.


Конкуренция


  • Около 5 конкурентов создали почти идентичные продукты, явно вдохновленные Roast My Landing Page.
  • Многие заимствовали текст, концепции, призывы к действию, ценообразование и маркетинговые идеи прямо с моего веб-сайта Roast My Landing Page.
  • Другие были вдохновлены, но добавили свои собственные мотивы.
  • Некоторые обращались и просили моей поддержки, обратной связи и совета.
  • Оказалось, что многие из этих проектов закрылись в считанные недели.
  • Я взял за правило не сосредотачиваться на том, что они делают, а вместо этого вкладывал энергию в развитие своего бизнеса. Но друзьям пожаловался.


Сбор отзывов


  • Перед тем как прожарить лендинг, я отправлял клиенту форму с 7 вопросами, на которые нужно было ответить, чтобы они могли задуматься и сосредоточиться, а также дать мне контекст.
  • После прожарки я разослал всем клиентам анонимный опрос Typeform, спрашивая их об одной идее по улучшению прожарки, которую я использовал для уточнения своего предложения.
  • Примерно каждый четвертый заполнил опрос, каждый четвертый отправил отзыв по электронной почте и от каждого второго я больше ничего не слышал.
  • Опрос включал рейтинг из 5 звезд. Из ответивших я получил 46 5-звездочных оценок и 4 4-звездочных.
  • Опрос также содержал вопросы о других сферах их бизнеса, которые основатели хотели бы прожарить это привело к тому, что я создал другие службы.
  • Около 25% клиентов ответили на мои предложения лично.
  • Около 50% фаундеров внедрили исправления, подробно описанные в обзоре. Большинство сделали это сразу же или через несколько недель (или даже месяцев) спустя.
  • Совсем недавно каждый четвертый заказчик попросил меня внести изменения за них.
  • Чем больше я работал на публике, тем больше мне помогали незнакомцы. Люди регулярно присылали мои идеи, исправления, даже свои собственные мини-прожарки несколько раз в неделю.


Как я привлекал клиентов


  • Целевая страница Roast My Landing Page имела различные проблемы с конверсией.
  • Я итерировал целевую страницу около 20 раз, протестировал 3 платежных решения, 4 ценовых диапазона и 5 потоков покупок. Я все еще тестирую это сейчас.
  • Мои самые эффективные маркетинговые каналы это сарафанное радио, участие в сообществах Indie Hackers и Productize, таргетинг в Twitter, таргетинг в Facebook и затем Google Реклама, партнерские отношения.
  • Наилучшая рентабельность инвестиций в рекламу на платной рекламе составила около 3.
  • Худшими маркетинговыми каналами оказались Quora, Reddit, электронная почта через Paved.com. Многочисленные тесты на этих платформах не привели к значительной конверсии.
  • Лучшим способом распространения сарафанного радио было перевыполнение. Я обещаю дать каждую прожарку в течение 48 часов, но многие клиенты получили свое в течение часа после заказа. Это произвело на фаундеров головокружительное впечатление и вызвало немало шума.


Инструменты, которые я использовал


  • Такие инструменты, как Loom, великолепны для записи видео в видео. Но когда им не удается записать промежуточную прожарку, это ужасно. Когда это происходит 3 раза подряд, вы думаете о том, чтобы бросить работу, арендовать небольшую надежную машину, собрать свои вещи и переехать на удаленную ферму подальше от всего и всех, кого вы знаете.
  • Я использовал SPP для управления заказами.
  • Типовая форма для обратной связи с клиентами.
  • Google PageSpeed Insights для определения времени загрузки страницы.
  • Autopilot для моего списка рассылки.
  • Ghost для этого блога.
  • Инструменты аналитики, которые я использовал, включают Hotjar для записей и тепловых карт, Heap для воронок и Google Analytics для высокоуровневых отчетов и показателей конверсии.
  • GetSiteControl помогает мне собирать потенциальных клиентов через мою еженедельную почтовую рассылку.
  • Hotjar помог мне собрать информацию о намерениях выхода.
  • Я использовал для платежей Stripe и Paypal.


Стоимость моего продукта


  • Прожарка начиналась с 39 фунтов стерлингов, поднялась до 299 фунтов стерлингов и сейчас составляет 149 фунтов стерлингов.
  • Я протестировал несколько разных ценовых категорий, чтобы определить, что принесет наибольшую прибыль.
  • Съемка прожарки требует ментальных затрат и чрезвычайно утомляет, поэтому мой лимит составлял около 4 в день.
  • Я перешел к ценообразованию не основанному на времени, поскольку я получил доказательства того, что прожарка увеличивает конверсию.
  • Я все еще изо всех сил пытаюсь привлечь нужных клиентов по правильной цене, не прекращая поддержки клиентов.


Реализованные мной процессы


  • Рутина это хорошо, но я борюсь с ней: еженедельные циклы отчетности и личные ретроспективы помогали мне быть в курсе событий.
  • Да, я проводил ретроспективы, сосредоточившись на том, что я могу улучшить по сравнению с предыдущей неделей.
  • Отчетность помогла мне сосредоточиться, особенно публичное размещение в моем Twitter и подробное описание моих вех на Indie Hackers.
  • У меня также есть небольшое сообщество единомышленников в Slack, с которыми я могу делиться идеями, я несу ответственность перед ними.
  • Сами прожарки относительно произвольной формы. Однако со временем сформировалась общая структура, что позволило сделать акцент на самые большие возможности.


Что же дальше?


Мало того, что Roast My Landing Page приносит прибыль, но и ведение бизнеса приносит мне плоды, которых я не ожидал.

Я (пока) не сидел на пляже, потягивая маргариту, пассивно зарабатывая мега баксы, но мне нравится давать действенный фидбэк по справедливой цене, видеть, как бизнес моих клиентов растет, нетворкаться и продолжать улучшать свое понимание фаундеров, их бизнеса и оптимизации конверсии.



Чтобы не терять свои находки по дизайну в тоннах закладок на компе, я создала телеграм-канал Дрын Дезигн. Все клевые и полезные материалы (туториалы, статьи, ссылки на аккаунты клевых чуваков), которые нахожу для себя, я буду постить туда. Угощайтесь.
Подробнее..

Figma плагины для продуктового дизайна. Локальный топчик с видео-инструкцией

25.05.2021 16:13:10 | Автор: admin

Для Figma написан целый легион плагинов навсе случаи жизни. Постоянно появляются рейтинги итоп-листы супер-пупер-мега-лучших. Ноэтот инструмент используют люди разных конфессий, решая разные свои задачки. Рыцари фриланса рисуют лендинги, студийные братья собирают промо-сайты, еретики даже визитки иплакаты пытаются делать вFigma. Идля всех есть свои плагины. Поэтому делать общий топ-100 пустое занятие.

Номожно накидать локальный местечковый топчик для продуктового дизайнера например. Внём небудет плагинов вдухе смотрите, какая любопытная идея или если вдруг вам когда-нибудь понадобится заменить все картинки нафото Николаса Кейджа. Только ежедневные трудяги. яуверен, этот список будет полезен нетолько UI-дизайнерам исочувствующим. Что-то полезное найдут для себя ивсе остальные фанаты Figma.

В конце статьи будет ссылка на видео-инструкцию.

Иерархия библиотек вOzon

Яслужу рядовым разработчиком интерфейсов вOzon, где наша маленькая, ногордая команда занимается внутренними продуктами компании. Всяческие админки иCRM-ки. Впрочем, идоосновного сайта мыдотягиваемся.

Работа внашей команде строится последующей схеме: для каждой Job или User Story мыделаем отдельный файл сэлементарным линейным сценарием. Там мысобираем экраны, пройдя которые пользователь решает свою задачу. Втаких сценариях, конечноже, появляются повторяющиеся паттерны, которые можно переиспользовать вдругих User Story иони достойны переноса вотдельную сценарную библиотеку. Этот подход позволяет нераздувать файлы, держать всю систему под контролем идостаточно свободно вносить правки, затрагивающие множество сценариев.

Сейчас унас вOzon есть несколько типов библиотек:

  • Атомарные токены дизайн-системы.

  • Молекулярные библиотеки сэлементами интерфейса. Изних собираются экраны сценариев.

  • Сценарные библиотеки, вкоторые попадают проектные организмы. Оттуда мыможем централизованно использовать ихвдругих сценариях. Повторюсь, разговор нетолько про сайт ozon.ru компании нашего масштаба имеют огромное количество внутренних продуктов, которые также подчиняются единой дизайн-системе.

Библиотечная иерархияБиблиотечная иерархия

Рабочие лошадки иудобные пони

Нохватит зауми! Вперёд кхит-параду. Ида, тут будут представлены иплатные сокровища, ночто значат деньги, когда дело касается Продукта иПродуктивности.

Master

Community

Этот плагин достоин носить джедайское звание Мастер. Сложно переоценить, сколько времени онсэкономил нашей команде. Яуже рассказывал онём насвоём YouTube-канале, асегодня подчеркну его полезность для продуктовой работы. Мало того, что онумеет перелинковывать инстансы кновому мастер-компоненту, сохраняя все оверрайды, так онещё может делать это сбиблиотечными компонентами.

Тут унас типичная ситуация. Форма собрана измолекулярных библиотечных компонентов. Спроектированы разные её состояния. Становится понятно, что она достойна быть добавленной всценарную библиотеку. Если делать это штатными средствами, придётся перенастраивать кучу экранов. Ноунас есть Master.

Копируем одну изформ ивставляем её всценарную библиотеку. Делаем компонент ипубликуем. Запускаем команду Pick Target Component изарсенала плагина Master. Возвращаемся вфайл сценария ивыделяем все наши формы. Запускаем команду Link Objects toTarget Component.

Дапребудет стобой сила, Master!

Design System Organizer

Community

ВнародеDSO. Крутейший комбайн поуправлению стилями икомпонентами. Кроме удобной системы организации стилей попапкам, переименованию идублированию, DSO умеет перелинковывать стили икомпоненты набиблиотечные. Причём непоодному компоненту, амассово. Может экспортировать иимпортировать стили между файлами. Всё это позволяет, достаточно безболезненно переезжать между версиями дизайн-системы, дублировать библиотеки ипроворачивать всякие эксперименты.

Тут унас локальные цветовые итипографские стили. Надо привязать ихктакимже библиотечным. Идём вбиблиотеку изапускаемDSO. Заходим вцветовые стили, выделяем нужную группу ивыбираем извыпадающего меню Set AsTarget. Возвращаемся внаш файл, запускаем DSO ивыбираем Relink Styles. Бум! Стили теперь тянуться изкомандной библиотеки. Такимже образом перелинковываем другие стили или компоненты.

Style Organizer

Community

Этот штепсель помогает неударять вгрязь лицом перед разработчиками. Проверяем, откуда тянутся стили. Ловим нестильные шейпы итексты. Чиним вручном или автоматическом режиме. Соответствуем высоким стандартам разработки Ozon иублажаем личного беса-перфекциониста.

Вот тут унас типичная ситуация. Наглазок всё впорядке, нотакли это? Стартуем Style Organizer. Ивидим, что один изчёрных квадратов имеет локальный стиль, второй библиотечный, атретий вообще без стиля. Можно пробежаться посписку ошибок вручном режиме, сшивая стили, аможно нажать Auto Fix Color иStyle Organizer будет действоватьсам.

Similayer

Community

Все знают обэтом замечательном плагине. Нонеупомянуть его былобы нечестно, ведь мыговорим олучших. Онможет выделить почти всё, что угодно помножеству признаков.

Давайте выделим слово Zen синего цвета, вне зависимости отстиля текста. Выделяем один синий Zen изапускаем Similayer. Выбираем параметры Fill Style иText Characters.

Удобненько!

Instance Finder

Community

Ищет ивыделяет только инстансы. Зато делает это шустрее Similayer иработает повсему документу, анепоодной странице.

Выделяем мастер или любой изинстансов изапускаем поиск. Можно сразу выделить все найденные настранице инстансы.

Select Layers

Community

Ещё один незаменимыйвыделятель. Чаще всего ловлю им слои по названию (он поддерживает частичное вхождение запроса). В отличииотSimilayer, SelectLayersне требует выделять образец для поиска соответствия и, что крайне важно, может искать только в выделенном.

Вот тут унас мега-вариант инпута. Выделяем поля пароля изапускаем плагин. Пишем название нужного слоя ивуаля! Можем поменять иконку, например.

Sorter

Community

Часто возникает необходимость пронумеровать экраны. Чтобы цифры шли попорядку, фреймы должны быть внужной последовательности впанели слоёв. Sorter может отсортировать ихпоположению налисте (инетолько). После чего ихможно переименовать штатными средствами.

Если попытаться пронумеровать экраны, нерасставив ихвпанели слоёв, получим хаос. Нуок. Выделяем все экраны, запускаем команду Sort Position ипосле этого уже штатный Rename Selection.

Порядочек.

Quantizer

Community

Расставляет элементы всетку сзаданным количеством колонок иотступами. Сильно помогает вработе над вариантами.

Выделяем, что нужно, истартуем Quantizer. Сделаем колонки сотступами по40px.

Кстати, вызнали, что можно таскать объекты всетке закруглые маркеры вцентре? Аменять отступ, хватаясь замаркеры между? Если делать это сShift, шаг будет кратен вашему Nudge Amount.

Swap

Community

Плагин, достойный горячей клавиши. Меняет между собой два любых объекта. Выставляет покоординатам верхнего левого угла.

Выделяем два объекта, запускаем команду Swap и, собственно, всё.

Layer Counter

Community

Карманный бухгалтер для ваших макетов. Подсчитает всё ився. Выделяем, запускаем. Наслаждаемся статистикой.

Если снять галку Include Nested Layers, увидим только количество выделенных фреймов.

Retextifier

Community

Может массово заменять текст ввыделенных блоках. Ноесть досадный недочёт при работе вWindows лишний перевод строки, скоторым можно бороться внешними средствами, заменив символ \n на\r или прогнав текст через сам плагин.

Замечательный инструмент, если умеешь импользоваться иутебя macOS.

НаmacOS: копируем текст, например, колонку изGoogle-таблицы. Выделяем целевые текстовые слои изапускаем плагин. Вставляем текст комбинацией Cmd+Shift+V.

Если увас Windows, действуем немного сложнее. Сначала вставляем скопированный текст вфайл Figma. Выделяем его, запускаем Retextifier, копируем итутже вставляем текст, жмём Change. Копируем изменённый текст, далее действуем как наmacOS. Надеюсь, автор плагина что-то придумает поповоду этого недоразумения.

Copy and Paste Text

Community

Вотличие отпредыдущего, этот плагин вставляет вовсе выделенные слои одинаковый текст избуфера. Безусловно полезно.

Копируем нужный текст, выделяем целевые слои, запускаем команду Paste Text

Find & Replace

Community

Поиск изамена потекстовым слоям споддержкой регулярных выражений (Regex). Для тех, кто умеет врегулярки ипонимает, как это круто.

Сейчас мыпоменяем местами буквы ицифры. Запускаем плагин, включаем поддержку Regex ипишем регулярное выражение. Найти (.*)-(.*) изаменить на$2-$1.

Мистика!

Nisa Text Splitter

Community

Разрезает текстовый блок настроки, сортирует, сшивает, расставляет буллиты имногое другое. Рекомендую.

Давайте расставим фильмы похронологии. Запускаем Nisa Text Splitter ирежем наш блок настрочки. Сортируем поалфавиту Sort byalphabet исшиваем обратно водин блок Join text. Внутри плагина ещё много другой годноты. Например, сразу делать Auto Layout изнарезанного текста.

Change Text to Layer Name

Community

Несамый необходимый штепсель, ночастенько выручает. Меняет текст наназвание слоя. Использую всвязке соштатным Rename Selection.

Выделяем текстовые блоки, применяем Rename Selection, оставляем старое название, добавляем кнему дефис иномер. Запускаем команду Change Text toLayer Name.

Математично!

Data Roulette

Community

Когда работаешь над продуктом, утебя есть постоянно используемые наборы данных. Эти наборы накапливаются икочуют изпродукта впродукт. Data Roulette позволяет хранить ихвGoogle-таблицах ирандомно заполнять ими макеты. Итекстами, ифотками.

Делаем Google-таблицу. Линк нанеё добавляем вData Roulette. Называем целевые слои всоответствии сназваниями колонок таблицы поставив вначало решётку. Можно сделать это вмастер-компоненте. Помере необходимости добавляем вGoogle-таблицу новые колонки.

Рулетка рулит!

Content Reel

Community

Для того, кому лень возиться сGoogle-таблицами, Microsoft наплагинил Content Reel. Только нужно залогиниться. Тогда можно будет создавать свои наборы данных.

Тут всё просто. Выделяем целевые слои, выбираем свой или чужой набор данных, вставляем.

Copypasta

Community

Очень часто нужно что-то добавить навсе экраны сценария. Водно итоже место. ИCopypasta прекрасно решает эту задачку.

Выделяем нужную деталь, запускаем Copypasta, жмём Save selection, выбираем целевые экраны, Duplicate Layers.

Шикарно.

Safely Delete Components

Community

Как ярассказал вначале, мыстараемся неоставлять локальных компонентов врабочем файле сценария. Всё должно тянуться избиблиотек. Заканчивая работу, нужно подчистить засобой.

Safely Delete Components удаляет неиспользуемые мастер-компоненты. Ноэтот плагин нужно использовать состорожностью. Нестоит запускать его вбиблиотеках.

После переноса компонентов всценарную библиотеку, выделяем компоненты локальные изапускаем Safe Delete.

SBOL-Typograph

Community

Незабываем оправильной типографике. Кавычках-ёлочках, длинных исредних тире. Вхорошем продукте всё должно быть прекрасно играмотно. Этот плагин работает сразу повсему документу, без выделения текстового слоя, чем ипримечателен.

Божечки-Ёжечки!

Хорошо, ногдеже тот самый плагин?

Конечно, это неполный список годноты. Янеставил абсолютно все плагины имог что-то упустить. Ксожалению, механизмы каталогизации исортировки вFigma Community оставляют желать лучшего. Посути ихинет вовсе. Поисковая строка даранжирование поколичеству установок. Апопулярность далеко невсегда результат качества. Поэтому ищите, ставьте, испытывайте иделитесь вашими рабочими лошадками вкомментариях.

Всем удачи напродуктовом фронте!

P.S.: Видео-версию статьи можете посмотреть намоём YouTube-канале.

P.P.S.: Ясерьёзно про комментарии.

Подробнее..

Как и зачем Mail.ru Group провела редизайн мобильной версии главной страницы портала

04.06.2021 16:20:58 | Автор: admin


Появление новых сервисов стало испытанием для главной страницы Mail.ru пользователям стало сложнее находить нужные разделы, и в компании решили обновить дизайн. Специалисты Mail.ru Group рассказали об изменениях в мобильной версии главной страницы портала, какие задачи он решает и к каким результатам позволил прийти.

Как было раньше


Старая версия мобильной главной в течение нескольких лет полностью решала те задачи, которые от нее ждали. Пользователи легко перемещались между вкладками, без труда находили Почту, Поиск и Новости. Однако появление новых продуктов Mail.ru Group становилось все большим вызовом интегрировать их в текущую версию получалось сложнее, появлялась разрозненность между блоками. Например, строку Поиска или окно входа в Почту стали замечать хуже, падала глубина скролла страницы, а пользователи уходили с середины новостной ленты.


Старая мобильная версия главной страницы Mail.ru

Кроме того, из-за редизайна бренда Mail.ru Почта и Поиск стали заметно отличаться от визуального стиля главной страницы. Стало понятно, что пора полностью обновить главную органично оформить текущие продукты компании, заложить основу для новых сервисов и партнеров.

План выглядел так:

  • Изменить визуальный стиль главной страницы, опираясь на новую дизайн систему Mail.ru;
  • Сделать доступ ко всем сервисам удобным и быстрым;
  • Добавить навигации по странице развлекательный характер за счет индивидуальных рекомендаций материалов и способов их оформления;
  • Сохранить видимость всех продуктов и учесть интересы тех, на которые пользователи чаще всего переходят с главной страницы Почты,Поиска и Новостей;
  • Адаптировать изменения под устройства с маленькими экранами, чтобы каждому пользователю было комфортно.

С чего начали


Сильные изменения в UX любого продукта могут привести к трудностям у пользователей. Чтобы адаптация к новому дизайну проходила менее болезненно, главную мы решили обновлять поэтапно.

Для начала мы решили направлять внимание пользователя на важные элементы только визуальными инструментами.


Первые UI варианты страницы

На первом этапе разработали три варианта главной страницы. Видна одинаковая последовательность блоков: Почта вверху, Поиск посередине, затем реклама и Новости. Мы убрали из первого экрана все неприоритетные элементы, чтобы сфокусировать внимание пользователя на ключевых продуктах и не отвлекать от Почты и Поиска. В этих вариантах глобально мы изменили только UI, частично применили нашу новую дизайн систему, а именно: закруглили блоки и кнопки, добавили тень и сделали виджеты погоды и котировок, но оставили много акцентного цвета.

Затем мы поработали над остальными продуктами за скроллом. Каждый блок и продукт обрел свой дизайн, который помогал выполнять их функции.


Новая лента

Например, для Кино Mail.ru сделали темную подложку так мультимедийный контент удобнее воспринимать. Для игр добавили большие карточки с обложкой, на которых заметны обновления. Телепрограмме добавили удобное переключение между каналами, чтобы пользователю было проще найти передачи, которые его интересуют. Еще мы недавно внедрили Пульс персональную ленту рекомендаций. На новой главной мы немного изменили ее стиль, добавили темный фон, что увеличило кликабельность.

Меняя главную, мы провели серию юзабилити-исследований в нашей лаборатории, чтобы понять, как реальные пользователи воспринимают изменения. По итогу первых исследований, 80% респондентов, вне зависимости от нахождения рекламы, выбрали синюю шапку как более яркую и привлекательную. Ее и оставили. Но проблема с приоритезацией продуктов осталась синий цвет привлекал очень много внимания, из-за чего Поиск терялся. Пользователи не замечали его или думали, что это панель для ввода пароля, чтобы зайти в свой почтовый аккаунт.

Изменение UX страницы


Пришло время пересобрать структуру страницы. Благодаря предыдущим исследованиям и стратегическому видению продукта мы понимали, что структура первого экрана должна позволить пользователю мгновенно ориентироваться на главной.


Варианты главной страницы для UX исследований

Для тестирования в UX-лаборатории мы собрали несколько макетов с разным расположением блоков, чтобы определить, какое из сочетаний будет лучше восприниматься пользователями. В них мы изменили структуру, а именно:

  • Поиск разместили сверху, так как он означает начало изучения страницы, и такое расположение в целом более привычное для пользователя;
  • Почту расположили под Поиском в виде виджета, чтобы человек не тянулся постоянно наверх. В дальнейшем мы будем выводить не только виджет Почты, но и календарь, Облако и социальные сети. Так пользователь сможет быстро и удобно переключаться между задачами и продуктами. Ниже расположили основную информацию на день: погоду, котировки и новости;
  • В процессе работы Погоду и котировки мы меняли местами с виджетом Почты. По итогам тестирования выбрали вариант, когда погода была ниже и не разделяла Поиск и Почту. Поменяли расположение рекламы;
  • Убрали акцентный цвет и сделали страницу максимально чистой.

UX-тестирование показало следующее. Пользователи сразу видели Поиск, чего мы и добивались. Почта стала не такой заметной, но это мы потом поправили визуально, добавили цвет и анимацию при входе.

Новости остались на том же месте, но мы немного поработали над самим блоком: изменили количество новостей (необходимость этого также показали тесты), добавили отступы между материалами и увеличили размер шрифта. В ленту добавили Пульс, сделав ее бесконечной, поэтому футер перенесли в бургер меню вверху слева так мы получили место для других проектов Mail.ru Group без потерь для дизайна и пользователя.

Изначально мы решили, что реклама будет наверху, отдельно от остальных блоков нам казалось, что так удобнее. Но участники тестирования воспринимали всю страницу как рекламную, поэтому поместили ее ниже.

Для дальнейшей разработки дизайна был выбран вариант с лучшим результатом после тестирования в лаборатории, где:

  • Наверху расположен навигационный блок с меню, геолокацией и профилем;
  • Поиск выше Почты, а Погода рядом с Новостями;
  • Меньше акцентного цвета (синими остались только логотип и Поиск).

Финальные штрихи


Мы определились со структурой, теперь осталось не менее важное визуальная часть.

У нас было несколько вариантов с разными формами и деталями. В итоге страница стала чистой: белого цвета с грамотно забрендированными ключевыми блоками. Фирменный цвет органично выделял Поиск, Почту и Новости. Строку Поиска сделали закругленной, чтобы она сильнее выделялась и не сливалась с виджетами ниже. Погоду и котировки разделили горизонтальные блоки более адаптивны и позволяют добавлять новые элементы.


Добавление виджетов

Теперь можно добавить несколько продуктов рядом с виджетом Почты и при этом ничего не сломать. В других вариантах это сделать не получиться из-за двойной карусели. По итогу можно сравнить, как было и как стало.


Сравнение старого и нового дизайна мобильной версии главной страницы Mail.ru

Как новая главная живет и процветает


Мы всегда раскатываем обновление постепенно, чтобы не сломать привычные сценарии пользователей. Пользователи положительно воспринимали новый дизайн, что подтвердил рост конверсии и переходов, говорит Вячеслав Яшков.



В результате мы заметили такие изменения:

  • +12% к переходам на медиапроекты, включая погоду и ковид;
  • +4% к переходам в Поиск;
  • +5% к переходам в Почту.

На данный момент мы активно работаем над персонализацией страницы, чтобы давать только полезную и актуальную информацию. Для пользователей экосистемы интеграция будет намного глубже.

Состав творческой группы:

  • Алена Китабова менеджер продукта.
  • Вячеслав Яшков руководитель команды дизайна Search & AI.
  • Елена Джуга дизайнер Search & AI.
  • Игорь Фролов руководитель группы frontend-разработки главной страницы и портальной навигации.
  • Владимир Францкевич программист группы frontend-разработки главной.
  • Денис Стасьев младший программист группы frontend-разработки главной.
  • Александр Буки программист группы frontend-разработки главной.
  • Анастасия Краснова ведущий инженер по тестированию.
Подробнее..

Как подобрать дизайнера для проекта?

05.06.2021 22:17:23 | Автор: admin

Если вы не хотите, чтобы ваш проект закончился на этапе разработки дизайна, или пользователи не убежали к конкурентам от увиденного - дизайнера нужно выбрать с умом, о чем я расскажу в этом материале.

Я постаралась систематизировать в этой статье свой опыт подбора множества дизайнеров на проекты самой различной сложности: от пакета баннеров, лэндинга до интерфейса No-code платформы без ТЗ. Материал будет полезен тем, кто впервые подбирает дизайнера на проект или получает дизайн не того качества, которого хотелось бы.

Поймите - кто конкретно вам нужен

Соревнование / Irina SalvartСоревнование / Irina Salvart

Дизайнеры, как и программисты все - разные. Как 1С-программист не напишет вам CMS на Python, так и дизайнер лэндингов не сделает прототип CRM, которым будет удобно пользоваться.

Запомним следующее:

  • UX дизайнер/UX инженер/UX аналитик: занимаются разбором требований, пишут ТЗ, создают CJM и, иногда, прототипы.

  • UI дизайнер: создает дизайн на базе прототипа, ТЗ, CJM и прочей информации. Часто заказчики поручают разработку сложных продуктов с нуля UI дизайнеру, и это самые большие грабли, которые только можно представить.

  • У дизайнера часто есть специализация. Мой коллега, который делает только интернет-магазины, прокачал себя в этом настолько, что конверсия его работ высока в любой тематике, за которую он бы ни взялся - практически без предварительного анализа. Однако, графический дизайн простой презентации способен отнять у него массу времени и энергозатрат.

В итоге, если вам нужен простой лэндинг - для него, как правило, хватит и UI дизайнера с ТЗ в зубах. Если нужен прототип CRM, упаковка стартапа - ищем жесткого аналитика, UX инженера с опытом разработки подобных решений.

Для средних, крупных проектов стоит присмотреться к студии, у которой в портфолио есть схожие проекты. Не стоит думать, что один человек способен совмещать в себе 5 профессий, при этом - не выгорать, оставаться психически здоровым долгое время.

Картину человек и дирижабль в одном лице я видела несколько раз, однако такие персонажи часто имеют свойство раз в полгода залетать в лечебные учреждения о желтых стенах или сидеть на препаратах, убивающих работоспособность и кое-что ещё.

Внимательно изучите портфолио дизайнера

Наброски / Irina SalvartНаброски / Irina Salvart

Ниже описаны общие рекомендации, которые поштучно и в некоторых случаях - могут не работать. Однако, если вы встречаете в работах дизайнера сразу несколько ошибок - скорее всего, лучше отказаться от сотрудничества.

Насколько работы похожи? Не раз видела портфолио дизайнеров, где 3-5-7 магазинов подряд являются просто перекрашенными версиями друг друга. С таким дизайнером новую кашу не сваришь.

Есть ли работы, схожие по направленности с вашей? Планируете делать магазин? Не поручайте его дизайнеру, у которого 10 баннеров, 3 лэндинга и 1 сайт услуг. И не верьте тому, кто скажет разберусь. Интернет-магазины подразумевают множество специфики, которую нужно сначала понять, прожить, выстрадать, а потом уже применять.

Какие используются шрифты? Часто начинающие дизайнеры грешат тем, что выбирают или неудачные, нечитаемые шрифты, от которых режет глаз, или просто вставляют стандарт в виде Arial по всем макетам. И то, и другое - повод отказать.

Есть ли работы, созданные для крупных компаний? Если у дизайнера есть опыт работы, скажем, с одним из крупных банков России - значит, как минимум, он стрессоустойчив. Если эти работы не выглядят как кусок понятно чего - значит, еще и хитёр, раз смог сделать что-то хорошее в условиях постоянно меняющихся требований и множества стейкхолдеров. В общем, несколько крупных компаний, доверившихся этому дизайнеру, вряд ли сильно ошиблись все сразу.

Скученность элементов или, наоборот, слишком много воздуха. Если вы смотрите на экран и не понимаете, куда смотреть, потому что за внимание спорят много блоков с информацией, или разные цвета вас отвлекают - этого дизайнера следует избегать. То же и с воздухом: одна строчка текста на экране плюс картинка где-нибудь в уголке - повод убедиться в адекватности дизайнера и посмотреть на другие работы.

Как с адаптивностью работ? Удивительно, но в 2к21 некоторые дизайнеры делают мобильные версии по остаточному принципу, хотя мобайл - это отдельная и сложная разработка. Посмотрите, делает ли дизайнер мобильные версии своих сайтов, насколько они удобны в использовании, не грешат ли они слишком малым/слишком большим количеством информации на экран. Если мобильных версий нет вовсе - право слово, не стоит.

Что с цветами? Если в проекте больше 3-4 цветов, или цвета спорят за внимание - в 99% случаев перед вами колхоз. Также следует обратить внимание на то, выделены ли CTA элементы (например, кнопки Купить, Заказать, Перезвоните мне) отдельным, контрастным цветом? Если да - это хороший знак. Планируя проект на большую аудиторию - помните, что далеко не все люди умеют правильно различать цвета, и дизайнер с соответствующим опытом будет очень полезен в таком деле.

Я отбираю дизайнеров по большему количеству критериев, однако выше описан тот шортлист, с которого полезно начать. Если у вас появится желание разобраться в дизайне подробнее - рекомендую начать с изучения базовых правил UI/UX дизайна и далее, в их свете, рассматривать конечные работы дизайнеров.

Попросите верстальщика посмотреть один из проектов дизайнера

Ты и твой парень-геймер / Irina SalvartТы и твой парень-геймер / Irina Salvart

Допустим, дизайнер прошел проверку по качеству работ и сейчас вы хотите понять - насколько быстро ваш верстальщик справится с выполнением проекта. Просто запросите у дизайнера доступ к Figma/PSD любого предыдущего большого проекта. Если откажется - это уже тревожный звоночек.

В готовом дизайне можно понять, насколько дизайнер позаботился о верстальщике, соблюдает ли он сетку и адекватные требования к макету. Незаконченный с точки зрения технических требований дизайн может увеличить срок верстки, разработки на несколько недель.

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

Не стесняйтесь спрашивать рекомендации

Всегда за / Irina SalvartВсегда за / Irina Salvart

Конечно, если вам нужны баннеры или обложка для социальной сети - в рекомендациях нет никакого смысла. Однако, если вы планируете разработку сайта или корпоративного решения за сотни тысяч рублей - нет ничего зазорного в том, чтобы спросить рекомендации, телефоны, мессенджеры предыдущих заказчиков. У опытных специалистов, которые работают за адекватный бюджет (1500-4000р/час) и достаточно давно, с этим обычно не бывает проблем.

Как минимум, несколько раз я натыкалась на агрессию со стороны исполнителя, когда спрашивала о рекомендациях. Каждый раз дополнительное изучение этой персоны и опрос предыдущих заказчиков давали мне понимание, что работа с ним завела бы проект в трясину эмоций и недопонимания.

Адекватный дизайнер даже с не очень адекватным заказчиком постарается расстаться так, что о нем в профессиональном плане нечего будет сказать кроме не сложилось. Если дизайнер ведется на эмоции или провоцирует их сам - вы не будете решать задачи бизнеса. Лучше просто запомнить: на фрилансе (речь о российских фриланс-площадках) много токсичных людей, которые находятся там, в том числе, потому, что удаленно мало кто видит их токсичность, и ваша задача - таких людей к проекту не допустить.

P.S. Если на той площадке, где вы нашли дизайнера, у него нет отзывов, спросите где они есть. Если их нет вообще нигде - лучше откажитесь. И помните что отзывы - не равно живые рекомендации.

Попросите показать готовые сайты

История успеха / Irina SalvartИстория успеха / Irina Salvart

Да, UI дизайнер рисует картинки. Да, он не отвечает на 100% за конечный результат в виде сайта. Однако, спустя много лет работы дизайнером, просьба показать готовые сайты мне не кажется такой уж неадекватной.

Дело в том, что если дизайнер качественно сдал макеты, подготовил ТЗ для верстальщика и базово протестировал результат на своих устройствах - сайт не будет выглядеть как то, что стыдно показать. Наличие хороших сайтов по ссылкам часто значит, что дизайнеру важно то, что он делает, и он старается помочь заказчику, а не просто поменять деньги на время.

Предложите заключить договор или безопасную сделку

Когда заказчик предлагает мне заключить договор, единственное что я спрашиваю - оформим на самозанятого, ИП или ООО? Предполагаю, ООО есть далеко не у всех, а вот оформить самозанятого можно за 5 минут. Наличие статуса или ИП у дизайнера свидетельствует о том, что он серьезно относится к своей работе. Также, у ответственного дизайнера всегда есть рамочный бриф, договор, который он готов прислать по запросу.

Если дизайнер наотрез отказывается оформлять безопасную сделку, мотивируя тем что решения всегда принимают в пользу заказчика, и договор, потому что морока с документами - морока чаще всего будет с ним.

К слову, о безопасной сделке. Конечно, это хорошее решение для некоторых случаев, однако придется положиться на модерацию площадки. Ввиду специфичности услуг дизайна, я стараюсь заключать свой договор, в котором прописано количество концепций, итераций правок и другие особенности, что и рекомендую делать вам.

Оцените личное общение

Дизайнер из 90-х / Irina SalvartДизайнер из 90-х / Irina Salvart
  • Насколько внимателен дизайнер? Например, вы задаете 2 вопроса в одном сообщении. Если вам отвечают на один, причем такое повторяется не раз - думайте сразу о том количестве правок, которое будете писать, и сколько раз будете просить их исправить.

  • Не боится ли он задавать вопросы, не строит ли из себя мачо, говоря что все понятно? Чем сложнее проект - тем больше вопросов заказчику я задаю, чтобы убедиться, правильно ли я его поняла. Неправильно понятое ТЗ = реальный шанс на то, что половину проекта придется переделывать.

  • Предложил ли дизайнер заполнить бриф, передать ему подробности проекта? Если брифа нет, как и других документов - один тревожный звоночек у вас есть.

  • Насколько грамотно и адекватно он общается? Если со второго сообщения в вас тыкают и говорят на сленге - стоит задуматься.

Работайте по адекватным ценам и соблюдайте договоренности

С моей точки зрения, в ценовой категории 200-1000 рублей в час непрофессиональных и откровенно странных дизайнеров гораздо больше, чем в категории 1500-2500 рублей в час. В первом случае, вы можете делать проект за 100.000 рублей 3 месяца, а во втором за те же деньги проект будет готов через 2 недели. В общем, попытка сэкономить часто будет стоить долгих поисков, большей вероятности возможных проблем, обильного списка правок и увеличения сроков.

И наконец, очевидное: соблюдайте договоренности и не заваливайте дизайнера десятками далеких от дизайна вопросов. Лучше изучить его анкету, работы, обсудить с понравившимся кандидатом 30 минут по Zoom и принять решение: работать или нет.Для найма на постоянную основу, критерии, конечно, другие, однако никто не мешает попробовать сделать с дизайнером 1-3 проекта, а затем, рассмотреть в качестве постоянного сотрудника.

Буду рада услышать о вашем опыте подбора дизайнера на проект!

Подробнее..

Перевод Как эти забавные картинки незаметно захватили сферу маркетинга

15.06.2021 12:07:46 | Автор: admin

Рассказ об истории вездесущих иллюстраций в стиле корпоративный мемфис и о том, почему они теперь буквально на каждом веб-сайте.

Плоские человеческие фигурки с изогнутыми руками и ногами, одежда ярких цветов, черты лица не более выразительны, чем силуэт, а если и есть какое-то выражение, то это обязательно улыбка.

Такой стиль иллюстраций называется корпоративный мемфис.

В последние несколько лет он незаметно захватил сферу маркетингового контента и дня не проходит, чтобы я не наткнулся на эти радостные фигурки в Интернете.

Похоже, это повсеместный тренд, от которого никуда не деться: жертвой этих причудливых картинок становятся и стартапы, и крупные технологические компании.

Как так получилось? И какое значение этот стиль имеет в сфере маркетинга?

Давайте разберемся.

Откуда название корпоративный мемфис?

Название кажется странным, но если разобраться в происхождении, то всё становится на свои места.

Слово мемфис относится к коллективу итальянских дизайнеров Мемфисская группа, который был основан в 1980 г. в Милане. Особенностью их стиля была некоторая игрушечность в сочетании с простыми формами и яркими цветами.

Со временем всё больше компаний начинали внедрять черты такого дизайна в собственные иллюстрации.

Получившийся в итоге стиль назвали корпоративным мемфисом.

Дизайнер Клэр Эванс собрала примеры этого тренда в ее коллекции вирусное проникновение этого стиля становится очевидным. Подобно воде, просачивающейся сквозь почву, он нашел отражение в контенте множества технологических компаний, включая Slack, Markup и Google.

В итоге теперь уже сложно различить компании по визуальному стилю взгляните сами.

Да, эти иллюстрации с разных сайтов: скриншоты из Slack, Markup и Google Покупок.Да, эти иллюстрации с разных сайтов: скриншоты из Slack, Markup и Google Покупок.

С историей появления и названием понятно попробуем разобраться, почему корпоративный мемфис завоевал такую популярность. Я выделяю четыре вероятных причины.

1. Смерть скевоморфизма

Помните старые 3D-иллюстрации на айфонах? Это скевоморфизм дизайнерский стиль, при котором изображение элементов интерфейса имитирует реальные аналоги.

С тех пор, как Apple перешла на iOS 7, всё больше компаний меняют свой визуальный стиль, отдавая предпочтение простым, упрощенным изображениям. Причина банальная: мы уже привыкли к цифровым приложениям и сенсорным дисплеям, поэтому нам больше не нужна имитация аналогов из реальной жизни. Кроме того, чем проще дизайн, тем быстрее такой контент потребляется а мы пропускаем через себя огромное его количество.

Так что покойся с миром, скевоморфизм.

Современный корпоративный стиль плоский и минималистичный. Поэтому иллюстрации в маркетинговых материалах тоже должны быть такими. А что может лучше подойти к упрощенным, приятным глазу логотипам, чем красочные мультики?

Корпоративный мемфис недостающий элемент мозаики плоского фирменного стиля.

2. Взаимозаменяемые цвета

Еще одна причина взлета корпоративного мемфиса универсальность цветовой гаммы: это позволяет компаниям внедрять корпоративный стиль во все визуальные материалы. Например, вот так Ютьюб берет красный и белый из своего плоского логотипа и переносит их в иллюстрацию.

Скриншот YouTube Скриншот YouTube

Взаимозаменяемость цветов также дает компании возможность представлять себя настолько разнообразной в этнокультурном отношении, насколько нужно. Это позволяет избежать проблемы недостатка разнообразия, характерной для стоковых фото.

Компании наконец-то могут легко изображать условных людей любого происхождения и этноса.

3. Простой, масштабируемый дизайн

Еще один фактор популярности корпоративного мемфиса простота создания иллюстраций в этом стиле.

Имея под руками тот же Adobe Illustrator, можно создавать векторную графику любых форм и цветов, и масштабируемость одно из многих ее преимуществ: размер изображений можно изменять, не жертвуя разрешающей способностью. Масштабируемость изображений стала очень важным компонентом для технологических компаний, поскольку им необходимо отображать контент на самых разных устройствах а обычные стоковые фотографии, опять же, не всегда дают такую возможность.

Для создания векторных изображений не требуется глубоких знаний: чтобы рисовать такие картинки, необязательно быть опытным дизайнером.

Мало того их даже не нужно рисовать: есть тысячи шаблонов, с помощью которых можно создавать любые иллюстрации, какие только нужно.

Теперь даже человек, невероятно далекий от дизайна, может наклепать кучу иллюстраций в стиле корпоративный мемфис быстрее, чем Усэйн Болт пробежит стометровку. Да, это обесценивает труд художников но одновременно расширяет возможности стартапов и одиночек.

Например, Canva одна из множества платформ, предлагающих готовые элементы оформления. Среди других ресурсов FreePik, UnDraw, векторная библиотека Adobe, Humaaans и т. д.

4. Радость на лице радость в жизни?

Пожалуй, самая большая притягательность корпоративного мемфиса солнечное настроение этих иллюстраций.

Радостный, дружелюбный вид фигурок возвращает нас в детство, дает ощущение уверенности и защищенности. С помощью различных подходов компании изображают и упрощают всевозможные ситуации и проблемы.

И это работает.

Когда я вижу очередную такую иллюстрацию, я чувствую, что обо мне заботятся. Мне кажется, что всё будет хорошо. Что мир не такой сложный, как может показаться.

И что, это всё? Это и есть Корпоративный мемфис? Просто яркие цвета, культурное разнообразие и радостное настроение?

Внешность может быть обманчива

Мы рассмотрели множество преимуществ корпоративного мемфиса, но за улыбками и солнечной атмосферой кроется кое-что еще. Давайте посмотрим, какие опасности стоят за этим стилем и лишь потом сделаем вывод, стоит ли его использовать.

Ненастоящее этнокультурное разнообразие

Эти иллюстрации слишком легко позволяют сделать вид, будто в компании царит половое, этническое, культурное и т. д. разнообразие, что, однако может совершенно не отражать реальное положение дел. Причудливые картинки не позволяют увидеть, действительно ли компания нанимает сотрудников из различных социальных групп (в том числе из недостаточно представленных). А еще хуже, что с помощью иллюстраций компания может представить сколь угодно широкое разнообразие которого в реальности не будет.

Простота для ленивых

Для создания этих мультяшных фигурок есть так много шаблонов, что их может делать каждый. Стартапам и небольшим компаниям это помогает не отставать от технологических гигантов. Но это же приводит к однообразию корпоративного дизайна, в котором не остается места уникальности.

Бездумное счастье

Улыбающиеся лица с непропорциональными частями тела создают впечатление, будто мир проще, чем на самом деле. Компании сознательно используют это, чтобы представить себя дружелюбнее, чем они есть в реальности. И мы начинаем верить, что техногиганты делают мир лучше но нельзя забывать, что почти у всех них есть темная сторона: например, такие компании, как Google, собирают пугающее количество данных о нас.

Заключение

Корпоративный мемфис это палка о двух концах.

С одной стороны, это репрезентативный, простой и дружелюбный визуальный стиль. Создавать такие картинки может каждый что очень помогает стартапам и независимым авторам.

Но нельзя забывать и о том, что такой дизайн может легко скрывать актуальные проблемы, заставлять нас думать, что мир лучше, чем есть на самом деле.

Если вы хотите использовать корпоративный мемфис для себя, я не буду вас винить: это прекрасный стиль, он всем нравится. Но спросите себя: может, есть другой, более индивидуальный и творческий подход? отражает ли этот стиль суть вашей работы? не чрезмерно ли вы упрощаете то, о чем говорите?

И если увидите маркетинговые материалы в стиле корпоративного мемфиса (что неизбежно), остановитесь на мгновение, задумайтесь, присмотритесь и оцените, достаточно ли правдиво эти иллюстрации воплощают компанию?


О переводчике

Alconost занимаетсялокализацией игр,приложений и сайтовна 70 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.

Мы также делаемрекламные и обучающие видеоролики для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.

Подробнее..

Нестандартные шрифты как подключить и оптимизировать

15.04.2021 10:21:55 | Автор: admin

Текст основная часть контента на большинстве сайтов, и важно грамотно подходить к его отрисовке. В этой статье мы разберём базовые моменты, касающиеся подключения и оптимизации шрифтов.

Сразу стоит отметить, что самый простой вариант вообще не подключать сторонние шрифты и пользоваться стандартными, которые предустановлены в большинстве операционных систем. Это хорошо знакомые Arial, Times New Roman и так далее эти шрифты называются веб-безопасными, достаточно просто указать название одного из таких шрифтов в коде, и всё будет работать.

Но чаще всего дизайн макета не позволяет обойтись веб-безопасным шрифтом, а требует использовать какой-то нестандартный. В этом случае при загрузке страницы файл со шрифтом нужно подгружать с сервера по той же схеме, что и остальные ресурсы CSS-файлы, изображения и так далее. Он может весить довольно много, именно поэтому для быстрой загрузки страницы выгоднее сначала рассмотреть возможность использования стандартных шрифтов. Но даже с нестандартными шрифтами можно избежать большинства проблем, если уделить внимание оптимизации.

Выбираем формат шрифта

Все слышали про TTF и OTF. Но это форматы, которые предоставляются с минимальным сжатием или совсем без него. Их стоит использовать только в том случае, если нужна поддержка очень старых браузеров.

Во всех остальных ситуациях можно выбрать WOFF и WOFF2 форматы, которые отличаются высокой степенью сжатия. WOFF2 вообще можно считать лучшим из существующих. Тем не менее, поддержка WOFF2 хотя и очень хорошая, но пока не абсолютная, поэтому в качестве подстраховки для не самых современных браузеров стоит использовать WOFF.

Подключение шрифтов с помощью Google Fonts

Есть простой и удобный способ подключить нестандартный шрифт использовать Google Fonts. Это бесплатный сервис, с помощью которого можно подключать шрифты, но не хранить их на своём сервере. Чтобы им воспользоваться, необходимо выбрать шрифт и добавить одно или несколько нужных начертаний, а затем вставить в <head> ссылку, которую сгенерирует Google Fonts во вкладке Embed.

Этого достаточно, чтобы шрифт подключился. Теперь его можно использовать в свойстве font-family без каких-либо дополнительных действий.

body {font-family: "Roboto", "Arial", sans-serif;}

Стоит отметить, что после основного шрифта важно указать веб-безопасный. В случае, если нестандартный шрифт не загрузится, браузер воспользуется альтернативным. Его нужно подобрать максимально похожим на основной шрифт.

Плюсы этого способа простота использования и всегда актуальные версии шрифтов, Google Fonts их часто обновляет. Но у него есть и минус запросы к сторонним серверам могут негативно повлиять на скорость загрузки страницы. Если выбираете этот способ, стоит обратить внимание на оптимизацию.

Подключение шрифтов с помощью правила @font-face

Есть альтернативный способ, при котором файлы со шрифтами хранятся вместе с остальными ресурсами сайта. Для них принято заводить отдельную директорию в корне проекта например, fonts. В неё следует поместить файлы для каждого начертания в нужных форматах в большинстве случаев, если не требуется поддержка старых браузеров, подойдут .woff и .woff2, о которых мы говорили ранее. Шрифты можно скачать на различных ресурсах. При этом всегда нужно обращать внимание на лицензию некоторые шрифты могут быть недоступны для коммерческого использования.

После того, как шрифты добавлены в проект, их нужно подключить в CSS-файле. Для этого используется правило @font-face. В самом базовом варианте оно будет включать:

  1. Название шрифта, которое затем нужно использовать, чтобы задать элементам подключённый шрифт.

  2. Адрес файла со шрифтом, который нужно подключить, и его формат. Если адресов несколько, их можно указать через запятую. В этом случае важен порядок браузер будет последовательно пытаться подключить файлы. Первым должен быть самый подходящий формат, а далее запасные варианты. Также с помощью функции local можно добавить возможность перед загрузкой шрифта с сервера проверить, установлен ли он на компьютере пользователя. Если да, запроса к серверу за шрифтом не будет при рендеринге используется локальная версия. Но у этого способа есть минус шрифт на компьютере пользователя может быть устаревшим, и тогда страница отобразится не совсем так, как было задумано.

  3. Начертания: жирное, курсивное и так далее. Для каждого начертания нужно отдельное правило @font-face.

Базовый вариант правила:

@font-face {font-family: "Roboto";font-style: normal;font-weight: 400;/* Браузер сначала попробует найти шрифт локально */src: local("Roboto"),/* Если не получилось, загрузит woff2 */url("/fonts/roboto.woff2") format("woff2"),/* Если браузер не поддерживает woff2, загрузит woff */url("/fonts/roboto.woff") format("woff");}/* Теперь можно использовать шрифт */body {font-family: "Roboto", "Arial", sans-serif;}

Для улучшения производительности правило @font-face лучше всего прописывать в самом начале CSS-файла. Так браузер сможет раньше начать обработку шрифта.

Оптимизация

Выбор современного формата шрифта, который обладает хорошей степенью сжатия это только первый шаг к оптимизации. Можно сделать гораздо больше, чтобы увеличить скорость загрузки страницы и сделать пользовательский опыт при взаимодействии с интерфейсом приятнее.

FOIT, FOUT и FOFT

Пока шрифт загружается, при рендеринге можно наблюдать разное поведение текста.

FOIT (Flash of Invisible Text) с англ. мелькание невидимого текста. При таком поведении, пока шрифт не загрузится, текст не отображается и появляется только после загрузки шрифта. Значительная проблема во время загрузки нет доступа к текстовому контенту.

FOUT (Flash of Unstyled Text) с англ. мелькание неоформленного текста. Во время загрузки используется шрифт, заданный по умолчанию (системный, например), а после загрузки страница перерисовывается с использованием загрузившегося шрифта. Эта перерисовка довольно заметна и может быть нежелательна.

FOFT (Flash of Faux Text) с англ. мелькание синтезированного текста. Это поведение можно наблюдать в промежутке, когда основное начертание уже загрузилось, а дополнительные (жирное, курсивное и так далее) нет. Браузер имитирует нужное начертание до загрузки настоящей версии. В этом случае страница может перерисовываться несколько раз по мере загрузки начертаний.

В разных браузерах логика рендеринга текста во время загрузки шрифта отличается. Например, Chrome и Firefox в течение трёх секунд не отрисовывают ничего, затем используют веб-безопасный шрифт, а после окончания загрузки текст перерисовывается. IE поступает похоже, но при этом не ждёт три секунды. Подобное поведение в разных браузерах можно унифицировать, используя свойство fontdisplay.

Свойство font-display

У свойства есть несколько значений, которые определяют поведение текста во время загрузки шрифта:

  • auto поведение по умолчанию, зависит от браузера.

  • block текст не отображается в течение короткого периода (3 секунды), затем отрисовывается запасной шрифт, если основной ещё не загрузился. Как только загрузка завершается, текст перерисовывается снова.

  • swap сразу же отрисовывается запасной шрифт, после загрузки шрифта повторный рендеринг.

  • fallback в течение очень короткого периода (100 миллисекунд) не отображается ничего, затем браузер использует запасной шрифт и ждёт 3 секунды если шрифт всё ещё не загрузился, остаётся запасной шрифт. Далее не важно, загрузился шрифт или нет, замена не произойдёт. Если шрифт загрузится, то он применится только при обновлении страницы.

  • optional текст не отображается в течение 100 миллисекунд, а затем отрисовывается запасным шрифтом. Даже если шрифт загрузится после этого, замена произойдёт только при обновлении страницы.

Оптимальное значение swap, его можно использовать в большинстве случаев, оно удобно для пользователей. При подключении шрифта с помощью Google Fonts это значение установлено по умолчанию. Если же есть необходимость избежать мелькания текста (например, для вдумчивого чтения), подойдёт optional.

Предзагрузка шрифтов

Ещё один способ оптимизации предварительная загрузка шрифтов. С её помощью можно изменить обычную приоритизацию загрузки ресурсов, тем самым сказав браузеру, что важно загрузить шрифт в первую очередь.

Стоит учесть, что браузер загрузит шрифт в любом случае даже если он не используется на странице. И, обладая высоким приоритетом, эта загрузка может блокировать загрузку других ресурсов, поэтому нужно грамотно выбирать, что именно предзагружать. Например, если на странице используются три разных шрифта, стоит предзагрузить только основной шрифт без дополнительных начертаний.

Для того, чтобы предзагрузка сработала, нужно поместить в <head> ссылку на шрифт и задать атрибуту rel значение preload:

<link rel="preload" href="http://personeltest.ru/aways/habr.com/fonts/roboto.woff2" as="font">

Также необходимо добавить тип ресурса, в данном случае font. Предзагружать можно и другие ресурсы CSS-файлы, изображения и так далее.

Уменьшение количества глифов шрифта

По умолчанию шрифт может содержать глифы (буквы, символы) разных языков и просто редко используемые. С помощью свойства unicode-range можно установить диапазон нужных символов в системе Unicode, тогда браузер будет подгружать сабсет (подмножество) шрифта только в тот момент, когда на странице появится символ из этого диапазона. Предварительно нужно подготовить файлы шрифтов, разбив их на группы.

Например, можно отдельно подключить латиницу и кириллицу, если на сайте представлены версии на двух языках. И с помощью unicode-range браузер поймёт, какой сабсет нужен для конкретной страницы, и загрузит только его. Такой файл будет иметь меньший вес и ускорит загрузку страницы.

Также можно проанализировать, какие конкретно глифы используются на сайте и создать кастомный сабсет исключительно с ними. Для этого есть специальные инструменты.

Google Fonts по умолчанию использует сабсеты. Это можно увидеть, открыв CSS-файл, который подключается в <head> при использовании сервиса. Для каждого языка есть отдельный сабсет. Пример для латиницы и кириллицы:

/* latin */@font-face {font-family: "Roboto";font-style: normal;font-weight: 400;font-display: swap;src: local("Roboto"),local("Roboto-Regular"),url(http://personeltest.ru/aways/fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxK.woff2)format("woff2");unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,U+2212, U+2215, U+FEFF, U+FFFD;}/* cyrillic */@font-face {font-family: "Roboto";font-style: normal;font-weight: 400;font-display: swap;src: local("Roboto"),local("Roboto-Regular"),url(http://personeltest.ru/aways/fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu5mxKOzY.woff2)format("woff2");unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;}

В статье разобраны только базовые способы оптимизации шрифтов. Но даже их достаточно, чтобы улучшить пользовательский опыт и значительно уменьшить вес файлов шрифтов, ускорив тем самым загрузку страницы.

Полезности

Подробнее..

Топ-5 софт-навыков дизайнера в банке

04.06.2021 14:18:19 | Автор: admin

Соавтор:Кузнецова Юлия Андреевна - UX-писатель Экосистемы РСХБ

Каким должен быть дизайнер в банке, чтобы и продукт хороший создавал, и коллеги не жаловались. Смотрим через призму софт-навыков вместе с UX-дизайнерами РСХБ.

#1 Коммуникабельность: не просто коллега человек

Дизайнер отличная профессия для интровертов. Рисуешь интерфейсы, слушаешь музыку, ни с кем не общаешься На самом деле, нет!

Работая в банке, ты участвуешь в большом количестве созвонов, слушаешь коллег, предлагаешь свои идеи. Споришь. Много споришь. Убеждаешь. Идешь на компромисс. Вместе с тобой над продуктом работают много других сотрудников продакт-менеджеры, аналитики, разрабы, редакторы, юристы ты должен уметь услышать каждого и найти общий язык.

Общаясь с разными специалистами, ты лучше понимаешь, как устроена работа на проекте и начинаешь понимать, что из твоих решений сработает и поможет банковским клиентам, а что вряд ли будет реализовано и сделано разве что покрасоваться на Dribbble.

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

#2 Презентация: готов объяснить свою работу

Вместе с другими командами дизайнеры преследуют общую цель сделать продукт самым успешным на рынке. При этом у каждой команды свое мнение и приоритеты. Что кажется важным для дизайнера, не так важно для разработчика, редактора или бизнеса.

Крутой дизайнер умеет переключить фокус с творческого и ранимого художника на хладнокровного адвоката. Если кто-то говорит: Это плохо сделано, это не значит, что ты плохой. Это значит, что коллега видит в данном решении слабые стороны. Продвинутый дизайнер отключает эмоции и включает голову. Объясняет и обосновывает свою позицию. Задаёт вопросы, внимательно слушает, делает все, чтобы добраться до истины и хорошего продукта.

Итог: Фильтруй плохой фидбек и умей доказать, какую ценность несет твое решение для пользователя и бизнеса, желательно предоставив проверенные факты и исследования.

#3 Аналитика: думает не только о красоте

Немного психолог, аналитик и исследователь банковский дизайнер работает не просто над сайтом с красивыми картиночками, он создает сложный финансовый продукт, в котором пользователь должен чувствовать, что его активы в безопасности.

Хороший дизайнер постоянно анализирует, как пользователи будут взаимодействовать с интерфейсом, удобно ли ему переводить деньги другу, перечислять зарплату сотрудникам или подавать заявку на кредит.

С одной стороны, ты должен на интуитивном уровне понимать психологию взаимодействия с интерфейсом. А с другой всегда остаешься скептиком и тестировать свои гипотезы. Порой пользователи воспринимают ту или иную функцию абсолютно непредсказуемо и не понимают твоей задумки. Одна только фраза Мне нравится. Думаю пользователям понравится тоже не поможет. Нужна аналитика. Много аналитики.

Итог: относись к своим решениям непредвзято. Любая хорошая идея может оказаться плохой во время теста. Исследования помогут тебе делать качественный продукт и соответственно лучше понимать пользователей.

#4 Понимание бизнес-процесса: переводит с банковского языка на человеческий

Юный дизайнер: мастерски работает в Фигме, любит компоненты, боготворит филигранную верстку.

Продвинутый дизайнер: понимает, как устроен бизнес и финансы.

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

Знает о банке

Знает о пользователе

как устроены процессы внутри банка

над чем работает банк

какие боли клиентов решает

как себя позиционирует и каких принципов придерживается

как работают конкуренты

кто и зачем пользуется банковскими продуктами

с какими проблемами сталкивается

что делает, чтобы решить эти проблемы

Дизайнер понимает интересы обеих сторон и знает, одна маленькая ошибка может привести как к финансовым потерям, так и к потери доверия пользователей. Зная это, он скрупулезно изучает сферу, в которой крутится. Работая над банком для бизнеса, дизайнер сам попробует зарегистрировать ИП, а разрабатывая приложение для инвестиций собирает свой инвестиционный портфель.

Итог: Не зацикливайся только на дизайне. Понимай бизнес, чувствуй пользователей. И не придумывай излишнюю красоту, которая усложняет опыт.

#5 Любознательность: постоянно учится новому

Наши знания постоянно устаревают. Чтобы в один день не найти себя на обочине никому не нужного дизайна, крутой специалист должен постоянно учиться новому, следить за трендами, изучать новые законы, интересоваться смежными темами, узнавать больше о техническом процессе разработки продуктов, интересоваться актуальными технологиями, изучать работы коллег и конкурентов. Только так ты сможешь создать действительно трендовый, стильный и инновационный продукт.

Итог: Я знаю, что ничего не знаю. И в этом не стыдно признаваться, если каждый день пытаешься узнать еще больше.

Подробнее..

Веб на заре Рунета. Как создавали и где хостили сайты в 90-е

13.04.2021 14:10:30 | Автор: admin

Хоумпейдж мой, домашняя страница готова. Сайт я свой доделал, бабуля!

Удивительно, но я совершенно не помню день своего знакомства с интернетом. Это определенно был 1996 или 97-й год, но сам момент отчего-то не отложился в памяти: интернет вошел в жизнь нашего поколения исподволь, вытеснив из нее и BBS, и эхоконференции Фидонета. Поначалу мы отчаянно потребляли контент: серфинг по сети в середине 90-х напоминал путешествия Колумба в поисках неизведанного, и ежедневно приносил новые увлекательные открытия. Затем у многих тяга к творчеству брала верх, и они начинали робкие эксперименты по созданию собственных кошмарных домашних страничек. Меня тоже не минула чаша сия воспоминания о том, как это было, сейчас вызывают лишь ностальгическую улыбку.

Толковых книг на русском языке по синтаксису HTML и тем более по веб-дизайну в середине 90-х еще не издавали. По крайней мере, мои воспоминания о подобной литературе относятся скорее к началу нулевых тогда на волне популярности темы таких изданий вдруг стало неожиданно много. Приходилось действовать экспериментальным путем: веб-страница сохранялась на диске, открывалась в Notepad.exe, после чего в коде менялись значения атрибутов html-тегов, удалялись и добавлялись строчки, а изменения тут же отслеживались в окне браузера. Собственно, мои первые веб-страницы были по большому счету локализованными копиями зарубежных хоумпейджей, делать что-то по-настоящему свое я научился немного позже путем натурных экспериментов.


Типичный сайт середины 90-х. От такого дизайна в наши дни и вправду может стошнить

Отличительной особенностью сайтов того времени было повсеместное использование вырвиглазных фоновых картинок, которыми следовало обязательно замостить все пространство страницы сверху донизу. Поэтому крайне важно было добиться, чтобы небольшое изображение правильно стыковалось само с собой по горизонтали и вертикали. Кто-то использовал для этого Photoshop, позже появились и специальные утилиты для работы с фоновыми картинками вроде HarmsTile99, посредством которых удавалось соорудить почти идеальные фоны для сайта, потратив на это минимум усилий. Некоторые Web-мастера (именно так их тогда и называли латиницей и с заглавной буквы W) очень любили прикрутить к какой-нибудь странице MIDI-файл, который без объявления войны начинал воспроизводиться сразу в момент открытия сайта. Лично я за такое готов был пристукнуть их чем-нибудь тяжелым, поскольку в целях экономии пользовался преимущественно ночным dial-upом, и временами забывал выключить колонки.

Интернет тогда поступал населению преимущественно по модему, поэтому для ускорения загрузки станиц (и благодаря ограничениям хостинга того времени) картинки приходилось сжимать. Формат PNG тогда еще не был широко распространен (поначалу для его поддержки вроде бы даже требовались дополнительные браузерные плагины). Картинки на сайтах были представлены файлами GIF для кнопок, надписей, шапок, и, конечно же, анимации, и JPEG для всего остального. JPEG мы сжимали с помощью Jpeg Optimizator и Jpeg Cleaner for DOS, для второго формата широко использовался GifClean 32 под винду. Позже, уже ближе к нулевым, широкое распространение получила универсальная программа WebGraphics Optimizer: ты загружал в нее картинку, и тулза выдавала несколько вариантов сжатого изображения с различной степенью компрессии: оставалось только выбрать компромисс между подходящим размером файла и количеством грязи и артефактов. Опции Save for Web в Фотошопе (по крайней мере, в той версии, которой пользовался я) тогда еще не существовало, мы выживали, как могли. Не существовало и удобной функции нарезки картинки на куски-слайсы, с помощью которой можно было собрать целую мозаику из фрагментов изображения с разными гиперссылками. Картинки резали на части в программе Picture Dicer, пока браузеры не научились наконец нормально поддерживать html-тег . После чего об этом извращении с огромным облегчением забыли.


WebGraphics Optimizer тулза для сжатия картинок

Самым громким писком моды 90-х были, конечно, анимированные GIFы, которые собирались в программах вроде Gif Movie Gear и Ulead GIF Animator. На веб-страницах бегало, скакало и крутилось буквально все. Считалось очень правильным и важным распихать на сайте как можно больше анимированных кнопок, картинок, значков и иконок, так, чтобы у посетителя через пару минут начало рябить в глазах и возникали рвотные позывы. В 1997 году GIF-анимация обрела еще и практическое значение: в Рунете появилась первая баннерообменная сеть Reklama.ru, использовавшаяся для взаимного продвижения сайтов, но при этом забиравшая определенную часть показов под собственную монетизацию. Сеть накладывала очень жесткие ограничения не столько на содержание баннеров, сколько на объем файлов, поэтому отдельные кадры в формате GIF порой приходилось сначала сжимать сторонними компрессорами, а потом еще и оптимизировать в самом GIF Animatore, сокращая количество цветов в палитре, добавляя туда прозрачность и убирая лишние слои. Иногда на это уходило даже больше времени, чем на рисование самой рекламы.


В Ulead GIF Animator создавалась практически вся эта назойливая анимированная графика

Создатели веб-страниц конца 90-х сталкивались в основном с тремя серьезными проблемами. Первая кодировки кириллицы. Браузеры не всегда умели корректно распознавать ее в автоматическом режиме, потому порой приходилось готовить несколько версий сайта сначала в Windows-1251, после чего копии веб-страниц перегонялись в KOI-8, ISO-8859-5 и CP866 с помощью утилит вроде ConvertHTML или Coder. Затем варианты сайта в разных кодировках связывались гиперссылками. Обновление всего этого зоопарка веб-страниц выливалось потом в отдельную эпопею. Крупные конторы, имевшие возможность подкрутить конфигурацию сервера, могли настроить выдачу сайта в разных кодировках через разные http-порты, но у обычной массы веб-мастеров не было доступа даже к папке /cgi-bin/, не говоря уж о более сложных вещах. Потому проблема решалась такими вот кустарными методами и всевозможными подпорками из костылей.

Второй геморрой поддержка экранных разрешений. Чтобы ничего не разъезжалось и не расползалось на разных компьютерах, сайты того времени заверстывались в невидимую таблицу, ширина которой определялась наиболее распространенными значениями экранного разрешения. Свои первые сайты я верстал под 640х480, но вскоре самым популярным стандартом стал 800х600, реже встречались веб-страницы, оптимизированные под 1024х768. Сделаешь таблицу слишком узкой по краям экрана появятся неопрятные пустые поля, слишком широкой у страдальцев со старыми дисплеями вылезут в браузере полосы прокрутки. Споры о том, какое разрешение считать основным и какую ширину таблиц выбирать в качестве стандарта, не утихали очень долго и порой превращались в настоящие холивары. По крайней мере, до тех пор, пока наука не придумала резиновый адаптивный дизайн.



Типичный сайт с табличной версткой. Такая компоновка сайтов была популярна до начала 00-х.
Но самой большой головной болью были, пожалуй, попытки добиться одинакового отображения веб-страницы в Internet Explorer и Netscape Navigator. В ходе браузерных войн разработчики придумывали html-теги, которые нормально поддерживала только их программа, кроме того, Microsoft, по слухам, активно подкармливала консорциум W3C, чтобы легализовать собственные нововведения в стандарт HTML. Дабы не заморачиваться, многие веб-мастеры вешали на свои страницы дисклаймер из серии Этот сайт лучше просматривать в Microsoft Internet Explorer, и со спокойной совестью отправлялись пить пиво. Другие вроде меня стремились к совершенству, и долгими ночами, матюгаясь сквозь зубы, копались в HTML-коде: только наладишь выравнивание объектов в IE, как в Нетшкафе съезжает ширина боковых колонок навигации, починишь колонки пропадают горизонтальные линии, вернешь на место линии вокруг картинок откуда-то вылезли отвратные рамки. Еще, помнится, существовал национальный браузер Ариадна, которым даже пользовались примерно никто. К началу нулевых понемногу стала набирать популярность Opera, добавив веб-мастерам еще немного попоболи: теперь оптимизировать страницы приходилось аж под три разных браузера.

Мало создать кошмарную домашнюю страничку, ее еще нужно было где-то разместить. Профессиональный хостинг стоил дорого и не каждому был по карману, но многие провайдеры при покупке у них интернета бесплатно предоставляли юзеру до мегабайта дискового пространства. Подобные личные сайты обычно имели URL вида www.cityline.ru/~username. Такой вариант хостинга имел несколько серьезных недостатков. Во-первых, провайдеры обычно накладывали ограничения на содержание сайтов, допуская к размещению только персональные страницы и не разрешая публиковать коммерческие. Во-вторых, через пару дней после того, как ты переставал платить за интернет, страничка попросту уничтожалась и если на твоем компе не осталось резервной копии, восстановить ее было уже невозможно. В-третьих, ты оказывался фактически привязанным к этой конторе: перенести статический сайт на другой хост при смене провайдера не составляло особого труда, а вот адрес, зарегистрированный во всех интернет-каталогах, терялся навсегда вместе с рейтингом Ramblers Top 100 и прочими честно заработанными ачивками.


Интернет-провайдер всея Руси Cityline. Дизайн сайта студии Артемия Лебедева

Второй вариант бесплатный хостинг. В Рунете с 1996 года действовал портал Halyava.ru, где можно было без-воз-мез-дно, то есть даром, разместить домашнюю страничку общим объемом не более 512 килобайт. На вопрос, чем продиктовано столь жесткое ограничение, в FAQ хостера был опубликован исчерпывающий ответ:

А зачем Вам больше? Если Ваша страничка начинает весить больше 512 килобайт, возникает вопрос: зачем делать такую тяжелую графику?

От щедрот душевных компания предлагала для каждой такой странички адрес вида www.halyava.ru/ваше-имя (для серьезных людей в малиновых пиджаках, которым не нравится слово Халява, были доступны URL формата www.homepage.techno.ru/ваше-имя), а также обвешивала ее рекламой. Фактически, сайт пользователя отображался во встроенном фрейме, в верхней части которого хостер откручивал баннеры и размещал ссылку на собственный сервис. Примечательно, что у Halyava.ru поначалу отсутствовала возможность загрузки веб-страниц по FTP: вместо этого данные на сервер передавались по электронной почте, по ней же пользователю отправлялись инструкции. Помнится, у какого-то из хостеров использовался другой извращенный метод: нужно было скопировать HTML-код через буфер обмена в специальную форму, из которой по нажатию кнопки Submit генерировалась в папке на сервере веб-страница с заданным именем. Попутно HTML-код проверялся на предмет запрещенных тегов. Страница жила на Халяве два месяца с момента получения сервером последней команды от юзера, а затем бесследно исчезала. Естественно, такой бесплатный хостинг не подразумевал использования каких-либо скриптов: только статические веб-страницы, только хардкор! Но даже столь спартанские условия для 90-х считались более чем приемлемыми. Халява, сэр!


Халявный хостинг в 90-е предлагали не так уж и много провайдеров, один из самых известных GeoCities

Для тех, кто знал английский и не боялся общаться с техподдержкой на иностранном языке, был открыт весь мир: например, на сервере GeoCities бесплатно давали целых 2 мегабайта, а лично я пользовался услугами халявного хостинга на портале Tripod.com. Там тоже лепили на размещаемые сайты собственную рекламу, тоже допускали к публикации только статические веб-страницы, а адрес сайта имел вид www.tripod.com/~username. GeoCities предлагал в добавок к сайту еще и бесплатный почтовый ящик. Кроме того, для загрузки веб-страниц на сервер там предоставлялся нормальный FTP-доступ. Правда, регистрация нового сайта представляла собой не самый простой квест: сначала нужно было выбрать подходящую тематическую рубрику в каталоге, затем найти незанятое имя, и только потом тебя допускали в святая святых к заполнению анкеты для получения membership. Возможно, именно такая нетривиальная система и отпугивала наших соотечественников. Зато американцы, в отличие от местных хостеров, никак не ограничивали размещение на пользовательских веб-страничках сторонней рекламы. Благодаря участию в партнерских программах я, помнится, даже заработал целых 15 баксов, а потом долго бегал по российским банкам с присланным мне по почте бумажным чеком, пытаясь его обналичить.


Еще один рай для любителей халявы из 90-х Tripod

Вскоре в Рунете стали возникать и другие площадки для бесплатного размещения сайтов, у разработчиков появилась возможность регистрировать для них домены третьего уровня или создавать алиасы вроде site.da.ru. Но, тем не менее, запуск скриптов по-прежнему оставался недоступным большинству пользователей бесплатных тарифов. Самыми популярными веб-сервисами в то время были гостевые книги и чаты, а самым распространенным языком, на котором писались CGI-сценарии Perl. Конечно, можно было прикрутить к своему сайту и стороннюю гостевую книгу с чужой рекламой таких предложений в Рунете было навалом, но каждому, конечно, хотелось иметь собственный чатик вроде легендарной Кроватки, или уютную гостевушку, аккуратно вписанную в существующий дизайн.

Поскольку Perl в случае неправильной настройки сервера (а правильно его настраивать было дано далеко не всем) технически позволял выполнять команды операционной системы и получить доступ к файлам за пределами домашней папки пользователя, а скрипты создавали нагрузку на сервер, доступ к /cgi-bin/ простым смертным открывали далеко не всегда. Чаще всего бесплатному юзеру предлагалось написать админу хостинга, что за скрипт он желает запустить на сервере и на кой ему это понадобилось. Затем следовало отправить скрипт на рассмотрение, и только в случае одобрения админ выкладывал его на сайт и давал ему права на выполнение. Отладка сценариев на Perl превращалась при этом в сущую пытку, а задача поправить где-нибудь неправильно указанный путь или ошибку в имени переменной в mission impossible. Доступ к СУБД на бесплатных тарифах тоже, понятно, отсутствовал как явление, данные писали в текстовые файлы, которые использовались вместо базы данных. Архаика, но чатик на Perl и .TXT благополучно просуществовал на моем сайте, кажется, до 2002 года, когда был упразднен за ненадобностью. Скрипты мы писали сами, но можно было обойтись и готовыми вариантами огромный выбор самых разных сценариев на все случаи жизни можно было добыть в коллекциях вроде freeware.ru там имелся ну просто кладезь скриптов и полезного софта на все случаи жизни. Бесплатный хостинг с полноценным доступом к CGI стал широко доступен только в самом начале нулевых, коммерческие пользователи подобных проблем по понятным причинам не испытывали и до этого.


Freeware.ru месторождение софта и полезных скриптов

Настоящим откровением в конце 90-х для меня стал стандарт CSS, о котором я узнал от коллег. Оказывается, совершенно необязательно прописывать в каждом html-теге кучу атрибутов, а вместо этого можно собрать все стили в одном внешнем текстовом файле. Вторым грандиозным открытием стала технология Server Side Includes, позволившая экономить кучу времени на обновлении контента. С помощью SSI впервые сделалось возможным отделить дизайн от собственно содержимого сайта: веб-мастер мог распихать шапку, подвал, навигацию и контент по разным файлам, а потом динамически собирать их воедино прямо на сервере. Захотел отредактировать меню на всех страницах проекта достаточно внести правки только в один файлик. У удобство. До появления полноценных CMS оставался ровно один шаг.
Вместо них в начале нулевых жизнь веб-мастера заметно облегчали редакторы вроде HomeSite, Hot Metal Pro, Adobe Page Mill, Hotdog, Macromedia DreamWeaver, и конечно же, Microsoft FrontPage, который генерировал адские объемы мусорного кода, но очень уж полюбился мне за наглядность и простоту. Да, код веб-страниц после FrontPage приходилось чистить в Блокноте, но это было неотъемлемой частью рабочего процесса.


Очень много веб-страниц было сверстано в Microsoft FrontPage

В тот период запад переживал самый пик знаменитого пузыря доткомов, а в российском сегменте сети начался бурный рост новых проектов, часть которых впоследствии превратитесь в крупные интернет-компании с многомиллионной капитализацией. Но это было потом. Тогда же подавляющее большинство русскоязычных сайтов создавалось на голом энтузиазме и поддерживалось за счет финансовых ресурсов и личного времени самих разработчиков. Многим тогда справедливо казалось, что в Рунете денег нет. Я и пара моих приятелей подхалтуривали иным способом, а именно, делали сайты для американских заказчиков, в основном, для малого и сверхмалого бизнеса. В Штатах подобные услуги стоили тогда дорого, в России на порядок дешевле. Помню, как меня ввел в полнейший ступор вопрос от джентльмена из Техаса, сколько долларов стоит в России час работы веб-мастера. Да пёс его знает! В России конца 90-х обычно платили за завершенный проект, да и то не всегда. Некоторые студенты вообще трудились за пиво. Помню, в тот период мы сделали хоумпейдж для какой-то пекарни из Алабамы, для религиозной общины из Пенсильвании, для семейного бизнеса, предлагавшего трансферт туристов на минивене из аэропорта Ла-Гуардия, для небольшого косметического салона и частного мастера по очистке бассейнов из техасской глубинки, для магазина газонокосилок из городка, который я даже не смог отыскать на карте Совсем не миллионные стартапы, конечно, но какие-то деньги это приносило. Притом наша небольшая банда веб-мастеров не давала никакой рекламы: простого знания английского вполне хватало, чтобы заказы приходили один за другим посредством сарафанного радио.

Когда PHP окончательно вытеснил Perl с просторов интернета, веб-программист мог считаться настоящим мужчиной, только если он осилил три главных достижения в своей жизни: посадил печень, вырастил патлы и написал собственную CMS. Количество самописных движков с примерно одинаковым функционалом, напоминавших велосипеды с квадратными, треугольными, трапециевидными и даже выполненными в виде ленты мёбиуса колесами, быстро превысило все разумные пределы. Но к тому моменту я уже окончательно завязал с веб-дизайном и вся эта вакханалия благополучно прошла мимо меня. Тем более, к этому моменту интернет в целом обрел свой современный вид, окончательно коммерциализировался, и веб-разработкой стали заниматься профессионалы, освоившие поистине промышленные масштабы производства по промышленным же расценкам. А для меня веб-дизайн никогда не был основной профессией и главным источником дохода. Гораздо больше мне нравилось заниматься текстами.

Однако говорят, что бросить возиться с сайтами иногда даже сложнее, чем бросить курить. Временами я все еще делаю что-то на Joomla и WordPress для собственного удовольствия. Но всякий раз, открывая свои старые архивы, я с улыбкой вспоминаю те времена, когда мы писали сайты в Notepad.exe, вручную оптимизировали перед выкладкой каждую картинку, а главное учились методом проб и ошибок, без роликов на YouTube, онлайн-курсов и даже без специальной литературы. В нашем распоряжении не было такого количества общедоступных сервисов, начиная от движков на любой вкус до визуальных конструкторов, с помощью которых можно за пару минут набросать мышкой работоспособный лендинг, попивая кофе и поглядывая одним глазом в ТикТок. Да и Рунет был крошечным, как детская песочница во дворе, а его население как и население той песочницы более наивным, добродушным и открытым. Хорошие все-таки были времена.

Подробнее..

Перевод CSS работа с текстом на изображениях

15.04.2021 14:13:15 | Автор: admin

Вы можете встретить компонент пользовательского интерфейса, у которого есть текст над изображением. В некоторых случаях в зависимости от используемого изображения текст будет трудно прочитать. У этой проблемы есть несколько различных решений, таких как добавление градиента или затемнение изображения, наложение тени на текст и другие. Написать эту статью меня вдохновил твит от Адди Османи.


Здесь я рассмотрю различные подходы и решения этой проблемы, а также то, как передать пользовательский интерфейс фронтенд разработчику таким образом, чтобы гарантировать, что UI реализован в соответствии с макетом дизайна, поскольку некоторые детали в CSS можно легко упустить.

Вступление

Давайте посмотрим на нашу задачу. При разработке компонента с текстом над изображением мы должны позаботиться о том, чтобы текст было легко прочитать.

Слева без оверлея, справа с оверлеем.Слева без оверлея, справа с оверлеем.

Обратите внимание, что версия без наложения градиента читается плохо. Для пользователя это нехорошо. Чтобы решить эту проблему, нам нужно добавить слой под текстом так, чтобы текст читался легко. Добавление этого слоя может быть сложной задачей, и я видел многих, кто внедряет это решение, не принимая во внимание доступность.

Обзор возможных решений

Давайте посмотрим на возможные решения.

Есть решения, требующие большего внимания, это градиентные решения. Почему? Потому что добавить слой градиента это очень просто, но текст не будет удобным.

Решения

Наложение градиента

Вообще говоря, наложение градиента это наиболее распространённое решение, позволяющее сделать текст на изображении более чётким. Учитывая это, я остановлюсь на нём немного подробнее.

При реализации наложения градиента у нас есть два варианта:

  • Использовать отдельный элемент для градиента (псевдоэлемент или пустой <div>)

  • Применить градиент как фоновое изображение.

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

Элемент содержимого позиционируется абсолютно, его фоновым изображением служит градиент. Это означает, что размер градиента равен высоте элемента.

.card__content {  position: absolute;  /* other styles (left, top, right, and padding) */  background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent);}

На первый взгляд может показаться, что градиент хорошо работает. Это не так. Я протестировал тот же градиент с большим количеством изображений, и вот результат.

Обратите внимание, что контраст между белым текстом и изображениями не всегда чёткий. Некоторые люди прочитают текст, но использовать такой градиент огромная ошибка.

Причина в том, что градиент должен покрывать больше пространства по вертикали, поэтому должен быть выше. Если градиент равен размеру контента, он будет работать не во всех случаях. Чтобы решить эту проблему, мы можем использовать min-height, как показано ниже:

min-height к элементу .card__content.

Flexbox для перемещения содержимого вниз.

.card__content {  position: absolute;  /* other styles (left, top, right, and padding) */  display: flex;  flex-direction: column;  justify-content: flex-end;  background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent);}

Другое решение большой padding-top, с ним не нужны min-height и flexbox.

.card__content {  position: absolute;  padding-top: 60px;  background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent);}

Обратите внимание на разницу между левой и правой карточками. Градиент больше по высоте.

Выглядит хорошо. Можем ли мы сделать лучше? Определённо да!

Смягчение градиента

Присмотревшись, вы заметите, где заканчивается градиент, то есть у него резкая граница.

Чтобы сделать лучше, мы можем применить смягчение градиента. Таким образом градиент будет выглядеть естественнее, и вы не заметите резких краёв в его конце.

Чтобы достичь плавности, в CSS нам нужно несколько границ перехода градиента, но на момент написания этой статьи в CSS нет нативного способа сделать несколько границ. Хорошая новость заключается в том, что рабочая группа CSS обсуждает возможность реализации нативного смягчения градиентов на CSS, но остаётся неясным, когда эту возможность внедрят.

К счастью, г-н Андреас Ларсен создал удобные плагины PostCSS и Sketch, которые помогают преобразовывать резкий градиент в более мягкий.

Вот градиент CSS для примера выше:

.card__content {  background-image: linear-gradient(    0deg,    hsla(0, 0%, 35.29%, 0) 0%,    hsla(0, 0%, 34.53%, 0.034375) 16.36%,    hsla(0, 0%, 32.42%, 0.125) 33.34%,    hsla(0, 0%, 29.18%, 0.253125) 50.1%,    hsla(0, 0%, 24.96%, 0.4) 65.75%,    hsla(0, 0%, 19.85%, 0.546875) 79.43%,    hsla(0, 0%, 13.95%, 0.675) 90.28%,    hsla(0, 0%, 7.32%, 0.765625) 97.43%,    hsla(0, 0%, 0%, 0.8) 100%  );}

Сравните карточки со смягчением градиента и без него.

Горизонтальные градиенты

Работа с текстом поверх изображения не может касаться только вертикального градиента, можно работать и с горизонтальным.

Вот CSS градиента для раздела выше. Чтобы добиться смягчения градиента, я использовал упомянутый ранее инструмент.

background: linear-gradient(  to right,  hsl(0, 0%, 0%) 0%,  hsla(0, 0%, 0%, 0.964) 7.4%,  hsla(0, 0%, 0%, 0.918) 15.3%,  hsla(0, 0%, 0%, 0.862) 23.4%,  hsla(0, 0%, 0%, 0.799) 31.6%,  hsla(0, 0%, 0%, 0.73) 39.9%,  hsla(0, 0%, 0%, 0.655) 48.2%,  hsla(0, 0%, 0%, 0.577) 56.2%,  hsla(0, 0%, 0%, 0.497) 64%,  hsla(0, 0%, 0%, 0.417) 71.3%,  hsla(0, 0%, 0%, 0.337) 78.1%,  hsla(0, 0%, 0%, 0.259) 84.2%,  hsla(0, 0%, 0%, 0.186) 89.6%,  hsla(0, 0%, 0%, 0.117) 94.1%,  hsla(0, 0%, 0%, 0.054) 97.6%,  hsla(0, 0%, 0%, 0) 100%);

Смешивание сплошного цвета и градиента

Я узнал об этом приёме на сайте Netflix. На домашней странице для незарегистрированного пользователя есть заголовок с большим фоновым изображением.

Мне это нравится, но он скрывает многие детали изображения. Используйте этот приём только в том случае, если изображение должно быть декоративным (не приносит реальных преимуществ конечному пользователю).

<div class="hero">  <img src="cover.jpg" alt="" />  <div class="hero__content">    <h2>Unlimited movies, TV shows, and more.</h2>    <p>Watch anywhere. Cancel anytime.</p>  </div></div>
.hero:after {  content: "";  position: absolute;  left: 0;  top: 0;  width: 100%;  height: 100%;  background-color: rgba(0, 0, 0, 0.4);  background-image: linear-gradient(    to top,    rgba(0, 0, 0, 0.8),    rgba(0, 0, 0, 0) 60%,    rgba(0, 0, 0, 0.8) 100%  );}

Вот наглядное объяснение того, как работает этот паттерн.

Наложение градиента и тень текста

Есть небольшая полезная деталь, которая может сделать текст поверх изображений ещё лучше. Всё дело в добавлении к тексту лёгкой тени. Даже когда заметить её нелегко, она может быть очень полезной, если изображение не загружается. Посмотрим на такой пример.

.whatever-text {  text-shadow: 0 2px 3px rgba(0, 0, 0, 0.3);}

Наложение градиента, тень текста и непрозрачность

Это закономерность, которую я заметил в проигрывателе видео на Facebook. Мне понравилось, что они использовали несколько техник, чтобы сделать текст и другие элементы пользовательского интерфейса чёткими. При работе с проигрывателем очень важно гарантировать, что элементы поверх него заметны.

.player__icon {  opacity: 0.9;}.player__time {  color: #fff;  text-shadow: 0 0 5px #fff;}

Что в этом нового? Значки и проигрыватель имеют непрозрачность в 90 %. Это помогает им смешаться с фоном под ними. Создаётся ощущение, что элементы управления вмешаны в изображение.

Кроме того, белая тень у белого текста эффективный способ сделать текст чётче. Вы хотите доказательства того, что всё вышесказанное будет работать, даже если фон полностью белый? Ну, вот.

Текст и элементы интерфейса хорошо читаются, даже когда изображение полностью беоеТекст и элементы интерфейса хорошо читаются, даже когда изображение полностью беое

Youtube делает то же самое со своими видео.

Вот что мне понравилось в подходе Youtube:

  • Тёмная рамка для каждого значка, чтобы он лучше выделялся.

  • Чёрная тень вместо белой для времени видео.

Радиальный градиент

Интересное решение, о котором я узнал от Netflix, радиальный градиент. Вот как он работает:

  1. Установите основной цвет заднего фона.

  2. Поместите изображение в верхний правый угол с шириной 75 %.

  3. Наложение соответствует размеру и положению изображения.

.hero {  background-color: #000;  min-height: 300px;}.hero__image {  position: absolute;  right: 0;  top: 0;  width: 75%;  height: 100%;  object-fit: cover;}.hero:after {  content: "";  position: absolute;  right: 0;  top: 0;  width: 75%;  height: 100%;  background: radial-gradient(    ellipse 100% 100% at right center,    transparent 80%,    #000  );}

Тем не менее команда Netflix в качестве оверлея использовала изображение .png. Конкретной причины этого я не знаю. Может быть, дело в проблеме с кросс-браузерностью или что-то в этом роде: я не тестировал решение с радиальным градиентом.

Выбор удобного пользователю цвета наложения

Я покажу отличный инструмент, который помогает выбрать правильную непрозрачность наложения в зависимости от изображения. Посмотрите его на Codepen. Интересная задача сделать градиент удобным.

В общем, если вы гарантируете, что наложение градиента правильно заполняет текст и имеет подходящий цветовой контраст, всё готово.

Тестирование

Решение нельзя считать хорошим, пока оно не протестировано, верно? Один из способов, который я использую для проверки наложения градиента, добавление белого фона ниже градиента. Если текст после этого читаемый, то градиент будет работать с любым изображением, а если нет, вам нужно настроить и улучшить его.

В приведённом выше примере я выбрал сплошной цвет под заголовком, а коэффициент контрастности составляет 4,74, такой коэффициент считается хорошим.

Работа с Firefox DevTools

Спасибо Гийсу Вейфейкену: он рассказал мне, что Firefox может тестировать цветовой контраст на градиентах. Это отличная функция.

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

Другие профессии и курсы
Подробнее..

Цифровая доступность пять ключевых проблем в интерфейсах. Совместный вебинар Яндекс.Практикума и Валерии Курмак

05.05.2021 16:05:29 | Автор: admin
13 мая Яндекс.Практикум вместе с Валерией Курмак проводит открытый вебинар Цифровая доступность: пять ключевых проблем в интерфейсах. Вебинар будет полезен дизайнерам и разработчикам интерфейсов, которые хотят научиться проектировать доступно.



Юзабилити строится на восприятии и взаимодействии. Но что, если пользователь для восприятия интерфейса масштабирует его на 400, 600 и более процентов? Как тогда работают выпадающие списки, сторис и другие такие обыденные для каждого дизайнера и разработчика элементы?

На вебинаре слабовидящий Дима Глюз покажет на примерах, какие барьеры он встречает в интерфейсах. А руководитель продуктового дизайна Яндекс.Практикума Сергей Кудинов и руководитель фронтенд-разработки Давид Роганов расскажут, как не создавать такие барьеры при проектировании.

Ведущая


Валерия Курмак член Strategic Leader in Accessibility Initiative в IAAP, автор образовательного курса по цифровой доступности, автор телеграмм-канала об инклюзивном дизайне Не исключение.

Спикеры


Дима Глюз слабовидящий пользователь с диагнозом нейропатия Лебера.

Сергей Кудинов руководитель продуктового дизайна Яндекс.Практикума, www.sergeikudinov.com

Давид Роганов руководитель фронтенд-разработки Яндекс.Практикума.

Вебинар пройдёт 13 мая в 19.30 (Мск). Регистрация.
Подробнее..

Псс, дизайнер, хочешь ещё один конструктор для создания сайтов?

11.05.2021 14:17:08 | Автор: admin

Всем привет! На самом деле я сторонюсь сравнений с конструкторами сайтов и ниже расскажу, почему это так. Наш проект это скорее редактор, позволяющий динамически верстать макеты без кода и генерирующий на выходе оптимизированный продакшн-реди код. В остальном мы ближе к графическим редакторам. Этакий No-Code Pixel Perfect инструмент, где всё нужное под рукой, и где реализовано всё то, чего не хватало в Фигме.




За всё, что мы делаем, отвечаем тоже вместе (с)


Для начала несколько слов про нашу команду. Она небольшая, что, конечно же, накладывает свои сложности, но даже в таком формате мы достаточно быстро реализуем наш план и с оптимизмом смотрим в будущее.


Самое время представиться. Меня зовут Витя, занимаюсь дизайном около 12 лет. За это время поработал в разных компаниях. В самом начале пути это был аутсорс. Затем пришел в uKit.Group, а на тот момент uCoz (честно напиши в комментариях, сколько сайтов кланов по контре собрал на юкозе, пока был юн и горяч). Можно сказать, что uKit это мой первый серьезный продуктовый опыт.


Последние 4 года работаю на позиции арт-директора.


В команде проекта, о котором я сейчас буду говорить, помимо меня всего три человека: два программиста Рома и Слава, и тестировщик Егор.


Для кого наш проект


Графит это продукт для профессионалов, а вернее, он для тех, кто уже понимает в дизайне и имеет определенный опыт. Для таких людей он будет максимально полезен. Слишком сильно занижать порог входа мы не стали, потому что все фишки, которые позволяют делать красивые и необычные сайты, требуют скилла.



У нас несколько аудиторных фокусов, один из их это небольшие дизайн-студии. Также можно выделить дизайнеров-фрилансеров. Мы многое ещё не успели реализовать на текущий момент, но вот именно фрилансерам, создающим сайты-визитки и небольшие сайты до 10-20 страниц, Графит подходит уже сейчас. Он способен удовлетворить многие их потребности в области Pixel Perfect, необычных дизайнов и нетривиальной верстки. Многие макеты из Фигмы можно сверстать почти один в один внутри Графита.


Хорошо там, где нас нет


При выборе рынка мы решили пойти путем, который вписывается в одно утверждение, не нами придуманное. Если ты начинаешь как российский продукт, тебе потом очень сложно вырасти в мировой, и наоборот начиная с мирового рынка, тебе будет проще потом прийти и в Россию. Поэтому мы сейчас больше смотрим в сторону западной аудитории. Отсюда и выбор дефолтного языка интерфейса он у нас английский. Наши первые тесты тоже были на западных пользователях.


Наши конкуренты: Фигма, Скетч, Editor X от Wix, Studio.design, Webflow, Readymag, SquareSpace. Аудитория каждого сервиса может найти для себя мотивацию юзать Графит. Наша задача донести, почему стоит это сделать.


Допустим, человек использует Фигму и Скетч, но не пользуется сайтбилдерами. Такая аудитория для нас привлекательна. Многие дизайнеры не побоюсь этого слова страдают от необходимости работать с верстальщиками. На Хабре про боль дизайнеров было немало статей, и сколько их ещё будет!


Tell me Why


Если описывать наши фичи, то можно отметить, что почти каждая из них так или иначе уже будет знакома дизайнерам, но их синергия в одном инструменте в таком же наборе нигде не встречается, могу говорить об этом уверенно.


I. Сетка


Прежде всего, Графит это инструмент сетки. Звучит не ново, согласен. Однако в нашем случае сетка представляет собой визуальный инструмент автоматической верстки, который ломает для дизайнера барьер между кодом и графикой. Сетка внутри Графита объединяет два способа расположения элементов: непосредственно по сетке и свободное позиционирование. Поэтому мы называем её гибридной.



Любая конструкция, собранная в Графите, по умолчанию адаптивна: добавляйте в контейнеры элементы по координатам, не думая о том, что случится при входе с мобильного устройства.


Дополнительную гибкость при сборке макетов дает стек. Конструкции любой вложенности создаются прямо с холста, при этом можно реализовать любые возможности современного CSS и Flexbox.


Наша сетка настраиваемая: самостоятельно устанавливайте количество колонок, межколонный интервал, ширину и отступы у контейнера. Элементы сайта сами адаптируются под изменения каждого параметра.


II. Панель слоев


Для удобства дизайнеров управлять структурой сайта можно с помощью панели слоев, реализованной по аналогии с привычными графическими редакторами.


Что мы привнесли от себя:


  • в списке слоев отображается структура сетки
  • элементы со свободной позицией помечаются специальной иконкой
  • элементы сетки сортируются по правилам, позволяя сохранить правильную структуру сайта

III. Дизайн-система


В Графите она рождается, живет и развивается вместе с сайтом. Это позволяет поддерживать и развивать дизайн-систему с минимальными затратами.



Что это дает:


  • можно перекрасить сайт целиком в один клик, либо изменить цвет отдельных элементов или контейнеров
  • управление всей типографикой происходит в режиме одного окна
  • есть возможность настроить собственные переменные и наследовать их в любой момент в любом проекте
  • каждую часть дизайн-системы можно заменить, используя механизм пресетов

IV. Визуальные компоненты


Эта функция пока только находится в разработке. Она позволит создавать компоненты из комбинации элементов сайта и переиспользовать их в дальнейшем. Механизм работы будет похож на реализацию компонентов (или символов) в графических редакторах.


С помощью компонентов можно будет, например, создать шаблон шапки или карточки и редактировать их в одном месте.


Что ещё?


Я бы особенно выделил нашу концепцию работы с марджинами. Если ты кликнешь в элемент и наведешь на его край, там появится маленькая палочка. Потянув за неё, ты увеличишь или сократишь внешний отступ. Опция простая и далеко не новая, но в сеточной инфраструктуре она имеет важное значение. Это позволяет работать с пустым пространством. Для дизайнеров это важно. Именно контраст между пустым пространством и контентом формирует ощущение от макета.


Подкапотное пространство


На самом деле в Графите есть множество других мини-фич, но про них мы наверное расскажем в следующем посте, который будет техническим. А пока, для затравки, чтобы порадовать не только дизайнеров, но и технарей, напишу небольшой абзац про технологии, на которых работает Графит.


Фронт: Lerna, React, Redux, Emotion (SPA), Flow, Prettier, Unit testing, Gitlab CI, Babel, Webpack, Sentry.


Бэк: Node.JS, Nest.JS, MongoDB, Firestore, Nginx + LUA, PM2, RabbitMQ, Docker, Dockerswarm, Grafana, Fluentd, Kibana.


О том, как мы всё это готовим и с какими трудностями сталкиваемся уже в следующем посте. Буду рад вашим вопросам!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru