CSS extensions in h-smile engine. Part II. Flex units.

Flex length units are "weights" used in distribution of free space along some direction.

Example of the document with flex units:

<html>
<head>
  <style>
  div.outer
  {
    border:red 2px dashed;
    width:400px;
    height:250px;
  }
  div.inner 
  { 
    margin-left:30%%; width:50%; margin-right:70%%; 
    height:100%%;
    background:gold; border:brown 4px solid; 
  }
  </style>  
<head>
<body>

  <div class="outer">
    <div class="inner"></div>
  </div>
  
</body>
</html>

This document will be rendered in h-smile engine as:



As you see left and right margins of div.inner are distributed as 30:70 and they span whole free space left from width:50% and borders of the div.inner.


Key point here is distribution of free space. Computation of flex units happens as a last phase of layout algorithm – when container’s dimensions are known and all non-flex lengths were computed. Space left from fixed lengths will be distributed among elements and parts given in flexes.


Here is another example that demonstrates weighted distribution of heights:

<html>
<head>
  <style>
  div.outer
  {
    border:red 2px dashed;
    width:400px;
    height:250px;
  }
  div.inner1 
  { 
    height:1*;
    margin:4px;
    background:gold; border:brown 4px solid; 
  }
  div.inner2 
  { 
    height:2*;
    margin:4px;
    background:lightblue; border:navy 4px solid; 
  }
  </style>  
<head>
<body>
  <div class="outer">
    <div class="inner1"></div>
    Some text in between.
    <div class="inner2"></div>
  </div>
</body>
</html>

And its rendering:



As we see here heights of div.inner1 and div.inner2 are distributed using given 1:2 ratio (1* and 2*).


Notation of flex units


There are two equivalent forms of flex length notation: N%% and N*. These two forms are different by multiplier: 1* is exactly 100%%.


Computation details


If sum of flexes in the space that needs to be distributed is less than 100%% then some free space (remainder) will be left undistributed. If sum is equal or more than 100%% then all flex values are used as weights in distribution so all free space will be “covered by flexes”.


Nothing new under the sun


Idea of flex units for CSS was taken from HTML 4.0 relative length units . Flex units in N* notation are used there as values of cells dimensions. ( I do not know any html rendering engine that has this part of standard implemented though ).


XUL specification has also concept of flexes. Flexibility of widths (?) or heights(?) of elements in container is defined by the flex attribute.


Why flex’es are so good?



  1. Flex units allows to position elements with respect of other content on the page. For example if user will change base font size of the document then dimensions given in flexes will be recalculated accordingly. In principle design based on flex units will produce layout that is more stable to changes of platform dependent things – font sizes and types, screen sizes. etc.

  2. Flex units allows to position elements staying in static layout mode – without need of position:relative, absolute.

  3. Flex units significantly reduce need of use of tables or JavaScript code for layout purposes.