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

Ключ к хорошему дизайну пользовательского интерфейса - это визуальная согласованность. Это также ключ к хорошему HTML и CSS.

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

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

Но проявляется это удивительно тонко. Рассмотрим этот дизайн:

Выглядит довольно последовательно, не правда ли? Но посмотрите его реальные измерения:

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

Люди в порядке, инструменты ленивы

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

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

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

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

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

Front-End разработчики склонны предполагать, что существует какая-то очень важная причина, по которой каждый дизайн остается таким, какой он есть. Они предполагают, что сложный в реализации циферблат часов должен выглядеть в точности так, как это было изначально, потому что они рассматривают всю работу UI-дизайнера как работу эксперта. Поэтому они не пытаются упрощать или обсуждать. Они просто предполагают, что за всем стоит какая-то умная аргументация, и что UI Designer создаст идеальное решение с первой попытки.

- Генри Лэтхэм, Как сэкономить UI-дизайнерам и фронтенд-разработчикам до 50% их рабочего времени.

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

.box1 { 
  margin-bottom: 26px; 
  .author { 
    color: #3c0a0a;
  } 
} 
.box2 { 
  margin-bottom: 27px;
  .author { 
    color: #3e0c0c;
  } 
}

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

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

Но если разработчик нормализовал сами значения, код станет чище:

.box { 
  margin-bottom: 26px;
  color: $title-red;
}

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

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

Большие команды управляют, но маленькие команды борются

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

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

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

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

Явный подход масштабирования дизайна к созданию пользовательских интерфейсов

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

Вот пример:

{
  textSizes: {
    "12": "12px",
    "16": "16px"
  },

  colors: {
    "black": "#000000",
    "blue0": "#094771",
    "blue1": "#0e639c"
  },

  fonts: {
    "roboto": "Roboto, sans-serif"
  },

  margin: {
    "auto": "auto",
    "2": "2px",
    "16": "16px",
    "32": "32px",
    "48": "48px"
  }
}

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

Но не будет ли это без надобности ограничивать дизайн? Адам Уотан и Стив Шогер рассматривают это в прекраснейшем Рефакторинг пользовательского интерфейса:

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

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

Вместо этого ограничьтесь заранее определенным ограниченным набором значений.

Или, как говорят в дзен:

В уме новичка есть много возможностей, но в сознании эксперта их немного.

- Сюнрю Судзуки

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

Явные весы делают всех счастливыми

Представьте, что вы пытаетесь написать HTML и CSS для следующего дизайна и сталкиваетесь с полем в 39 пикселей между двумя элементами:

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

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

margin: {
    "auto": "auto",
    "2": "2px",
    "16": "16px",
    "32": "32px",
    "48": "48px"
  }

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

Принятие явных масштабов дизайна в вашем следующем проекте с помощью Tailwind CSS

Дизайнерские весы не нужно продавать дизайнерам; это уже часть их ментальной модели. Если не сделать его явным руководством по стилю, он существует, по крайней мере, неявно - спросите их «каковы наши обычные отступы для кнопок?», и они получат простой ответ. «А как насчет кнопок большего размера?», и они сообщат вам следующее значение в своей шкале интервалов.

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

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

В Tailwind источником истины является tailwind.config.js, который выглядит так:

{
  textSizes: {
    "12": "12px",
    "16": "16px"
  },

  colors: {
    "black": "#000000",
    "blue0": "#094771",
    "blue1": "#0e639c"
  },

  fonts: {
    "roboto": "Roboto, sans-serif"
  },

  margin: {
    "auto": "auto",
    "2": "2px",
    "16": "16px",
    "32": "32px",
    "48": "48px"
  }
}

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

<div class='text-16 text-blue0 roboto m-16'>Hello world</div>

Значит это:

{
  /* text-16 */
  font-size: 16px;

  /* text-blue0 */
  color: #094771

  /* roboto */
  font-family: Roboto, sans-serif

  /* m-16 */
  margin: 16px;
}

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

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

В частности, Tailwind CSS с его способностью генерировать классы CSS на основе нестандартных масштабов дизайна очень хорошо подходит для проектов, которые имеют настраиваемые пользовательские интерфейсы, созданные с помощью инструментов векторного рисования, таких как Sketch или Figma.

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

История происхождения

(Что такое средний пост без бесстыдной пробки?)

Этот пост основан на нашем опыте создания Protoship Codegen, инструмента, который поможет вам быстрее создавать веб-приложения SaaS, порталы электронной коммерции и веб-сайты с богатым контентом, конвертируя ваши проекты Sketch в идеальные HTML и CSS.

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

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

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

Станьте одним из первых здесь! Https://protoship.io/join/

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