I love building websites. But, the long arduous efforts to get page layouts done, scare me. So started experimenting with ways to create arbitrary grid layouts, so I can write a layout manager someday , to take care of this business for me.
I refer the reader to this excellent post on
"What does width:100% do in CSS" to get a feel for block elements vs inline elements. To summarize, block elements generate a newline before and after them, but setting their width to something takes effect absolutely, i.e whether or not there is enough content inside the element to fill up the space. This is much like "fill_parent" in the android world. Inline elements are the opposite. They don't have the newline , but by default they expand only as much as their content, like "wrap_content" in android world.
However, what we need is a container that would behave as a block element, housing child elements that will be laid out horizontally, as well as vertically for a proportion of height/width of the parent. There are other display attribute values in CSS, that one can use to achieve these. I refer the reader to the
display attribute reference. These work with modern safari, chrome and firebox browsers with HTML5. Note, the table-cell and table types, this is exactly what we need.. Without further yapping, here is the code.
The idea is simple, use display:block if you need vertical splitting. Use display:table-cell otherwise. Internal containers are all inline-blocks so that they will expand as needed
Using divs and spans :
<div style="width:50%;height:100px;display:table;">
<span style="width:10%;height:50%;border:1px solid;display:table-cell">
<div style="width:100%;height:100%;display:inline-block">
<span style="width:100%;height:50%;border:1px solid;display:block">
<div style="width:100%;height:100%;display:inline-block">
<span style="width:100%;height:50%;border:1px solid;display:table-cell"> span 4.1.1 </span>
<span style="width:100%;height:50%;border:1px solid;display:table-cell"> span 4.1.2 </span>
</div>
</span>
<span style="width:100%;height:50%;border:1px solid;display:block"> span 4.2</span>
</div>
</span>
<span style="width:30%;height:40%;border:1px solid;display:table-cell"> span 5 </span>
<span style="width:60%;height:60%;border:1px solid;display:table-cell"> span 6 </span>
</div>
Using ul and li:
<ul style="list-style-type:none;margin:0;padding:0;width:100%;display:table;">
<li style="display:table-cell;width:40%;border:1px solid">
<ul style="list-style-type:none;margin:0;padding:0;width:100%;height:100%;display:inline-block">
<li style="display:block;width:100%;height:50%;border:1px solid">
<ul style="list-style-type:none;margin:0;padding:0;width:100%;height:100%;display:table">
<li style="display:table-cell;width:50%;border:1px solid">list 1.1.1</li>
<li style="display:table-cell;width:50%;border:1px solid">list 1.1.2</li>
</ul>
</li>
<li style="display:block;width:100%;height:50%;border:1px solid"> list 1.2</li>
</ul>
</li>
<li style="display:table-cell;width:30%;border:1px solid">list 2</li>
<li style="display:table-cell;width:30%;border:1px solid">list 3</li>
</ul>
Here is a cakephp helper that uses ul/li s to create layouts.
App::uses( 'AppHelper' , 'View/Helper' ); |
App::uses( 'File' , 'Utility' ); |
class LayoutHelper extends AppHelper { |
public $helpers = array ( 'Html' , 'Form' , 'Common' ); |
private $dirStack = array (); |
function generateAttributes( $attrs ) { |
if ( $attrs == NULL || count ( $attrs ) <= 0) |
foreach ( $attrs as $k => $v ) { |
$attrlist .= $k . '="' . $v . '" ' ; |
function generateClassAttr( $class , $options ) { |
if ( $options == NULL || ! is_array ( $options )){ |
return $this ->generateAttributes( array ( "class" => $class )); |
else if ( array_key_exists ( 'class' , $options )){ |
$options [ 'class' ] = $options [ 'class' ] . ' ' . $class ; |
return $this ->generateAttributes( $options ); |
$options [ 'class' ] = $class ; |
return $this ->generateAttributes( $options ); |
|
public function beginContainer( $options =NULL) { |
array_push ( $this ->dirStack, DIR_HORIZONTAL); |
return '<ul' . $this ->generateClassAttr( "layout-cntr" , $options ). '>' ; |
public function endContainer() { |
public function beginCell( $options =NULL){ |
$dir = $this ->getCurrentDirection(); |
$class = "layout-cell-h" ; |
if ( $dir == DIR_VERTICAL) |
$class = "layout-cell-v" ; |
return '<li' . $this ->generateClassAttr( $class , $options ). '>' ; |
public function endCell(){ |
public function beginCellContainer( $dir , $options =NULL){ |
array_push ( $this ->dirStack, $dir ); |
return '<ul' . $this ->generateClassAttr( "layout-cell-cntr" , $options ) . '>' ; |
public function endCellContainer(){ |
array_pop ( $this ->dirStack); |
private function getCurrentDirection() |
return $this ->dirStack[ count ( $this ->dirStack) - 1]; |
Comments
Post a Comment