So if you have been following my blog lately you would have noticed I am doing some adventures in HTML lately… No I am not leaving my XAML love behind I just feel that I should look at other stuff and get ideas from different technology stacks.
In todays article I want to show how layout specifically one nicknamed as the “Traditional Box Model” comes in handy to know for those that like me come form a XAML background, a background which has a rich layout system, a background where panels are the kings of the realm. We’ll see how in HTML, yes this is a bit harder, but very achievable. We will also see how HTML5 and CSS3 introduces some really cool concepts and how layout becomes comparable to XAML layout and panels.
I remember back in the days when I used to do web (around 6 years ago) many would layout the page by using a <table />. Yes a table believe it or not! You might ask yourself “but a table is really for displaying lists of data no??”. Well layout is not really the most intuitive thing to figure out in HTML and devs love shortcuts thus yes; tables were (and in some cases still are) a tool to do layout. But is it the best way to do layout?? No, its not really… A more flexible way to do layout is by using divs. Enter the “Box Model”.
Lets say we wanted to do something like this
One way of picturing this layout is that every box is a div (some might argue it doesn’t really need to be a div but really any element that has display: block, but for simplicity, let’s say divs for now). A div by default will occupy all the width available, so if we had the following HTML the output would not really resemble the layout we have in the image here.
This would actually render into something like this
Blue div == ‘mainSection’; Red div == ‘sideSection’;
In order to get these 2 divs side by side, we need to specify a CSS property called float. You can specify left, right, none or inherit. In our case we will want to set the mainSection to float: left and the sideSection to float: left. The piece that many forget to add, which then results in chaos is to set to the next element (in our case the footer) the css property clear: both. This will restore the flow of the document and basically in our case it will prevent the footer from going up on the side of the sideSection div.
So here is the CSS styling we have done so far
And here is the result we got
Nothing really changed did it?? Nope it did not. And the reason for that is that as I was saying before a div will occupy the full width available by default. What we can do here to make the mainSection and sideSection layout side by side is to set a width for the divs. And we finally get a result that looks like this
What is annoying here is that we had to specify a width to both divs… In all fairness the sideSection can stay without a width and this would make it occupy the reminder width inside the page. That’s cool BUT we want our mainSection to take the dynamic width and not really the sideSection, right? Yes you can do it with the Traditional Box Model BUT instead lets have a look at how we can do this and much more using the new hot stuff from HTML5 and CSS3.
Enter “Flexible Box Model”
The flexible box model is still something that browsers are experimenting with in fact you’ll find that you will need to annotate the properties for this with –webkit and –moz- and –ms . don’t you love experimental things Anyways, the idea with this is to be able to be more dynamic, to have a proper way how to specify layout. With this model you’ll be able to specify if you want the flow to be horizontal or vertical (just like orientation in StackPanel for those XAML guys reading) you’ll be able to specify how much “percentage” of the space available vertically/horizontal should a box take up (just like ColumnDefenitions and RowDefinitions in Grid for those XAML guys reading). You will also be able to specify the alignment and yes also the index you want each box to be in…
Does this feel more like panels in the XAML world. WUHUU now we are talking …. so let’s pimp up our screen with some hot and spicy HTML 5 / CSS3.
Let’s start fresh… here is some new HTML … Basically a parent div with 4 divs and lets start rocking!
The first thing we want to do is tell the container div that we want to use the new box model. To do so we set display: box. Since this is experimental still we need to specify display:-webkit-box;
As I was saying the new flexible box model supports orientation, you do this by specifying box-orient. As expected this takes horizontal and vertical . P.S do not forget to add the –webkit- and all the rest.
And this gives us
This might look like its nothing but hey we just started… Ok seems like these boxes are only using the width that the inside text measures, lets make them use all space available evenly (just like we would do with a XAML Grid)
To do so we use another cool CSS3 feature. The magic property is called box-flex.
And this gives us
Already very exciting isn’t it?! What was that 1 we set to box-flex. The 1 is basically being used in the following formula >> widthOfParent * 1/numberOfElements = widthForElement (ex: 600 * 1/4 = 150). For example if I set 3 for one of the boxes, I get this result which is Box3 is as big as the other 3 boxes all together. (doesn’t it sound like a * measure for ColumnDefinitions in XAML )
Yes resizing the browser window will nicely resize these boxes just like one would expect. AWESOMENESS on a stick!!!!!
What if I want that all boxes are 100px BUT (since I am a crazy evil designer that likes to bully developers) I want them to be all centred in the middle of the screen. Well to give each box a size we know what we have to do, set the width css property. To specify how to layout them there is a new CSS3 property called box-pack. This property will tell the Browser how to distribute the free space. You can set this to start, end, center and justify. Lets go for center (-webkit-box-pack:center;) and we get something like this
if I specify –webkit-box-pack: justify I get this
What if we want to change the rendering order of the boxes? CSS3 to the rescue box-direction a new CSS property will do the trick by setting it to reverse. –webkit-box-direction:reverse
And yes you can even change the order of the boxes (just like a XAML Panel) by specifying the box-ordinal-group
Last but not least is box-align which can be center, left, right and also stretch.
Check out more details on this over here. I hope that this article really shows you that HTML5 and CSS3 are really making some very cool and exciting things for us devs. If like me you come from a background where layout is something really rich (which in any XAML technology, layout is super easy to work with) HTML5 and CSS3 are building mechanisms to be leveraged and easily build awesome web applications.
I am very excited about this, layout sometimes is taken for granted but what is a good UI platform without a good and flexible layout system. Thankfully HTML5 and CSS3 are here to rescue us from the evil designer requests