Мысли о верстке с JavaScript позиционированием изИсточник: habrahabr Quiensabe
Рискну опубликовать недавно сформировавшуюся идею относительно верстки современных сайтов, в т.ч. в так называемом "плиточном" стиле. Но прежде чем излагать мысли хочу привести два "предупреждения":
Суть идеи.Наблюдая за тенденциями в дизайне сайтов, которые в плане интерфейса все ближе к приложениям, а также сталкиваясь с проблемами в верстке подобных проектов, захотелось придумать подход упрощающий верстку необычных сайтов (которые постепенно становятся вполне обычными). При обычной верстке html - задает структуру контента, а css - управляет и позиционированием и визуальным представлением документа. Эта двойственность css приводит к раздутым файлам стилей, внутри которых бывает сложно ориентироваться. Одни и те же свойства управляют и положением и внешним видом элементов - это вносит путаницу и затрудняет отладку. На мой взгляд, и думаю, эта мысль не нова, позиционированием блоков мог бы заняться JavaScript, это позволит создавать динамические структуры легко адаптирующиеся к разным разрешениям на разных устройствах, но описывать структуру документа на чистом JavaScript - мягко говоря, неудобно. В идеале хотелось бы создать некий "мини-язык" упрощающий возможности разметки документа для человека не являющегося специалистом в JavaScript. В таком "мини-языке" можно было бы максимально просто сформулировать правила адаптации макета к любому разрешению экрана. А JavaScript обеспечил бы выполнение этих правил. Дальнейший код и картинки как раз и показывают, как это могло бы выглядеть.
РазметкаЛюбой макет при адаптации под экран пользователя для начала не должен разваливаться на части, поэтому логичнее всего, по-моему, начинать разметку с направляющих. Например, так:
Таким образом, направляющие становятся свойствами объекта guideX с пользовательскими именами. Теперь добавим горизонтальные направляющие:
Теперь к полученной сетке можно привязать блоки. block.name = 'left, top, right, bottom'; Например в нашем случае:
(Конечно, блоки можно определять и напрямую, не используя направляющие, но это затруднит понимание структуры макета) Также блок можно определить через указание расположения внутри родительского блока: block.name = 'положение_по_x width, положение_по_y, hieght'; Например, так:
Третьим типом указания расположения блока является указание положения его центра, а также ширины и высоты. Конструкция в этом случае будет выглядеть так: При определении блока можно указать гораздо больше параметров его позиционирования, просто дописывая их через пробел. Эти параметры будут рассмотрены позже. После отслеживаются изменения на странице для соответствующего изменения позиционирования. Например, в данном случае содержимое блока sidebar - может не влезть на экран, что может привести к нарушению структуры. Поэтому изменения размеров блоков отслеживаются, и в данном случае, при увеличении высоты блока sidebar - соответственно сдвинется направляющая guideY.footer, и соответственно изменятся размеры блока content и положение блока footer. Таким образом, при наполнении страницы не нужны многочисленные вложенные блоки div. Достаточно описать просто:
в любом месте страницы, и логотип встанет на место. При этом внутри div-блока - естественно можно использовать всю стандартную html + css разметку.
РасширениеКонечно, в таком виде данная надстройка мало кому может быть действительно полезна. Интересный функционал появляется при использовании некоторых дополнений.
Вложенные блоки.
block.tel = ' in block.logo 10, 100%-50, 100%, 100%'; Или в варианте с указанием стороны пристыковки block.tel = ' in block.logo right 100%-10, bottom 50'; Вложенный блок всегда находится на большем уровне, чем родительский, поэтому нет сложностей с перекрытием объектов.
Зависимости.Предположим, что нам нужен статичный дизайн в 1000px, по центру окна. Для этого проще всего использовать такой код:
Но в ряде случаев может понадобится более сложные зависимости, например когда контент должен быть сдвинут немного влево, так чтобы свободное пространство слева - было в два раза меньше чем справа… Этого можно достичь добавлением правил.
Первые две строки только объявляют направляющие, но не определяют их значения. Вторые две - задают правила, по которым высчитываются координаты направляющих. Кстати, для переменной ширины блока можно заменить последнюю строку на:
Оператор "to" - означает, что величина разницы будет от 1000 до 1300, с приоритетом последней. По сути, при анализе такой страницы выполняется решение системы линейных уравнений (или в сложных случаях решается задача на оптимизацию, к примеру симплекс методом), и вычисляются необходимые значения. Именно использование правил в случае дальнейшего расширения движка может позволить реализовывать сложные вещи путем написания минимального количества кода. Такой подход позволяет создавать гибкие зависимости между любыми блоками наиболее простым и естественным образом. Анализируя графический макет будущего сайта, человек мыслит примерно такими правилами как "этот блок тянется… этот статичный… этот по ширине равен этому… этот в центре этого… и т.п.". Запись этих заключений в виде правил гораздо проще и логичнее чем стандартные подходы к верстке. При этом совмещение этого подхода с использованием свойств блоков (описано в следующем пункте) позволит реализовать действительно сложные структуры всего несколькими правилами.
СвойстваЕстественно расширить возможность системы не только на позиционирование блоков, но и на другие особенности, там где преимущества интерактивного кода помогут решить проблемы корректного отображения. Для этого, у блоков и направляющих нужно реализовать дополнительные свойства. Конечно, перечень свойств можно дополнять, я перечислю самые основные.
1. Обычные свойстваК любому определенному свойству блока можно обратиться напрямую. Например, после определения: block.logo = '0, 0, '100, 50'; можно обратиться к block.logo.left или к block.logo.bottom. Также к обычным свойствам я отношу параметр заполнения блока. По умолчанию любой блок тянется вниз, при увеличении объема контента. Но написав block.name.fix = true. Можно зафиксировать размер блока.
2. Подгонка шрифтовblock.name.fontsize = 'n%'; - этот параметр задает размер шрифта в пропорции от высоты блока. Такой подход позволяет выводить надписи идеально подходящим по размеру шрифтом. Например, вывести текстовый логотип с высотой равной шапке сайта, при любом разрешении.
3. Подгонка картинокblock.name.image_fit = '[путь/]имя_файла [left/top/right/bottom]'; - позволяет заполнить блок изображением, причем изображение масштабируется таким образом чтобы заполнить блок целиком. Если указан второй параметр - то при подгонке по этой стороне не производится обрезка изображения.
4. Перетаскивание блоковblock.name.dragX = 'true/false [start [, end]]'; - задает возможность перетаскивать блок по оси X в пределах от start до end, от текущего положения. Пример: block.tel.dragX = 'true -10, 80%'; Перетаскивание блоков позволяет сделать простую анимацию блоков. Например, такая конструкция.
Такая запись позволит полностью определить структуру блоков в шапке со слайдером на три слайда, останется только заполнить соответствующие div блоки.
Добавление записи:
Позволит, перетаскивая блок scroll - перематывать слайдер внутри блока block.slider. А запись:
Позволит перематывать слайдер напрямую двигая его (например, на сенсорном экране)
Формальное описаниеФормально все операторы выглядят так:
блоки:
правила:
Где <число> - это любое выражение JavaScript, либо любой процент (будет вычислен исходя из размеров родительского блока), либо пара выражений типа '<число1> to <число2>' - означающее будет выбрано число в диапазоне от <число1> до <число2>, по возможности близкое в <число2>. В выражениях не могут должны зарезервированные слова: to, fit, fix, image_fit, left, center, right, top, midle, bottom, pos_center, in, guideX, guideY, block, rule После описания разметки обязательно идет вызов функции run(); Чтобы не раздувать статью я не описываю механику работы движка. Но суть проста: в скрипте определяются объекты guideX, guideY, block и rule. После пользователь определяет разметку создавая свойства для этих объектов и определяя значения простыми строками. А при запуске run(); - выполняется перебор этих свойств и определение числовых значений. После этого для всех свойств объекта block ищутся соответствующие им div-блоки и блокам присваивается соответствующее позиционирование. Отрисовка выполняется циклически, чтобы учесть возможные изменения размеров блоков в зависимости от контента, а после аналогичные перестроения происходят при изменении размеров страницы или перемещения подвижных блоков.
ПримерВ качестве примера приведу код для создания страницы-визитки. На фоне должно отображаться изображение, подогнанное под размеры экрана, Вверху слева - логотип и слоган, внизу - контакты. По центру блок со слайдером или другим контентом фиксированного размера. Код
ЗаключениеК преимуществам подхода можно отнести: отсутствие мусора в css в виде дополнительных стилей и "костылей", простота разработки адаптивной верстки для любых разрешений, настройка логики позиционирования, используя простые "правила", разделение правил позиционирования от оформления и содержимого документа, возможность частичной автоматизации верстки, используя экспорт направляющих и общей логики разметки из psd-файла с помощью дополнительного скрипта. Также к плюсам можно отнести то, что для работы движка не требуется никаких действий кроме подключения js-файла. А весь "язык разметки" состоит из нескольких типовых выражений, которые легко выучить и применять. Также можно добавить что и сегодня JavaScript часто используется при верстке сайтов для решения проблем или разработки нестандартных элементов. Описываемый подход мог бы помочь реализовать многие вещи в пару строк, даже если человек не хочет использовать движок для верстки основной структуры страницы.
К недостаткам относится необходимость изучения нового подхода в разметке, принципиально отличного от существующего, невозможность нормального отображения сайта без JavaScript, а также возможные проблемы при непродуманной или очень сложной структуре документа. Конечно, в рамках статьи невозможно показать все возможности применения такого подхода. Как и мысли по поводу реализации описанного функционала. Впрочем, идее нет еще и двух дней, так что со временем наверняка появится множество вариантов ее расширения. Надеюсь, кого-нибудь такой подход заинтересует. |