Enyo Daily #4 - Box Model
The flexible box controls and layouts in Enyo are really just convenience wrappers around the standard CSS3 flexible box model. If you haven't looked into the CSS method before, I suggest you take a few moments to look into it. Ajaxian has a post that gives you a quick intro; Html5 Rocks has another good one. W3C also has the draft spec for perusal; there's also an earlier draft that appears to match WebKit's implementation a little more closely.
[[MORE]]There are two ways in Enyo to implement a flexible layout: FlexBox and FlexLayout. You could also code the CSS yourself which is completely legal so I suppose there are 3 ways ... but let's pretend you don't want to do that right now. The key difference between the Box and the Layout is that the former is a Control and the latter a Component. This means that HFlexBox and VFlexBox are renderable DOM nodes whereas HFlexLayout and VFlexLayout are not.
In reality, all of the relevant code is provided by the Layout components. The HFlexBox and VFlexBox are simply Controls with layoutKind set to their appropriate layout. I've found that I use the FlexBoxes when I just need a generic control to layout child controls and the FlexLayouts when I'm using a more complex kind.
One key difference between the "usual" implementation of the flexible box model and enyo's is how it handles the flexed components. Normally, a node that is flexed will be given its natural space and its portion of the remaining. In enyo, it only receives the left over space. It accomplishes this by setting the width of the node to 0px as an inline style. Here's the comment from FlexLayout:
// we redefine flex to mean 'be exactly the left over space'
// as opposed to 'natural size plus the left over space'
The result of this is that some components might be forced to overlap if the remaining space isn't sufficient to hold them. Here's a quick example:
var _Example = {
name:"com.technisode.example.App",
kind:"Control",
components:[
{kind:"HFlexBox", components:[
{flex:1, components:[
// on a 1024x768 screen, this button will be overlapped
// by the next one because it only gets the
// remaining space
{kind:"Button", width:"500px"}
]},
{kind:"Button", width:"300px"},
{kind:"Button", width:"300px"}
]}
]
};
enyo.kind(_Example);