How to build better layouts with GSS polyfills

Two-way relationship
You’ve probably noticed that we’re using == instead of =. A   cushion tells the solver not to let the elements overlap. With GSS, you can   create layouts completely independently from DOM structure. The pipe (|) defines the edge of a container element, which is   specified using in(). Notice how we can explicitly set a 10px gap between the cover and card, while using the larger [gap] variable for the other gaps on   the page:

@v |-10-[#cover]-[#follow]-| in(#profile-card) gap([gap]);
Again using one line, let’s centre the follow button horizontally relative to the card:

#follow[center-x] == #profile-card[center-x];
Now we can lay out our row of buttons inside the card   and chain the button tops. button[border-radius] = button[height] / 6;
With one line of GSS, you can accomplish an incredible amount of dynamism that’s maddeningly impossible in CSS. To accomplish that same four-button layout with VFL, all you need is one line:

@h |-[#b1]-[#b2]-[#b3]-[#b4]-| in(#panel) gap(10);
Visual formatting
One nice thing about working with VFL is that it’s visual: you can tell what’s going on with just a quick glance. As powerful as one-line arithmetic constraints are, marginally complex layouts quickly become verbose. The third language – Visual Grid Language (VGL) – is beyond the scope of this particular tutorial. In our four-button example, here’s how we’d   express a layout where #b3 has a weak constraint to be centre-aligned in the #panel, but a   stronger constraint not to get closer than 10px to the other buttons:

#b3[center-x] == #panel[center-x];
@h |-[#b1]-[#b2]~-~[#b3]~-~[#b4]-| in(#panel) gap(10)
!strong;
Intrinsic values
One thing new GSS developers often forget is that constraints live in a separate world to the DOM. VFL enables developers to describe one-dimensional alignments in a terse, visual style. @v |-[#avatar]-[#name]-| in(#cover)
gap([gap]) outer-gap([flex-gap])
chain-center-x(#cover[center-x]);
Now, we’ll stretch the cover horizontally across the   profile-card with a 10px gap:

@h |-10-[#cover]-10-| in(#profile-card);
Next, we’ll align the follow button below the cover image within the card. We believe that if something as groundbreaking as   GSS is possible to make happen in today’s browser, we ought to do it instead of waiting for standards to catch up. Cushions
In addition to gaps, which generate equality (==) constraints, VFL can also generate inequality constraints   (=, =) with cushions, specified using a tilde (~). And, internally a VFL statement simply generates many CCSS statements – so unlike CSS with   its several incompatible layout modes, GSS offers a holistic layout paradigm. Ask yourself this: why is it so hard to centre one element inside another with CSS? GSS doesn’t know about those native properties unless you tell it to measure them from the DOM. However, it’s been almost 15 years since Badros proposed CCSS, and we need this now. When you   allow developers to describe element properties relative to each other, you end up naturally creating cyclic dependencies – logic loops   –   that are extremely difficult to resolve. Each dash (-) represents a gap, defined using gap(). To compute optimal solutions to these constraints, Badros and Borning developed the Cassowary Constraint Solving Toolkit. When the panel gets too narrow, all of the buttons should vertically stack. CSS’s dominant layout mechanism, the float, was first published over a decade ago, when most web pages were just that: static pages, not interactive, responsive web apps. That’s because we’re writing constraints, not variable assignments. Unfortunately, Cassowary remained a purely academic accomplishment for about a decade, until Apple decided that it needed a better layout paradigm for the growing number of different screen resolutions being used. Fortunately, a better future is   arriving early. GSS: The basics
So, how would you centre an element inside another in CSS? With GSS conditionals, you can design layouts that adapt not just to screen size, but to any property. That’s why GSS comes with @if and @else. Let’s use cushions to   keep the name within the horizontal bounds of the cover; we’ll make the alignment !strong to ensure the width of the cover and panel stay large enough to   satisfy this constraint. For sake of brevity, constraints will primarily use id selectors, only structure.gss will be covered and   texture.css will be omitted (check out the for a live demo). This article originally appeared in net magazine issue 256. The first language is Constraint CSS (CCSS). By default, all constraints are weak. You can centre any element inside another with a one-liner:

#element1[center-y] == #element2[center-y];
Want to give all of your buttons a border-radius relative to their height? We’ve implemented a webified version of VFL in GSS. GSS comes with four strengths: !weak, !medium, !strong and !require, which makes a   constraint mandatory. You shouldn’t wait, either. Then, we’ll   throw in a chain function to align the   center-x of the two aligned elements with the cover’s center-x. To   change this, you can add a strength, which look like CSS’s !important. That’s a useful tool, but we believe designers need more flexibility. The result was Cassowary-based Cocoa Auto Layout, which now   powers Mac OS   X and iOS. Setting up GSS is simple: just include the necessary JavaScript files and use type=”text/gss” on link tags that load .gss files or style tags with inline GSS. When the card is taller than it is wide, we want to simplify the layout by vertically stacking all of the buttons inside the cover photo:

@else {
@h |-10-[#cover]-10-| in(#profile-card);
@v |-10-[#cover]-10-| in(#profile-card);
@v |-[#avatar]-[#name]-[#follow]-[#message]-
[#following]-[#followers]-|
in(#cover)
gap([gap]) outer-gap([flex-gap])
chain-center-x(#profile-card[center-x]);
}
True source-order independence
Do you see how the panel and buttons take on a   parent-child relationship, even though there’s no   nesting of the HTML elements? The @h directive defines a horizontal layout, @v specifies vertical ones. This is true source-order independence. As platforms like iOS and OS X evolve to give their developers powerful new layout tools, the web platform looks increasingly unattractive to   new   developers. Try doing that with old-school CSS,   or   even Flexbox! By using cushions around the follow button, it can slide around to satisfy the centre constraint if there is space for it   to   do so:

@h |-[#message]~-~[#follow]~-~[#following]-[#followers]-|
in(#profile-card)
gap([gap])
chain-top
!strong;
}
Finally, let’s finish our conditional. Given the flat HTML:

div id=”profile-card”/div
div id=”cover”/div
div id=”avatar”/div
h1 id=”name”Dan Daniels/h1
button id=”follow” class=”primary”Follow/button
button id=”following”Following/button
button id=”followers”Followers/button
button id=”message”Message/button

Let’s create the layout below, where the follow button has a weak constraint to stay in the middle of the panel, but stronger constraints to not get too close to   the other buttons. In our four-button example, how would you specify button width if you wanted it to be the width of its text plus padding? Aligned elements are specified inside square brackets ([]). In this tutorial, I’m going to introduce you   to the fundamentals of the first two. Here, we’re using required intrinsic values to make sure the solver understands the size of the name element’s text. Forget the hacks. At The Grid (thegrid.io) we’re developing a product that requires adapting complex layouts to content and devices. Constraints represent two-way relationships between properties. Not Just An Experiment

GSS is still under development and there are a few missing pieces to be added, but we’re so confident about it that we’re using GSS to build our flagship consumer product, The Grid. We think GSS has the potential to be the future of web layout, and we’d love to see it standardised. @if #profile-card[width] = #profile-card[height] {
Next, when we vertically align the avatar and   name within the cover, we’ll vertically centre the   alignment by using [flex-gap] as the outer-gap. @If, Or @Else! }
Putting it all together
Now that you’ve got a feel for CCSS and VFL, let’s put it together into a simple, real-world layout. Variables
Of course, GSS supports custom constraint variables. Strengths
When constraints conflict, the stronger one overcomes. Unfortunately, new CSS features such as Flexbox insist on coupling layout to content, and even proposed future features won’t address basic problems such as relative centre alignment. Let’s say you want to build a panel with a row of four buttons and 10px of spacing.

Updated: 29 ноября, 2014 — 9:12 пп