|
5 | 5 | color: b
|
6 | 6 | layout: post
|
7 | 7 | ---
|
| 8 | +Soon after the W3C introduced Cascading Style Sheets, [Greg Badros](http://www.badros.com/greg/), the author of the Cassowary Constraint |
| 9 | +Solver & [recently retired Facebook VP](http://allthingsd.com/20130920/facebook-engineering-and-products-vp-greg-badros-to-leave-company/), |
| 10 | +proposed [Constraint CSS (CCSS)](http://www.cs.washington.edu/research/constraints/web/ccss-uwtr.pdf) as a general solution for CSS layout. |
| 11 | +Back in '99 Badros demonstrated *responsive* layouts with CCSS that today's designers still can't reproduce without grinding out piles of JavaScript. |
| 12 | +For more than a decade, no one seemed to take notice outside academia... Until Apple implemented Cassowary & Greg's pioneering concepts in its new |
| 13 | +AutoLayout engine with the launch of OS X Lion. Despite the evolutionary leap for app developers, web designer's have had to settle |
| 14 | +with [float-based](http://www.sitepoint.com/give-floats-the-flick-in-css-layouts/) & table-based layouts that have remained unimproved to this day. |
8 | 15 |
|
9 |
| -Constraints allows you to design great layout. |
| 16 | +> "We should contemplate how very, very far behind the web platform is in making it delightful to build the sorts of things that are work-a-day in native environments." <a href="http://infrequently.org/2012/02/misdirection/">Alex Russell</a> |
10 | 17 |
|
11 |
| -## Constraints |
| 18 | +The foundation of GSS is a modernized implementation of CCSS. From CCSS primitives other, more exotic layout API's can and are accomplished. |
12 | 19 |
|
13 |
| -Constraints express [relationships between variables](#constraintsaretwoways) that [may or may not hold](#mayofmaynothold). You can constrain any numerical style property of an element, not just its position & size. |
| 20 | +## Constraints, the basics |
| 21 | + |
| 22 | +Constraints express [relationships between variables](#constraintsaretwoways) that [may or may not hold](#mayofmaynothold). You can constrain any |
| 23 | +numerical style property of an element, not just its position & size. |
14 | 24 |
|
15 | 25 | For example, if I want all paragraph tags to have line-height greater than 16px and less than 1/12th the size of the window:
|
16 | 26 |
|
17 |
| - {% highlight css %} |
| 27 | +{% highlight css %} |
18 | 28 |
|
19 | 29 | p[line-height] >= 16;
|
20 | 30 | p[line-height] <= ::window[height] / 12;
|
|
78 | 88 |
|
79 | 89 | {% highlight css %}
|
80 | 90 |
|
81 |
| - #gss { |
82 |
| - width: == 200; |
83 |
| - } |
84 |
| - |
85 |
| - #cassowary { |
86 |
| - width: == 200; |
87 |
| - } |
88 |
| - |
89 |
| - #gss[width] + #cassowary[width] == 350; |
| 91 | +#gss[width] == 200; |
| 92 | +#cassowary[width] == 200; |
| 93 | +#gss[width] + #cassowary[width] == 350; |
90 | 94 |
|
91 | 95 | {% endhighlight %}
|
92 | 96 |
|
93 | 97 | In the previous example, we're asking GSS to give the `#GSS` and `#cassowary` elements a width of 200px and we
|
94 | 98 | later declare a constraint for the sum of these two elements to be equal to 350px. In this case, one of these
|
95 |
| -two constraints will not hold. As we'll see later in the documentation you can influence the constraints solving |
96 |
| -by given more intent to GSS about what you want. <a href="http://codepen.io/cbchouinard/pen/XJROdV" target="_blank">Live example.</a> |
| 99 | +two constraint will not hold. <a href="http://codepen.io/cbchouinard/pen/XJROdV" target="_blank">Live example.</a> |
| 100 | + |
| 101 | +As we'll see next, you can influence the constraints solving by given more information to GSS about your intent. |
97 | 102 |
|
| 103 | +<a name="strenghts"></a> |
98 | 104 | ### Strenghts
|
99 | 105 | Strenghts allows you to guide GSS in your layout intention by giving the GSS constraints solver more details about which constraints you prioritize.
|
100 | 106 |
|
|
121 | 127 |
|
122 | 128 | `!medium` is the default for all constraints when no strenght is explicitly defined.
|
123 | 129 |
|
124 |
| -Using the [May or may not hold example](#mayofmaynothold) example we saw previously, |
125 |
| -we'll give in the following example more strenghts to the each individual `width` to |
| 130 | +Using the [May or may not hold](#mayofmaynothold) example we saw previously, |
| 131 | +we'll now give a stronger strenght to each individual `width` constraints to |
126 | 132 | make sure they overcome the sum constraints: <a href="http://codepen.io/cbchouinard/pen/bNRbQg" target="_blank">Live example.</a>
|
127 | 133 |
|
128 |
| - |
129 | 134 | #### !require strenght
|
130 | 135 | `!require` is a special strength that guarantees the constraint will hold, otherwise everything breaks.
|
131 | 136 |
|
132 |
| -**Pro Tip** Use `!require` carefully & sparingly. `!require`'s quickly lead to systems where |
| 137 | +**Pro Tip** Use `!require` carefully & sparingly. `!require`'s quickly lead to systems where |
133 | 138 | all required constraints cannot be satisfied.
|
134 | 139 |
|
135 | 140 | For example, the following GSS expressions will be unsolvable:
|
136 | 141 |
|
137 | 142 | {% highlight css %}
|
138 | 143 |
|
139 |
| - #gss { |
140 |
| - width: == 200 !require; |
141 |
| - } |
142 |
| - |
143 |
| - #cassowary { |
144 |
| - width: == 200 !require; |
145 |
| - } |
146 |
| - |
147 |
| - #gss[width] + #cassowary[width] == 350 !require; |
| 144 | +#gss[width] == 200 !require; |
| 145 | +#cassowary[width] == 200 !require; |
| 146 | +#gss[width] + #cassowary[width] == 350 !require; |
148 | 147 |
|
149 | 148 | {% endhighlight %}
|
150 | 149 |
|
151 |
| -We're asking GSS to find a solution where the width of the #gss and #cassowary element must absolutely be 200px |
152 |
| -and their sum must absolutly be 350px which is impossible. |
| 150 | +We're asking GSS to find a solution where the widths of the #gss and #cassowary element must be 200px |
| 151 | +and their sum must be 350px which is impossible. |
153 | 152 |
|
154 | 153 | ### Constraints order
|
155 | 154 | Generally speaking, later constraint statements are more powerful than earlier ones. There could be exception
|
156 |
| -to this behavior as well see in the following sections. |
| 155 | +to this behavior as we'll see in the following sections. |
157 | 156 |
|
158 |
| -Taking the [May or may not hold example](#mayofmaynothold) we saw previously, by changing the order you'll get a |
| 157 | +Taking the [May or may not hold example](#mayofmaynothold) we saw previously, by changing the order of the constraints you'll get a |
159 | 158 | different result. <a href="http://codepen.io/cbchouinard/pen/rawBRr" target="_blank">Live example.</a>
|
160 | 159 |
|
161 |
| -## Stays <a name="stays"></a> |
162 |
| - |
163 |
| -Ambiguity can be largely overcome by declaring more constraints, but what about situations like: |
164 |
| - |
165 |
| -{% highlight css %} |
166 |
| - |
167 |
| -#box[right] == ::window[right]; |
168 |
| -#box[width] >= 100; |
169 |
| -#box[left] >= 100; |
170 |
| - |
171 |
| -/* the #box's width will stretch */ |
172 |
| - |
173 |
| -{% endhighlight %} |
174 |
| - |
175 |
| -Will the `#box` move or stretch to satisfy the last constraint? Again, the later constraint statements are more |
176 |
| -powerful than later ones, so the box's width would stretch. You can control this by either changing the order in |
177 |
| -which the constraints are declared or by using a `stay` like so: |
178 |
| - |
179 |
| -{% highlight css %} |
180 |
| - |
181 |
| -#box[right] == ::window[right]; |
182 |
| -#box[width] >= 100; |
183 |
| -#box[left] >= 100; |
184 |
| -@stay(#box[width]); |
185 |
| - |
186 |
| -/* the #box's position will move */ |
187 |
| -{% endhighlight %} |
188 |
| - |
189 |
| - |
190 |
| -Many `stay`s can be declared at once with `@stay([var1],[var2],[var3])`. |
191 |
| - |
192 |
| - |
| 160 | +<a name="lineararithmetic"></a> |
193 | 161 | ## Linear Arithmetic
|
194 | 162 |
|
195 | 163 | Cassowary only allows for "Linear Arithmetic" constraints, you can do simple math operations like `+`, `-`, `*` and `/`,
|
196 | 164 | but all expressions must be linear (of the form `y = mx + b`). Basically, you can do most things except multiply or
|
197 |
| -divide two constraint variables. |
| 165 | +divide two constraint variables. <a href="http://codepen.io/cbchouinard/pen/MYvOWO" target="_blank">Live example.</a> |
198 | 166 |
|
199 | 167 | {% highlight css %}
|
200 | 168 |
|
|
204 | 172 |
|
205 | 173 | {% endhighlight %}
|
206 | 174 |
|
207 |
| -I wish we could go non-linear, but we can't because math. |
| 175 | +We wish we could go non-linear, but we can't because math. |
208 | 176 |
|
209 | 177 | ## Units of measurement
|
210 | 178 | Default unit in GSS are pixels. GSS also supports the following units:
|
|
214 | 182 | #pourcentage[width] == 10%;
|
215 | 183 | {% endhighlight %}
|
216 | 184 |
|
| 185 | +<a name="selectors"></a> |
217 | 186 | ## Selectors
|
218 | 187 |
|
219 |
| -GSS Selectors guide: [view all selectors](/guides/selectors) |
| 188 | +GSS supports many selectors to allow you to select elements for which you want to declare constraints. |
220 | 189 |
|
| 190 | +{% highlight css %} |
| 191 | +.className > #someElm ~ div { |
| 192 | + width: == 100; |
| 193 | +} |
| 194 | +{% endhighlight %} |
| 195 | + |
| 196 | +Since we have a lot of selector we've dedicated a guide for them. We invite you to scroll all the way |
| 197 | +down in that guide, there's some useful information there: [GSS Selectors Guide](/guides/selectors) |
| 198 | + |
| 199 | +Note that this guide is refering to [ruleset](rulesets) which are covered next. |
| 200 | + |
| 201 | +<a name="rulesets"></a> |
221 | 202 | ## Rulesets
|
222 | 203 | GSS allows you to declare constraint using ruleset as with CSS:
|
223 | 204 |
|
|
289 | 270 | In this example `(^ #elm)` will search for a `#elm` element contained in the current element having
|
290 | 271 | the `.container` class. <a href="http://codepen.io/cbchouinard/pen/yyXPej" target="_blank">Live example.</a>
|
291 | 272 |
|
292 |
| - |
| 273 | +<a name="variablesandscope"></a> |
293 | 274 | ## Variables and scope
|
294 | 275 | Declaring a variable in GSS is as simple as using it:
|
295 | 276 |
|
|
690 | 671 |
|
691 | 672 | {% endhighlight %}
|
692 | 673 |
|
693 |
| -In this example we are constraining `#elmA` and `#elmB` against the virtual element. |
| 674 | +In this example we are constraining `#elmA` and `#elmB` against the virtual element. |
694 | 675 |
|
695 | 676 | Virtuals are very handy with [VFL](/guides/vfl-guide).
|
0 commit comments