Introduction

Overview and examples

Flexi is a responsive-design layout framework like Bootstrap and Foundation. Flexi is focused on performance and maintainability, utilizing Ember for greater configuration and convenience than Bootstrap or Foundation can offer.

Flexi's custom elements and attribute DSL allow us to quickly build layouts without any hand-rolled CSS. The attribute DSL gives us the convenience of attribute syntax with the performance of class based selectors. <box xs="4" sm="hidden"> becomes <box class="col-xs-4 hidden-sm">. The attribute DSL even lets us work with existing Bootstrap and Foundation layouts.

Like Bootstrap and Foundation, we have breakpoints for various screen widths and columns to divide rows. Both breakpoints and columns-per-row are completely customizable, and we can even add additional breakpoints.

Optional viewport-specific templates let us separate our layout concerns by viewport size. Think mobile vs desktop when the layout is drastically different between screen sizes.

Sustain improves the performance of your app by reducing the amount of work your app needs to do. Instead of tearing down one instance and creating an entirely new instance, sustain seamlessly swaps a component instance's location as layouts and routes transition from one position to the next.

Example

Concrete examples can be found on the demo site, but for now we'll walk through a basic layout: a simple navbar that goes from mobile buttons that span their entire row to tabs on desktop.

<screen>
  <page>
    <hbox fit class="navbar">
      <box xs="hidden" sm="1 visible" md="2" lg="3"></box>
      <centered sm="fit">
        {{#link-to "row-col" class="nav"}}Row-Col{{/link-to}}
      </centered>
      <centered sm="fit">
        {{#link-to "grid" class="nav"}}Grid{{/link-to}}
      </centered>
    </hbox>
    <hbox class="content">
      <box xs="hidden" sm="1 visible" md="2" lg="3"></box>
      {{outlet}}
    </hbox>
  </page>
</screen>

Our navbar starts with an <hbox>, a flexi element that lays out elements horizontally, like a row.

We want our nav buttons to become tabs once the user's viewport is large enough, and to offset these tabs to keep them aligned with our content. To accomplish this, we start our navbar with a <box> that will act as an offset.

Our <box> contains an xs="hidden" attribute, hiding it when the screen is "eXtra Small" while our <centered> nav buttons each take a half of the navbar.

Once the screen is large enough, our <box> becomes visible with a width of "1" (sm="1 visible"). At the same time, our centered nav buttons now look like tabs via the fit attribute (sm="fit"), which will shrink them to fit to their content.

Attributes carry over to larger breakpoints unless overridden by a similar attribute (hidden vs visible, column size, etc.), so our visible and fit attributes apply to all breakpoints larger than xs

Rows and Columns

<vbox> <!-- column container -->
  <hbox> <!-- row container -->
    <vbox fit> <!-- sizes to its content -->
      <box>Top</box>
      <box>Bottom</box>
    </vbox>
    <box>Fills remaining space in the row</box>
  </hbox>
  <hbox>
    <box fit>Shrinks to fit content</box>
    <box xs="6">Gets half of the row</box>
    <box>Fills remaining space in the row</box>
  </hbox>
</vbox>

Grids

Grids have no explicit rows, instead they wrap automatically when column size is greater than columns-per-row.

<grid>
  <centered xs="6" sm="4" md="3" lg="2" style="background: aqua;">1</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: orange;">2</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: aqua;">3</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: magenta;">4</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: grey;">5</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: orange;">6</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: aqua;">7</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: magenta;">8</centered>
  <centered xs="6" sm="4" md="3" lg="2" style="background: aqua;">9</centered>
</grid>