Рискну опубликовать недавно сформировавшуюся идею относительно верстки современных сайтов, в т.ч. в так называемом «плиточном» стиле. Но прежде чем излагать мысли хочу привести два «предупреждения»:
- я — дилетант. Хотя моя жизнь напрямую связана с программированием уже более 10 лет, я отношусь тем людям, которым интересно в IT очень многое от 3D моделирования до робототехники. А потому бывает, не знаю элементарных для специалиста вещей. Иногда это помогает, иногда мешает, но что есть, то есть.
- если вы хотите в результате «пощупать» технологию в деле, вынужден разочаровать. Все дальнейшее – только изложение мыслей и идей. Создать готовый движок на хорошем уровне у меня не хватит ни времени, ни умений. Впрочем, если кто-то заинтересуется изложенным – я готов всячески содействовать разработке.
Суть идеи.
Наблюдая за тенденциями в дизайне сайтов, которые в плане интерфейса все ближе к приложениям, а также сталкиваясь с проблемами в верстке подобных проектов, захотелось придумать подход упрощающий верстку необычных сайтов (которые постепенно становятся вполне обычными).
При обычной верстке html – задает структуру контента, а css – управляет и позиционированием и визуальным представлением документа. Эта двойственность css приводит к раздутым файлам стилей, внутри которых бывает сложно ориентироваться. Одни и те же свойства управляют и положением и внешним видом элементов – это вносит путаницу и затрудняет отладку.
На мой взгляд, и думаю, эта мысль не нова, позиционированием блоков мог бы заняться JavaScript, это позволит создавать динамические структуры легко адаптирующиеся к разным разрешениям на разных устройствах, но описывать структуру документа на чистом JavaScript – мягко говоря, неудобно. В идеале хотелось бы создать некий «мини-язык» упрощающий возможности разметки документа для человека не являющегося специалистом в JavaScript. В таком «мини-языке» можно было бы максимально просто сформулировать правила адаптации макета к любому разрешению экрана. А JavaScript обеспечил бы выполнение этих правил. Дальнейший код и картинки как раз и показывают, как это могло бы выглядеть.
Разметка
Любой макет при адаптации под экран пользователя для начала не должен разваливаться на части, поэтому логичнее всего, по-моему, начинать разметку с направляющих.
Например, так:
guideX.left = '20%'; guideX.sidebar = '10%+20'; guideX.right = '10%+420';
Таким образом, направляющие становятся свойствами объекта guideX с пользовательскими именами.
Теперь добавим горизонтальные направляющие:
guideY.top = '20'; guideY.content = 170'; guideY.footer = '100%-120'; guideY.bottom = '100%-20';
Теперь к полученной сетке можно привязать блоки.
Блок определяется координатами левого верхнего и правого нижнего углов.
block.name = ‘left, top, right, bottom’;
Например в нашем случае:
block.logo = 'guideX.left, guideY.top, guideX.left + 300, guideY.content'; block.content = 'guideX.left, guideY.content, guideX.sidebar - 10, guideY.footer'; block.sidebar = 'guideX.content, guideY.content, guideX.right, guideY.footer'; block.footer = 'guideX.left, guideY.content, guideX.right, guideY.footer';
(Конечно, блоки можно определять и напрямую, не используя направляющие, но это затруднит понимание структуры макета)
Также блок можно определить через указание расположения внутри родительского блока:
block.name = ‘положение_по_x width, положение_по_y, hieght’;
Например, так:
block.name = 'center 1000, top 50%';
Третьим типом указания расположения блока является указание положения его центра, а также ширины и высоты. Конструкция в этом случае будет выглядеть так:
block.name = ‘pos_center центр_по_x, центр_по_y, width, hieght’;
При определении блока можно указать гораздо больше параметров его позиционирования, просто дописывая их через пробел. Эти параметры будут рассмотрены позже.
После всех определений выполняется функция run(); которая на основе реального размера окна браузера, размеров блоков и страницы, рассчитывает размеры и координаты блоков и задает стили для соответствующих div блоков.
После отслеживаются изменения на странице для соответствующего изменения позиционирования. Например, в данном случае содержимое блока sidebar – может не влезть на экран, что может привести к нарушению структуры. Поэтому изменения размеров блоков отслеживаются, и в данном случае, при увеличении высоты блока sidebar – соответственно сдвинется направляющая guideY.footer, и соответственно изменятся размеры блока content и положение блока footer.
Таким образом, при наполнении страницы не нужны многочисленные вложенные блоки div. Достаточно описать просто:
<div id=”logo”> логотип </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, по центру окна. Для этого проще всего использовать такой код:
block.name = 'center 1000, top 100%';
Но в ряде случаев может понадобится более сложные зависимости, например когда контент должен быть сдвинут немного влево, так чтобы свободное пространство слева – было в два раза меньше чем справа… Этого можно достичь добавлением правил.
guideX.left = ''; guideX.right = ''; rule.my1 = 'guideX.left * 2 = 100% - guideX.right'; rule.my2 = 'guideX.right - guideX.left = 1000';
Первые две строки только объявляют направляющие, но не определяют их значения. Вторые две – задают правила, по которым высчитываются координаты направляющих.
Кстати, для переменной ширины блока можно заменить последнюю строку на:
rule.my2 = 'guideX.right - guideX.left = 1000 to 1300';
Оператор «to» — означает, что величина разницы будет от 1000 до 1300, с приоритетом последней.
По сути, при анализе такой страницы выполняется решение системы линейных уравнений (или в сложных случаях решается задача на оптимизацию, к примеру симплекс методом), и вычисляются необходимые значения. Именно использование правил в случае дальнейшего расширения движка может позволить реализовывать сложные вещи путем написания минимального количества кода.
Такой подход позволяет создавать гибкие зависимости между любыми блоками наиболее простым и естественным образом. Анализируя графический макет будущего сайта, человек мыслит примерно такими правилами как «этот блок тянется… этот статичный… этот по ширине равен этому… этот в центре этого… и т.п.». Запись этих заключений в виде правил гораздо проще и логичнее чем стандартные подходы к верстке. При этом совмещение этого подхода с использованием свойств блоков (описано в следующем пункте) позволит реализовать действительно сложные структуры всего несколькими правилами.
Свойства
Естественно расширить возможность системы не только на позиционирование блоков, но и на другие особенности, там где преимущества интерактивного кода помогут решить проблемы корректного отображения. Для этого, у блоков и направляющих нужно реализовать дополнительные свойства. Конечно, перечень свойств можно дополнять, я перечислю самые основные.
Некоторые свойства влияют на внешний вид элементов, а не на их позиционирование, что несколько противоречит концепции изложенной в начале статьи. Но это сделано намеренно, так как такой подход позволяет решить многие часто возникающие проблемы максимально просто.
1. Обычные свойства
К любому определенному свойству блока можно обратиться напрямую.
Поддерживаются: block.name.left, block.name.top, block.name.right, block.name.bottom, block.name.width, block.name.height, возможно другие.
Например, после определения: block.logo = ‘0, 0, ‘100, 50’; можно обратиться к block.logo.left или к block.logo.bottom.
Также к обычным свойствам я отношу параметр заполнения блока. По умолчанию любой блок тянется вниз, при увеличении объема контента. Но написав block.name.fix = true. Можно зафиксировать размер блока.
Если удастся качественно реализовать, можно будет добавить и свойство fit – автоматически выравнивающего масштаб контента в соответствии с размерами блока, по аналогии с соответствующей функцией в издательских системах.
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%’;
block.name.dragY = ‘true|false [start [, end]]’; — аналогично.
Перетаскивание блоков позволяет сделать простую анимацию блоков. Например, такая конструкция.
block.header = '10%, 20, 90%, 300'; // объявляем шапку. block.slider = 'in block.header 0, 0, 100%, 270'; // в шапке – поле для слайдера. block.scroll = ' in block.header 0, 270, 33.33%, 100%'; // объявляем скролл. block.slider_content = 'in block.slider 0, 0, 300%, 100%'; // в слайдере – слайды. block.slide_1 = 'in block.block.slider_content 0, 0, block.slider.right, 100%'; // слайд 1. block.slide_2 = 'in block.block.slider_content block.slider.right, 0, block.slider.right*2, 100%'; // слайд 2. block.slide_3 = 'in block.block.slider_content block.slider.right*2, 0, block.slider.right*3, 100%'; // слайд 3.
Такая запись позволит полностью определить структуру блоков в шапке со слайдером на три слайда, останется только заполнить соответствующие div блоки.
Добавление записи:
block.scroll.dragX = 'true 0, 100% - block.scroll.width'; rule.my1 = block.slider_content.left = - block.scroll.left*3';
Позволит, перетаскивая блок scroll – перематывать слайдер внутри блока block.slider.
А запись:
block.slider_content.dragX = 'true';
Позволит перематывать слайдер напрямую двигая его (например, на сенсорном экране)
Формальное описание
Формально все операторы выглядят так:
направляющие:
guideX.<имя направляющей> = '<число>'; guideY.<имя направляющей> = '<число>';
блоки:
block.<имя блока> = '[in <имя родительского блока>] {<число>,<число>,<число>,<число> | {left|center|right} <число>, {top|midle|bottom} <число> | pos_center <число>, <число>, <число>, <число>} [fix] [fit] [font_size <число>] [image_fit [путь/]имя файла] [dragX [<число> [,<число>]]] [dragY [<число> [,<число>]]]';
правила:
rule.<имя блока> = '<число> = <число>';
Где <число> — это любое выражение 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-блоки и блокам присваивается соответствующее позиционирование. Отрисовка выполняется циклически, чтобы учесть возможные изменения размеров блоков в зависимости от контента, а после аналогичные перестроения происходят при изменении размеров страницы или перемещения подвижных блоков.
Пример
В качестве примера приведу код для создания страницы-визитки. На фоне должно отображаться изображение, подогнанное под размеры экрана, Вверху слева – логотип и слоган, внизу – контакты. По центру блок со слайдером или другим контентом фиксированного размера.
Код
<html> <head> <script src="js.js"></script> <script language = 'javascript'> guideX.left = '10%'; block.content = '0,0,100%,100% image_fit background.jpg'; block.logo = 'guideX.left,12%,100%,23% font_size 100%'; block.slogan = 'guideX.left,23%,100%,26% font_size 70%'; block.slider = 'pos_center 50%, 55%, 700, 270'; block.footer = 'right 100%-guideX.left, bootom 12.6% font_size 15%'; </script> <style type="text/css"> * { font-family:"Times New Roman",Georgia,Serif; color:#fff; } </style> </head> <body> <div id="logo">Logo</div> <div id="slogan">Cамая компанейская компания</div> <div id="slider"> <!-- Код слайдера --> </div> <div id="footer">Наш адрес не дом и не улица...<br /> Копирайт (с) CopyRight</div> </body> </html>
Отображение сайта на разных экранах показано на рисунках.
Заключение
К преимуществам подхода можно отнести: отсутствие мусора в css в виде дополнительных стилей и «костылей», простота разработки адаптивной верстки для любых разрешений, настройка логики позиционирования, используя простые «правила», разделение правил позиционирования от оформления и содержимого документа, возможность частичной автоматизации верстки, используя экспорт направляющих и общей логики разметки из psd-файла с помощью дополнительного скрипта. Также к плюсам можно отнести то, что для работы движка не требуется никаких действий кроме подключения js-файла. А весь «язык разметки» состоит из нескольких типовых выражений, которые легко выучить и применять.
Также можно добавить что и сегодня JavaScript часто используется при верстке сайтов для решения проблем или разработки нестандартных элементов. Описываемый подход мог бы помочь реализовать многие вещи в пару строк, даже если человек не хочет использовать движок для верстки основной структуры страницы.
Например, для заполнения блока div изображением, с автоматической подгонкой под размер блока, достаточно строки.
block.name = 'image_fit background.jpg'; // блок без указания разметки, но с фоновым изображением
К недостаткам относится необходимость изучения нового подхода в разметке, принципиально отличного от существующего, невозможность нормального отображения сайта без JavaScript, а также возможные проблемы при непродуманной или очень сложной структуре документа.
Конечно, в рамках статьи невозможно показать все возможности применения такого подхода. Как и мысли по поводу реализации описанного функционала. Впрочем, идее нет еще и двух дней, так что со временем наверняка появится множество вариантов ее расширения. Надеюсь, кого-нибудь такой подход заинтересует.
ссылка на оригинал статьи http://habrahabr.ru/post/167525/
Добавить комментарий