Overconstrained:
The Secret Lives of Rectangles

Alex Russell <slightlyoff@google.com>
TXJS, June 14, 2012
@slightlylate

...and this talk isn't about any of that

I want to talk about this.

Wikipedia
Stanford

They figured out how to solve optimization problems:

"Maximize Z subject to the following constraints..."

Lets say it in (pseudo)math

Constraints: 

  Mountain <= 4
  Road <= 7
  Mountain + Road <= 6

  0 <= Mountain, Road, etc.  // Not negative!

Maximize(Z) = (15 * Mountain) + (10 * Road) // profit

What does this have to do with CSS?

CSS Is About Constraints


Wikipedia

<!doctype html>
<html>
  <head>
    <style>
      body > article {
        width: 30%;
        min-width: 50px;
        max-width: 50em;
      }

      @media screen and (max-width: 570px) {
        body > article { width: 100%; }
      }
    </style>
  </head>
  <body>
    <article>...</article>
  </body>
</html> 

CSS Is About Constraints
on Boxes

Stanford
flickr.com/photos/fdecomite/1423775059

Boxes in math

  Right = Left + Width
  Bottom = Top + Height

Box Relationships

  Top = other.Top + padding
  Left = other.Left + padding
  Right = other.Right - padding
  Bottom = other.Bottom - padding

Boxes in Constraints

  var left = v(), right = v(), bottom = v(), top = v();
  var width = v(), height = v();

  constrain( // Not negative
    geq(left, 0), geq(right, 0), geq(bottom, 0), geq(top, 0),
    geq(width, 0), geq(height, 0)
  );
  constrain( // The simplest box model ever.
    eq(right,  plus(left, width)),
    eq(bottom, plus(top, height))
  );
  // Set a position
  constrain(eq(left, 50), eq(top, 50));
  // Set our width/height
  constrain(eq(width, 150), eq(height, 90));
  var Box = inherit({
    initialize: function(id) {
      this.id = id;
      this._left = v();   this._right = v();
      this._bottom = v(); this._top = v();
      this._width = v();  this._height = v();
      constrain(
        geq(this._left, 0),  geq(this._right, 0),
        geq(this._bottom, 0), geq(this._top, 0),
        geq(this._width, 0), geq(this._height, 0)

        eq(this._right,  plus(this._left, this._width)),
        eq(this._bottom, plus(this._top, this._height))
      );
    },
    set left(v)   { constrain(eq(this._left,   v)); this.layout(); },
    set top(v)    { constrain(eq(this._top,    v)); this.layout(); },
    set width(v)  { constrain(eq(this._width,  v)); this.layout(); },
    set height(v) { constrain(eq(this._height, v)); this.layout(); },

    layout: function() { /* Copy styles here */ },
  });

Relationships

  var outer = new Box("outer");
  outer.left = 50;
  outer.top = 50;
  outer.width = 150;
  outer.height = 90;

  var inner = new Box("inner");
  inner.left = plus(outer._left, 10);
  inner.top = plus(outer._top, 10);
  inner.width = 100;
  inner.height = 50;

So What?

panels.js

Panels

  var p = new Panel();
  document.body.appendChild(p);

  p.left = 200;
  p.top = 150;
  p.width = 100;
  p.height = 100;
  p.debug = true;
  p.movable = true;

  var p2 = new Panel();
  document.body.appendChild(p2);
  p.width = 140;
  p.height = 100;
  p.rightOf = p2;
  p.above = p2;
  p.debug = true;
  p.movable = true;

Yes, but what Completely Uselss stuff can it do?

Thank you!

Questions?

@slightlylate