Layout
From FHTML
Contents |
1 What's the same as html?
- Before getting into what aspects of layout are the same as html, let's first say what's different. Html's wrap layout strategy is not optimal for application layout.
- So FluidHtml takes the position that you are probably creating an application. To that end, we provide as much functionality as we can to help you! But FluidHtml doesn't support wrap layout (except in text of course) as it would probably just get in your way.
- FluidHtml supports the new CSS3 display:box model via the
box-orientandbox-alignproperties.
1.1 box-orient (horizontal/vertical)
The box-orient property (vertical/horizontal/none) determines how children of an element will be rendered (horizontal is default). In this example the blue boxes will be alined vertically within the red box.
<style type="text/fhtml">
.vBox {
box-orient:vertical;
w:auto;
h:auto;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.vBox>div {
w:100;
h:100;
box-shadow:inset 2px 2px 8 #666666;
margin-top:20px;
}
</style>
<div class="vBox" >
<div />
<div />
<div />
</div>
.vBox {
box-orient:vertical;
w:auto;
h:auto;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.vBox>div {
w:100;
h:100;
box-shadow:inset 2px 2px 8 #666666;
margin-top:20px;
}
</style>
<div class="vBox" >
<div />
<div />
<div />
</div>
1.2 box-align
- In an element where box-orient is 'vertical', all children will be layed out vertically. But how will they be placed horizontally? The
box-alignproperty answers this question.
<style type="text/fhtml">
.vBox {
box-orient:vertical;
w:300;
h:auto;
background:white;
border:none;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.vBox>div {
box-align:center;
w:100;
h:100;
background:#F4F4F4;
border:none;
border-radius:0px;
box-shadow:inset 8px 8px 8 #666666;
margin-top:20px;
}
</style>
<div class="vBox" >
<div />
<div />
<div />
</div>
.vBox {
box-orient:vertical;
w:300;
h:auto;
background:white;
border:none;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.vBox>div {
box-align:center;
w:100;
h:100;
background:#F4F4F4;
border:none;
border-radius:0px;
box-shadow:inset 8px 8px 8 #666666;
margin-top:20px;
}
</style>
<div class="vBox" >
<div />
<div />
<div />
</div>
1.3 padding and margins
- All html padding and margin properties are supported.
- In this example, secret
*drawingLayer.showPaddingAndMargins:true;property displays margins and borders of elements. Red lines are padding, blue lines are margins.
<style type="text/fhtml">
.vBox {
box-orient:vertical;
alpha:.7;
w:300;
h:auto;
background:white;
border:none;
padding:30px;
padding-right:10px;
box-shadow:8px 8px 8 #666666;
}
/*Set props on children*/
.vBox>div {
w:100;
h:100;
background:#F4F4F4;
border:none;
margin:20px;
margin-bottom:10px;
box-shadow:inset 8px 8px 8 #666666;
/*This is secret fhtml stuff!*/
*drawingLayer.showPaddingAndMargins:true;
}
</style>
<div class="vBox" >
<div />
</div>
.vBox {
box-orient:vertical;
alpha:.7;
w:300;
h:auto;
background:white;
border:none;
padding:30px;
padding-right:10px;
box-shadow:8px 8px 8 #666666;
}
/*Set props on children*/
.vBox>div {
w:100;
h:100;
background:#F4F4F4;
border:none;
margin:20px;
margin-bottom:10px;
box-shadow:inset 8px 8px 8 #666666;
/*This is secret fhtml stuff!*/
*drawingLayer.showPaddingAndMargins:true;
}
</style>
<div class="vBox" >
<div />
</div>
2 What's extra?
2.1 box-orient (none)
- Accepting 'none' as an argument for
box-orientallows FluidHtml to be very flexible regarding layout.
- Where html wants to continually wrap elements, sometimes what developers want is to simply align an element to a point on the screen, according to a coordinate rule, function or whatever.
- The many aspects of layout with FluidHtml that make it flexible and powerful are fundamentally enabled by
box-orient:none.
In this example we set box-orient:none on the main fhtml div. It's children can then be placed anywhere. In this case we place a vertical box at bottom right and a circle at center left.
<style type="text/fhtml">
.containerRight {
box-orient:vertical;
/*Because we've set box-orient:none on parent element,
we can set x and y to any values*/
x:right|-20;
y:bottom|-20;
w:auto;
h:auto;
background:#F4F4F4;
border:black;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.containerRight > div {
w:100;
h:100;
background:#F4F4F4;
border:none;
box-shadow:inset 2px 2px 8 #666666;
margin-top:20px;
}
.circleLeft {
x:left|20;
y:center;
shape:circle;
w:50;
h:50;
background:#F4F4F4;
border:none;
box-shadow:8px 8px 8 #666666;
}
</style>
<!--This box lets its children be aligned anywhere! -->
<div style="box-orient:none;" >
<div class="containerRight" >
<div />
<div />
<div />
</div>
<div class="circleLeft" />
</div>
.containerRight {
box-orient:vertical;
/*Because we've set box-orient:none on parent element,
we can set x and y to any values*/
x:right|-20;
y:bottom|-20;
w:auto;
h:auto;
background:#F4F4F4;
border:black;
box-shadow:8px 8px 8 #666666;
padding:0px 20px 20px 20px;
}
/*Set props on children*/
.containerRight > div {
w:100;
h:100;
background:#F4F4F4;
border:none;
box-shadow:inset 2px 2px 8 #666666;
margin-top:20px;
}
.circleLeft {
x:left|20;
y:center;
shape:circle;
w:50;
h:50;
background:#F4F4F4;
border:none;
box-shadow:8px 8px 8 #666666;
}
</style>
<!--This box lets its children be aligned anywhere! -->
<div style="box-orient:none;" >
<div class="containerRight" >
<div />
<div />
<div />
</div>
<div class="circleLeft" />
</div>
2.2 x and y
- Html makes it difficult to simply set
xandy(left and top).floatdoesn't really get it done;box-aligndoesn't really get it done. And in a standard html wrap coordinate system, it's a big pain.
- In FluidHtml, it's easy. Set
box-orientof your parent element to 'none' and you can set x and y (or left and top - they're interchangeable) to your heart's content.
<style type="text/fhtml">
#test {
x:100;
y:100;
width:200;
height:200;
background:#F4F4F4;
box-shadow:8px 8px 8 #666666;
border:none;
}
</style>
<div style="box-orient:none;" >
<div id="test"></div>
</div>
#test {
x:100;
y:100;
width:200;
height:200;
background:#F4F4F4;
box-shadow:8px 8px 8 #666666;
border:none;
}
</style>
<div style="box-orient:none;" >
<div id="test"></div>
</div>
2.3 Using simple umbers
- You don't need to say 'px' all the time!
y:20;
width:100;
height:100;
width:100;
height:100;
2.4 Offsets
- FluidHtml allows you to, essentially, set margins in the same declaration that you're setting a coordinate.
- Here we use
xto set the horizontal alignment of an element in a vertical box toright|-20. It will be aligned to the right with a 20px margin. - This example will launch in a new window so you can resize it easily.
x:right|-20;
y:bottom|-20;
width:50%;
height:50%;
y:bottom|-20;
width:50%;
height:50%;
2.5 Less nesting of boxes
- In html, people have gotten used to nesting elements inside one another to achieve a layout goal. With FluidHtml, it's often possible to create elements at the same level using percentage-based rules and offsets.
- Here we create top, left, middle and right css styles and then put four elements (no nesting) on the page that use them.
- This example will launch in a new window so you can resize it easily.
<style type="text/fhtml">
#fhtml {
box-orient:none;
}
div {
background:#666666;
box-shadow:inset 2px 2px 8px #FFFFFF;
}
#top {
h:65;
w:100%;
}
#left {
y:65;
w:120;
h:100%|-65;
}
#middle {
x:120;
y:65;
w:100%|-370;
h:100%|-65;
}
#right {
x:100%;
y:65;
w:250;
h:100%|-65;
}
</style>
<div id="top"/>
<div id="left"/>
<div id="middle"/>
<div id="right"/>
#fhtml {
box-orient:none;
}
div {
background:#666666;
box-shadow:inset 2px 2px 8px #FFFFFF;
}
#top {
h:65;
w:100%;
}
#left {
y:65;
w:120;
h:100%|-65;
}
#middle {
x:120;
y:65;
w:100%|-370;
h:100%|-65;
}
#right {
x:100%;
y:65;
w:250;
h:100%|-65;
}
</style>
<div id="top"/>
<div id="left"/>
<div id="middle"/>
<div id="right"/>
2.6 Aligning elements to other elements
- You can 'slave' a coordinate of one element to another. The syntax is as follows:
masterElement|edge|offset;
- The 'masterElement' can be acquired by a simple id or by executing a script. In the following example, y:master|bottom|20; sets the elements y property to align to the bottom edge of
masterwith an offset of 20. - In the following example we only animate the master element. The slave follows.
- Use this syntax to keep an element aligned to the edge of another element no matter what changes occur in the first element, even while animating.
- There is a bug when animating reference-based coordinates as in the example below (x and y values aren't refreshing). We know about it and are working on it.
<style type="text/fhtml">
#master {
x:20;
y:20;
width:60;
height:60;
}
#slave {
x:master|right|20;
y:master|top|20;
width:master|width|0;
height:master|height|0;
}
</style>
#master {
x:20;
y:20;
width:60;
height:60;
}
#slave {
x:master|right|20;
y:master|top|20;
width:master|width|0;
height:master|height|0;
}
</style>
2.7 Aligning elements using javascript in CSS
- FluidHtml allows you to use javascript (within CSS) to assign coordinates.
- This is immensely useful - enjoy.
- In the following example, the red div will always be 1/2 the width of its parent as the parent resizes. Of course, you can use any mathematical equation to set any value - this is just a simple example.
- This demo will launch in a separate window to make it easy for you to test resizing.
<style type="text/css">
div {
y:50;
w:javascript:getCoord(); /*Set coordinates with javascript from CSS.*/
h:100;
background:#F4F4F4;
border:none;
box-shadow:8px 8px 8 #666666;
}
</style>
<script type="text/javascript" fhtmlignore="false" >
/*This function will be recalled whenever coord needs update,
like when parent resizes */
function getCoord() {
return root.width * .5;
}
</script>
<div/>
div {
y:50;
w:javascript:getCoord(); /*Set coordinates with javascript from CSS.*/
h:100;
background:#F4F4F4;
border:none;
box-shadow:8px 8px 8 #666666;
}
</style>
<script type="text/javascript" fhtmlignore="false" >
/*This function will be recalled whenever coord needs update,
like when parent resizes */
function getCoord() {
return root.width * .5;
}
</script>
<div/>
2.8 XYRB coordinates
- Most coordinate systems use x, y, width and height. But sometimes it's useful to think of an element in terms of its 'edges' rather than its size. So FluidHtml allows you to define an element's coordinates in terms of x, y, right and bottom.
-
rightis interchangeable withr;bottomis interchangeable withb.
<style type="text/css">
#fhtml {
box-orient:none;
}
div {
x:50%;
y:50%;
r:100%|-20;
b:100%|-20;
background:#F4F4F4;
border:none;
box-shadow:10px 10px 8 #666666;
}
</style>
<div/>
#fhtml {
box-orient:none;
}
div {
x:50%;
y:50%;
r:100%|-20;
b:100%|-20;
background:#F4F4F4;
border:none;
box-shadow:10px 10px 8 #666666;
}
</style>
<div/>
2.9 Animation and 'auto'
- Like html, FluidHtml supports 'auto' as a value for width and height. However, FluidHtml elements that use auto will automatically expand and shrink to accommodate their children no matter how those children animate.
- So, if any child of an element with width or height of auto is animated in any way that changes that child's size or position, the parent will respond.
This example shows:
- How to start an animation.
- How to use a script to assign an endpoint of an animated property.
- How autoSizing elements respond to animation of their children.
- How to switch targets from frame to frame in an animation. (You can even switch per action...)
<style type="text/css">
div {
background:#F4F4F4;
border-radius:8px;
}
.vBox {
x:center;
y:center;
width:auto;
height:auto;
box-orient:vertical;
box-shadow:8px 8px 8 #999999;
padding:20px;
}
.vBox>div {
w:60;
h:60;
box-shadow:inset 6px 6px 8 #999999;
}
</style>
<script type="text/javascript" fhtmlignore="false" >
//This function starts an animation on a div
function doAnimation() {
$('anim').start('controls');
}
//This function is called in an animation frame to get end value
function getTweenValue() {
return parent.height/2;
}
//Start the animation
doAnimation();
</script>
<div id="fhtml" >
<div style="box-orient:none" >
<div class="vBox" >
<div />
<div />
<div id="anim" />
<div id="last" />
</div>
</div>
</div>
<style type="xml/fhtmlassets" >
<animation name="controls" easing="inOutExpo" >
<frame>
<action property="x" end="500" />
</frame>
<frame>
<action property="x" end="300" />
</frame>
<frame>
<!--Here we switch targets in a frame.
Any script can be run to get new target. -->
<action target="previousSibling" property="h" end="Math.cos(90)+30;" />
</frame>
<frame>
<action property="h" end="javascript:getTweenValue();" />
</frame>
<frame>
<!--Use an imported utilty class method to get end value-->
<action target="last" property="h" end="+=100" />
</frame>
<frame>
<action target="last" property="h" end="20" />
</frame>
<frame>
<action target="last" property="y" end="+=160" />
</frame>
<frame>
<action target="last" property="y" end="240" />
<action target="last" property="width" end="-=20" />
<action target="last" property="x" end="300" />
</frame>
</animation>
</style>
div {
background:#F4F4F4;
border-radius:8px;
}
.vBox {
x:center;
y:center;
width:auto;
height:auto;
box-orient:vertical;
box-shadow:8px 8px 8 #999999;
padding:20px;
}
.vBox>div {
w:60;
h:60;
box-shadow:inset 6px 6px 8 #999999;
}
</style>
<script type="text/javascript" fhtmlignore="false" >
//This function starts an animation on a div
function doAnimation() {
$('anim').start('controls');
}
//This function is called in an animation frame to get end value
function getTweenValue() {
return parent.height/2;
}
//Start the animation
doAnimation();
</script>
<div id="fhtml" >
<div style="box-orient:none" >
<div class="vBox" >
<div />
<div />
<div id="anim" />
<div id="last" />
</div>
</div>
</div>
<style type="xml/fhtmlassets" >
<animation name="controls" easing="inOutExpo" >
<frame>
<action property="x" end="500" />
</frame>
<frame>
<action property="x" end="300" />
</frame>
<frame>
<!--Here we switch targets in a frame.
Any script can be run to get new target. -->
<action target="previousSibling" property="h" end="Math.cos(90)+30;" />
</frame>
<frame>
<action property="h" end="javascript:getTweenValue();" />
</frame>
<frame>
<!--Use an imported utilty class method to get end value-->
<action target="last" property="h" end="+=100" />
</frame>
<frame>
<action target="last" property="h" end="20" />
</frame>
<frame>
<action target="last" property="y" end="+=160" />
</frame>
<frame>
<action target="last" property="y" end="240" />
<action target="last" property="width" end="-=20" />
<action target="last" property="x" end="300" />
</frame>
</animation>
</style>







