Good afternoon, Habr!
I would venture to publish the recently formed idea about the layout of modern sites, including in the so-called "tiled" style. But before expressing my thoughts I want to give two “warnings”:
- I am an amateur. Although my life is directly related to programming for more than 10 years, I am among those people who are interested in IT very much from 3D modeling to robotics. That is why it happens, I do not know things that are elementary for a specialist. Sometimes it helps, sometimes it interferes, but what is, that is.
- if you want to “touch” the technology in action as a result, you have to disappoint. All further - only the presentation of thoughts and ideas. To create a ready-made engine at a good level, I don’t have enough time or skills. However, if someone is interested in what has been stated - I am ready to assist the development in every possible way.
The essence of the idea.
Observing the trends in website design, which are closer to applications in terms of the interface, as well as facing problems in the layout of such projects, I wanted to come up with an approach that simplifies the layout of unusual sites (which are gradually becoming quite ordinary).
In the usual layout, html sets the content structure, and css controls both the positioning and the visual presentation of the document. This css duality leads to bloated style files within which it can be difficult to navigate. The same properties control both the position and appearance of the elements - this causes confusion and makes debugging difficult.
')
In my opinion, and I think this idea is not new, JavaScript could take a lot of block positioning, it will allow creating dynamic structures that easily adapt to different resolutions on different devices, but describing the structure of a document in pure JavaScript is, to put it mildly, inconvenient. Ideally, I would like to create a kind of “mini-language” that simplifies the markup of a document for a person who is not a JavaScript expert. In such a “mini-language,” it would be as easy as possible to formulate rules for adapting a layout to any screen resolution. And JavaScript would enforce these rules. Further code and pictures just show how it might look.
Markup
Any layout when adapting to the user's screen, for a start, should not fall apart, so the most logical, in my opinion, is to start marking with guides.
For example:
guideX.left = '20%'; guideX.sidebar = '10%+20'; guideX.right = '10%+420';

Thus, guides become properties of the guideX object with user names.
Now add horizontal guides:
guideY.top = '20'; guideY.content = 170'; guideY.footer = '100%-120'; guideY.bottom = '100%-20';

Now blocks can be attached to the resulting grid.
The block is determined by the coordinates of the upper left and lower right corners.
block.name = 'left, top, right, bottom';For example in our case:

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';
(Of course, the blocks can be defined directly without using guides, but this will make it difficult to understand the layout structure)You can also define a block by specifying the location inside the parent block:
block.name = 'position_ by_x width, position_ by_y, hieght';For example:
block.name = 'center 1000, top 50%';
The third type of indication of the location of the block is an indication of the position of its center, as well as width and height. The construction in this case will look like this:
block.name = 'pos_center center_po_x, center_po_y, width, hieght';When defining a block, you can specify much more parameters for its positioning by simply appending them through the gap. These parameters will be discussed later.
After all the definitions, the
run () function is executed
; which, based on the actual browser window size, block and page sizes, calculates block sizes and coordinates and sets styles for the respective div blocks.
After the changes are tracked on the page for a corresponding change in positioning. For example, in this case, the contents of the sidebar block - may not fit on the screen, which can lead to disruption of the structure. Therefore, changes in block sizes are tracked, and in this case, as the height of the
sidebar block increases, the
guideY.footer will move
accordingly , and the size of the
content block and the position of the
footer block will change accordingly.
Thus, filling the page does not require multiple nested divs. It is enough to describe simply:
<div id=”logo”> </div>
anywhere on the page and the logo will snap into place. At the same time inside the div-block - naturally you can use all the standard html + css markup.
Expansion
Of course, in this form, this add-on can be really useful for few people. An interesting feature appears when using some add-ons.
Nested blocks.

For example, in order to insert a site slogan in the header using the example above, it is convenient to use a nested block.
block.tel = 'in block.logo 10, 100% -50, 100%, 100%';Or in the variant with the side docking
block.tel = 'in block.logo right 100% -10, bottom 50';The nested block is always at a higher level than the parent, so there are no difficulties with overlapping objects.Dependencies
Suppose we need a static design at 1000px, in the center of the window. The easiest way to do this is to use the following code:
block.name = 'center 1000, top 100%';
But in some cases, you may need more complex dependencies, for example, when the content has to be shifted slightly to the left, so that the free space on the left is two times less than on the right ... This can be achieved by adding rules.
guideX.left = ''; guideX.right = ''; rule.my1 = 'guideX.left * 2 = 100% - guideX.right'; rule.my2 = 'guideX.right - guideX.left = 1000';

The first two lines only declare guides, but do not define their values. The second two - set the rules by which the coordinates of the guides are calculated.
By the way, for a variable block width, you can replace the last line with:
rule.my2 = 'guideX.right - guideX.left = 1000 to 1300';
The operator "to" - means that the difference will be from 1000 to 1300, with the priority of the latter.
In fact, when analyzing such a page, a solution of a system of linear equations is performed (or in difficult cases the optimization problem is solved, for example, by the simplex method), and the necessary values ​​are calculated. It is the use of rules in the event of further expansion of the engine can allow to implement complex things by writing the minimum amount of code.
This approach allows you to create flexible dependencies between any blocks in the most simple and natural way. Analyzing the graphic layout of the future site, a person thinks about such rules as "this block stretches ... this static ... this width is equal to this ... this one in the center of this ... etc.". Writing these conclusions in the form of rules is much simpler and more logical than standard approaches to layout. At the same time, combining this approach with the use of block properties (described in the next paragraph) will make it possible to implement really complex structures with just a few rules.
Properties
It is natural to extend the system's ability not only to positioning blocks, but also to other features, where the advantages of interactive code will help solve the problems of correct display. For this, the blocks and guides need to implement additional properties. Of course, the list of properties can be supplemented, I will list the most basic.
Some properties affect the appearance of elements, rather than their positioning, which is somewhat contrary to the concept outlined at the beginning of the article. But this is done intentionally, since such an approach makes it possible to solve many frequently encountered problems as simply as possible.
1. Normal properties
Any specific block property can be accessed directly.
Supported:
block.name.left, block.name.top, block.name.right, block.name.bottom, block.name.width, block.name.height, maybe others.
For example, after the definition:
block.logo = '0, 0,' 100, 50 '; you can refer to
block.logo.left or
block.logo.bottom.Also, I refer the block fill parameter to ordinary properties. By default, any block pulls down as content increases. But writing
block.name.fix = true . You can fix the size of the block.
If it can be implemented qualitatively, it will be possible to add the fit property — content that automatically scales the content according to the block size, by analogy with the corresponding function in publishing systems.
2. Font fitting
block.name.fontsize = 'n%'; - this parameter sets the font size in proportion to the height of the block. This approach allows you to display labels in perfect font size. For example, display a text logo with a height equal to the header of the site, at any resolution.
3. Picture Fit
block.name.image_fit = '[path /] filename [left | top | right | bottom]'; - allows you to fill a block with an image, and the image is scaled in such a way as to fill the entire block. If the second parameter is specified, then when fitting along this side, the image is not cropped.
4. Dragging blocks
block.name.dragX = 'true | false [start [, end]]'; - sets the ability to drag the block along the X axis from start to end, from the current position. Example:
block.tel.dragX = 'true -10, 80%';block.name.dragY = 'true | false [start [, end]]'; - similarly.
Dragging blocks allows you to make simple block animation. For example, such a construction.
block.header = '10%, 20, 90%, 300';
Such a record will allow you to completely determine the structure of the blocks in the header with a slider on three slides, you only need to fill in the corresponding div blocks.

Adding an entry:
block.scroll.dragX = 'true 0, 100% - block.scroll.width'; rule.my1 = block.slider_content.left = - block.scroll.left*3';
Allow dragging the scroll block to rewind the slider inside the block.slider block.
A record:
block.slider_content.dragX = 'true';
Allows you to rewind the slider directly moving it (for example, on the touch screen)
Formal description
Formally, all operators look like this:
guides:
guideX.< > = '<>'; guideY.< > = '<>';
blocks:
block.< > = '[in < >] {<>,<>,<>,<> | {left|center|right} <>, {top|midle|bottom} <> | pos_center <>, <>, <>, <>} [fix] [fit] [font_size <>] [image_fit [/] ] [dragX [<> [,<>]]] [dragY [<> [,<>]]]';
regulations:
rule.< > = '<> = <>';
Where
<number> is any JavaScript expression, or any percentage (to be calculated based on the size of the parent block), or a pair of expressions like
'<number1> to <number2>' - meaning the number in the range from
<number1> to
<number2 > as close as possible to
<number2> . In expressions can not be reserved words:
to, fit, fix, image_fit, left, center, right, top, midle, bottom, pos_center, in, guideX, guideY, block, ruleAfter describing the markup, the
run () function call is sure to go
;In order not to inflate the article, I do not describe the mechanics of the engine. But the essence is simple: the script defines the objects
guideX, guideY, block and
rule . The user then defines the markup by creating properties for these objects and defining values ​​in simple lines. And when you run
run (); - these properties are searched and numeric values ​​are determined. After that, for all properties of the
block object, the corresponding div-blocks are searched for and the corresponding positioning is assigned to the blocks. Drawing is performed cyclically to take into account possible changes in block sizes depending on the content, and after similar rebuildings occur when the page is resized or moving blocks move.

Example
As an example, I will give the code for creating a business card page. The background should display an image that fits the screen size, Top left - the logo and slogan, bottom - contacts. Center block with a slider or other fixed-size content.
Code
<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>

The site is displayed on different screens shown in the figures.
Conclusion
The advantages of the approach include: the absence of garbage in css in the form of additional styles and “crutches”, the ease of developing adaptive layout for any resolutions, setting up positioning logic using simple “rules”, separating positioning rules from the layout and content of the document, the possibility of partial automation of layout using export guides and common markup logic from a psd file using an additional script. Also to the pluses can be attributed to the fact that the engine does not require any action other than connecting the js-file. And the whole "markup language" consists of several typical expressions that are easy to learn and use.
You can also add that today, JavaScript is often used when designing websites to solve problems or develop non-standard elements. The described approach could help to realize many things in a couple of lines, even if a person does not want to use the engine for the layout of the main structure of the page.
For example, to fill a div block with an image, with automatic adjustment to the block size, a string is sufficient.
block.name = 'image_fit background.jpg';
The disadvantages include the need to study a new approach in markup, which is fundamentally different from the existing one, the impossibility of a normal site display without JavaScript, as well as possible problems with an ill-conceived or very complex document structure.
Of course, within the framework of the article it is impossible to show all the possibilities of applying this approach. As well as thoughts about the implementation of the described functionality. However, the idea does not even have two days, so that over time there will probably be many options for its expansion. I hope someone will be interested in such an approach.