Jump to content

Как верстать UI при помощи веб-технологий


s0rr0w
 Share

Recommended Posts

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

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

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

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

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

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

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

Еще одна проблема в любой разработке - недостаток информационных потоков между разработчиками. Затрагивать эту тему мы будем потому, что она напрямую влияет на качество кода. Очень часто проблемы вызывает то, что кодер считает себя конечным звеном разработки: дали задание, собрал и забыл. Это пагубная практика. Перед любой сборкой нужно думать. Много думать, моделировать в голове будущую сборку. Если кодеру что-то не нравится в дизайне, нужно садиться с дизайнером и оговаривать все ньюансы перед сборкой. Многие проблемы можно обходить еще до начала сборки, ведь проще перерисовать пару элементов, чем переверстывать тонны кода потом. Аналогично обстоят дела и с другой стороной медали - программистами. Если вы сделали что-то эдакое, которое требует от программера дополнительных переменных или условий, вы должны идти к нему и обсуждать эту проблему. Если это не сделать сразу - потом вы будете переделывать работу по несколько раз за свой счет, срывая сроки и недосыпая ночами.

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

* Какие первые потенциальные проблемы могут возникнуть при сборке?

* Какие закономерности можно выявить в дизайне, и как их можно систематизировать?

* Какие исключения из закономерностей есть, можно ли ими пренебречь?

* Достаточно ли информации представлено на рисунке, чтобы выполнить все задание?

* Какое поведение должно быть у каждого из элементов?

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

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

Edited by s0rr0w
Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

Подводные камни

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

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

post-218-1271099476_thumb.png

А потом его расширил до вот такого:

post-218-1271099484_thumb.png

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

Для начала стоит классифицировать все объекты, чтобы проще было определять зависимости. Итак, что мы видим?

1. Плашка.

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

На что стоит обратить внимание?

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

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

а) Входит ли в ширину плашки загогулина в заголовке, или нет.

б) Как должны позиционироваться другие плашки без загогулины относительно данного дизайна плашки.

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

2. Заголовок плашки.

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

* Длинный текст заголовка. Что будет, если текст заголовка будет в две строки?

* Загогулина. Принадлежит ли загогулина логически заголовку, или же всей плашке?

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

3. Панель кнопок и кнопки.

* Дизайн состояний кнопок. Кнопки имеют несколько состояний, нужны варианты всех доступных состояний: hover, active, usual.

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

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

5. Панель табов.

Тут все более-менее понятно, за исключением пары вопросов

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

* Дизайн состояний активаторов табов. На дизайне не показано, как будет выглядеть hover-состояние на неактивном и активном активаторе таба.

6. Контентная область.

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

7. Две колонки.

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

* Пропорции колонок. Пропорции колонок должны быть резиновыми или левая часть должна быть статической? Какие еще пропорции могут встречаться?

* Зеркальные колонки. Могут ли колонки быть в зеркальном отображении? Это важно при выборе вариантов кода для решении данной задачи.

8. Дерево

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

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

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

Link to comment
Share on other sites

Подводные камни

Да да, целиком и полностью...

Еще надо представить, что бы во вложенном 5-го уровня пункте слова не вылазили на контент или красиво и грамотно переносились и чтобы плашка вмещала в себя теоритически бесконечное кол-во пунктов. Тяжко. И переделывать потом очень неприятно. А все потому, что ТЗ четкого тут никто не может предоставить, работы по верстке начинаются задолго до окончания переговоров с заказчиком =).

Link to comment
Share on other sites

  • 1 month later...

3. Думаем как машина.

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

Разумная уникальность

Дизайнеры очень любят рисовать то, что красиво выглядит. Работа у них такая. А вот кодер должен быть тем Цербером, который не дает дизайнеру интерфейса слишком разгуляться. Потому что нарисовать изменения, зачастую, требует получаса работы, а внести изменения в код всего продукта, протестировать, внести все исправления и удалить недочеты - две недели. Почему так долго? Да потому что нельзя вносить слишком много уникальных правок в код. Это сильно фрагментирует его и приводит к трудноуловимым ошибкам.

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

1. Сделать новый стиль и структуру кода для данного дизайна, старый код и стиль оставить как есть.

2. Сделать новую структуру и новый стиль, но внести изменения во все участки кода.

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

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

Итеративность кода

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

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

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

Заголовок может не "знать", какой именно блок находится после него. Перекладывать это на программную часть очень плохо. Зато можно изменить условия задачи, и перенести уголки и тень в блок, который "знает", какого цвета его фон. Т.е. плашка под заголовком будет иметь ровную линию внизу, а уголки и тень будет формировать тот блок, который находится под заголовком, ему достаточно иметь отрицательное смещение margin-top. Вуаля! Таким простым изменением поведения блока мы серьезно облегчили задачу программисту, ведь теперь ему не нужно думать про логику вывода блока, а достаточно просто выводить его. Мы облегчили задачу серверу, потому что ему не не нужно обрабатывать дополнительный код. Мы сделали код чище и понятнее, а это самое главное.

Модификаторы вместо глобальных конструкций

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

.menuBlock UL LI { color: green }

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

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy