Верстка

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

В первую очередь это Большая книга CSS Девида Макфарланда. В ней объясняются основы верстки с самого начала, материал изложен очень подробно и с примерами. Также можно начинать с сайта htmlbook.ru. Материал там изложен более кратко, но тоже достаточно хорошо. Также этим сайтом удобно пользоваться в качестве справочника. После изучения основ очень полезно прочитать CSS ручной работы Дэна Сeдерхольма. Эта книга мало касается теории и больше посвящена практике и качеству верстки. Во многом на написание данной статьи меня вдохновила именно она.

Отношение к верстке в нашей стране довольно неоднозначное. С одной стороны, верстка — это основа сайта и его лицо. Плохая верстка испортит впечатление о любом сайте (не забываем, что сайт во многом несет имиджевую функцию и по нему судят о самой компании), может привести к потере функционала или, в особо запущенных случаях, недоступности сайта вообще или на отдельных браузерах. Несемантическая верстка или верстка таблицами помешает продвижению сайта. С другой стороны, верстальщиков считают чернорабочими от web development, этакими джамшутами в сайтостроительстве, а саму верстку неинтересным и нетребующим особых интеллектуальных затрат занятием. По моему мнению людей, которые так считают можно разделить на 2 типа. Либо это истинные профессионалы своего дела, любую задачу они решают на автопилоте, так как решали подобные уже не раз, и верстка для них сводится лишь к написанию кода, который уже давно готов у них в голове. Их код не глючит, сразу работает во всех заявленных браузерах и опрятно выглядит. Вторая же категория людей делает верстку по принципу «сделал и забыл», лишь бы побыстрее. Их не волнует что будет в дальнейшем с их кодом, какие проблемы могут вылезти потом у заказчика, главное, что акт выполненных работ подписан. Однако, в таком случае не стоит удивляться, что второй раз заказчик к вам уже не обратится и никому не порекомендует. Даже если вы работаете на фирму, то ущерб репутации будет нанесен ей. И если она готова мириться работой сделанной быстро и плохо, то не стоит расчитывать на рост своей заработной платы, так как главным для такой фирмы является снижение издержек. Также с подобным опытом будет труднее найти новую работу, которая вряд ли будет особо выгодно отличаться от старой.

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

1) соответствие макету
2) кроссбраузерность
3) семантика и опрятность в организации кода
4) устойчивость кода к изменениям контента сайта

Соответствие макету и организация работы с дизайнером

То что верстка должна соответствовать макету сайта, думаю вопросов не вызывает, ведь именно этот вид был утвержден заказчиком, и именно так он хочет, чтобы сайт выглядел. Однако насколько полным должно быть это соответствие? Часто этот критерий вводят в абсолют и требуют идеального соответствия, так называемого pixel perfect («пиксель в пиксель»). Считается, что это главный критерий качества работы верстальщика. Также умение верстать подобным образом часто можно увидеть в вакансиях в разделе требований. Безусловно верстальщик должен уметь верстать «пиксель в пиксель», но нужно ли это делать?

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

creative9.com
creative9

gunswords.com
gunswords

www.visaforjapan.com
visaforjapan

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

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

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

note1
note2

Как видно, они немного отличаются. Отступ сверху и слева стал 20px вместо 15px. Что это? Небрежность дизайнера или это дизайнерский ход, и отличие действительно должно быть? Только сам дизайнер может ответить на этот вопрос. Вот тут начинаются проблемы. Если дизайнер в данный момент не на связи, то у верстальщика есть 2 выхода — переверстать элемент заново согласно макету и продолжать работу или оставить элемент таким же, каким он был на первом макете, и попытаться верстать дальше, так как теперь макет и верстка не совпадают. В первом случае будет создан новый класс, увеличится итоговый CSS, но формально верстальщик молодец. Он сделал все как было на макете. Потом выясняется, что дизайнер случайно изменил элемент на втором макете и нужно, чтобы он выглядел как на первом. Одними словами тут дело не ограничится, ведь вы помните, что мы делаем perfect pixel верстку, а значит нам нужно, чтобы дизайнер переделал второй макет, переутвердил его у заказчика, выслал его верстальщику, верстальщик выкинул новый класс, подчистил CSS, подогнал верстку под новый макет (ведь изменилась геометрия элемента, а значит, что расположение других элементом поменялось) и порадовал бекендера, что ему необходимо поменять классы в шаблоне, если бекенд разрабатывается параллельно с фронтом. Вся эта бюрократия отнимает время и нервы. Второй вариант чуть-чуть лучше, но дизайнеру все равно придется переделать свою работу и выслать переутвержденный вариант, а верстальщику подгонять под него верстку.

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

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

Дизайнер — тоже человек. Неужели вы думаете, что дизайнер любит попиксельно выравнивать абсолютно все элементы на макете, чтобы потом ткнуть верстальщика носом со словами «а у меня на макете по-другому»? Представьте, если в проекте большое количество макетов, на которых куча повторяющихся элементов. Если использовать pixel perfect, то тут застрелится либо дизайнер, заставляющий их все выглядеть одинаково, либо верстальщик, заставляющий их выглядеть по-разному, но согласно макетам. Во втором случае получим много лишнего CSS, который будет тяжело поддерживать, сайт будет дольше загружаться и выглядеть неряшливо, так как вряд ли в большинстве случаев различия между одинаковыми по сути элементами действительно были необходимы. И самое плохое здесь то, что на все это безобразие затрачено куча труда, а значит и денег.

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

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

2) уменьшение конечного кода, более опрятный и логичный код

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

