Skip to main content

Creating arbitrary grid layouts in HTML/CSS

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.



<?php
App::uses('AppHelper','View/Helper');
App::uses('File','Utility');
/**
 * Layout helper to create any web page layout you need
 */
class LayoutHelper extends AppHelper {
     
    public $helpers = array('Html','Form','Common');
     
    private $dirStack = array();
     
    
    /**
     * Generate the attributes for the tag
     * @param unknown_type $attrs
     * @return string
     */
    function generateAttributes($attrs) {
        if ($attrs == NULL || count($attrs) <= 0)
        return '';
        $attrlist = ' ';
        foreach ($attrs as $k => $v) {
            $attrlist .= $k . '="'. $v . '" ';
        }
        return $attrlist;
    }
     
    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);
        }
        else {
            $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() {
        return '</ul>';  
    }
     
    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(){
        return '</li>';  
    }
     
    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);
        return '</ul>';
    }
     
    private function getCurrentDirection()
    {
        return $this->dirStack[count($this->dirStack) - 1];
    }
}


Comments

Popular posts from this blog

Thoughts On Adding Spatial Indexing to Voldemort

This weekend, I set out to explore something that has always been a daemon running at the back of my head. What would it mean to add Spatial Indexing support to Voldemort, given that Voldemort supports a pluggable storage layer.. Would it fit well with the existing Voldemort server architecture? Or would it create a frankenstein freak show where two systems essentially exist side by side under one codebase... Let's explore..

Basic Idea The 50000 ft blueprint goes like this.

Implement a new Storage Engine on top Postgres sql (Sorry innoDB, you don't have true spatial indexes yet and Postgres is kick ass)Implement a new smart partitioning layer that maps a given geolocation to a subset of servers in the cluster (There are a few ways to do this. But this needs to be done to get an efficient solution. I don't believe in naive spraying of results to all servers)Support "geolocation" as a new standard key serializer type in Voldemort. The values will still be  opaque b…

Setting up Hadoop/YARN/Spark/Hive on Mac OSX El Capitan

If you are like me, who loves to have everything you are developing against working locally in a mini-integration environment, read on

Here, we attempt to get some pretty heavy-weight stuff working locally on your mac, namely

Hadoop (Hadoop2/HDFS)YARN (So you can submit MR jobs)Spark (We will illustrate with Spark Shell, but should work on YARN mode as well)Hive (So we can create some tables and play with it) We will use the latest stable Cloudera distribution, and work off the jars. Most of the methodology is borrowed from here, we just link the four pieces together nicely in this blog. 
Download StuffFirst off all, make sure you have Java 7/8 installed, with JAVA_HOME variable setup to point to the correct location. You have to download the CDH tarballs for Hadoop, Zookeeper, Hive from the tarball page (CDH 5.4.x page) and untar them under a folder (refered to as CDH_HOME going forward) as hadoop, zookeeper


$ ls $HOME/bin/cdh/5.4.7 hadoop hadoop-2.6.0-cdh5.4.7.…

Enabling SSL in MAMP

Open /Applications/MAMP/conf/apache/httpd.conf, Add the line LoadModule ssl_module modules/mod_ssl.so         or uncomment this out if already in the conf file
Also add lines to listen on 80, if not there alreadyListen 80ServerName localhost:80 Open /Applications/MAMP/conf/apache/ssl.conf. Remove all lines as well as . Find the line defining SSLCertificateFile and SSLCertificateKeyFile, set it to SSLCertificateFile /Applications/MAMP/conf/apache/ssl/server.crt SSLCertificateKeyFile /Applications/MAMP/conf/apache/ssl/server.keyCreate a new folder /Applications/MAMP/conf/apache/ssl. Drop into the terminal and navigate to the new foldercd /Applications/MAMP/conf/apache/sslCreate a private key, giving a password openssl genrsa -des3 -out server.key 1024Remove the password cp server.key server-pw.key openssl rsa -in server-pw.key -out server.keyCreate a certificate signing request, pressing return for default values openssl req -new -key server.key -o…