1) увеличение скорости верстки
Верстальщик больше не занимается pixel hunting, а верстает исходя из того что он видит. Если потом дизайнер попросит что-то немного сдвинуть, то это легко сделать, и это не идет ни в какое сравнение с версткой perfect pixel по затратам времени.

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

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

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

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

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

1) дизайн в принципе можно сверстать.

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

2) макет с общими стилями присутствует и делается в первую очередь.

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

Что должен содержать макет со стилями?

а) палитра использованных цветов

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

Палитра должна быть семантической. Вот пример плохой палитры.

palete1

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

К тому же если потом заказчик захочет что-то поменять по ходу, то наверняка не будет говорить «а давайте все что было сининьким сделаем красненьким, а то что было красненьким, сделаем сереньким». Скорее всего он скажет что-то вроде «а давайте поменяем цвет ссылок с синего на красный, а дату просроченных документов будем выводить не красным, а серым». Чувствуете разницу? Заказчик выражается самантически верно, а палитра у нас вместе с переменными лишена семантики. В таком случае рискуем либо получить переменную blueColor, которая по факту будет содержать красный цвет, либо придется помимо изменения значения переменной, также менять и названия переменных. Зачем в таком случае вообще стоило заморачиваться с переменными? Вот пример семантически верной палитры.

palete2

Палитра должна содержать все использованные в проекте цвета. Типичными цветами являются: цвет основного текста, цвет основного фона, цвет ссылок, цвет акцентированных элементов, цвет неактивых элементов, цвет кнопок и т.д. Конечно могут быть иключения. Если допустим цвет используется только однажды в каком-то уникальном элементе, то нет смысла вносить его в палитру, но в этом случае, если он не бросается в глаза (допустим впервые появился не оранжевый цвет, а чуть более бледный оттенок серого), то на это стоит обратить внимание в коментариях (допустим пририсовать стрелочку с пометкой «новый цвет»). В таком случае верстальщик точно не пропустит этого, но при этом ему не придется залазить в свойства каждого элемента на макете, чтобы ничего не упустить, достаточно лишь выбирать подходящий цвет из палитры. Но исключения для того и исключения, чтобы не быть правилами. Хуже отстутствующей палитры только палитра, которой дизайнер не следует. Это ведет к ошибкам в верстке, снижению скорости верстки, так как верстальщику приходится проверять вручную цвет каждого элемента, и к бардаку в цветовых переменных, так как верстальщик не знает общей логики распределения цветов на макете.

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

Первый способ работает замечательно. Можно к примеру задать уровень непрозрачности текста 70%, рамки 90%, а заднему фону 30%. Однако если мы поддерживаем IE8, то от этого способа придется отказаться, так как RGBA в этом браузере не поддерживается. Конечно возможен вариант с изящной деградацией, когда для IE8 будет указан точно такой же цвет, но только с полной непрозрачностью. Но если мы используем допустим непрозрачность 30%, то разница между IE8 будет слишком большой и может привести к тому, что, к примеру, текст будет не виден на слишком темном фоне.

Свойство opacity хоть и не поддерживается в IE8, но довольно хорошо там эмулируется. Однако у этого метода есть своя особенность — оно назначается для всего HTML элемента целиком, включая все вложенные элементы. Таким образом, чтобы сделать непрозрачность текста, фона и рамки разными придется дробить их на разные HTML элементы, нарушать вложенность элементов и, как следствие, как-то ее эмулировать, чтобы размеры фона определялись контентом.

Нужно ли так коверкать HTML структуру и усложнять CSS? Зависит от дизайна. Если непрозрачность является важной частью дизайна (например это фон всплывающего окна, который должен показывать, что все остальные элементы страницы сейчас неактивны), то конечно стоит. Но если она использована лишь для того, чтобы сделать цвет текста чуть светлее, то определенно нет.

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

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

б) используемые размеры отступов

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

в) текстовое оформление

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

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

г) динамические элементы

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

3) макеты должны быть грамотно оформлены

а) грамотное распределение слоев

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

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

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

Часто встречается требование давать группам осмысленные названия. Это удобно, но по-моему мнению не так важно, как правильная группировка слоев. Т.е. гораздо удобнее пользоваться макетом в котором есть четкая иерархия групп, которые называются group1, group2, group3 и т.д., чем если имеем группу «форма для отправки данных», в которой просто набросаны в произвольном порядке штук 50 слоев этой самой формы. Достаточно осмысленно назвать только круппные группы, такие как шапка, подвал, боковая панель, главное меню и т.д. При нормальной иерархии слоев, понять, что скрывается под group1 не сложно, просто отключив ее отображение.

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

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

б) должны использоваться направляющие линии

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

4) вспомогательные материалы должны предоставляться отдельно, а не только в составе макета

Речь идет о различных «рыбных» картинках, логотипах и иконках. Конечно их можно вырезать из макета, но зачем тратить время, если они изначально уже были в отдельных файлах у дизайнера? Особенно важно представлять иконки, так как вырезать взаимозаменяемые элементы особенно трудно и долго. Предположим у нас есть определенный список, в котором перед каждым элементом может быть какая-то иконка. Верстальщик вырезает все иконки с холстом одинакового размера, чтобы их можно было менять между собой, но выровнять иконки все иконки одинаково внутри холста задача нетривиальная. Разница может составлять всего пару пикселей, но внешне будет видно, что иконки «поплыли». Еще заметнее будет расхождение, если иконки могут как-то меняться в зависимости от действий пользователя — к примеру менять свой цвет при наведении мышки на какой-то элемент. В таком случае ошибка в выравнивании даже в 1 пиксель будет легко заметна и потребует исправления исходных файлов. Всего этого можно избежать, если предоставить набор иконок сразу, в которых все выровнено идеально с самого начала.

Продолжение следует…