Showing posts with label ui. Show all posts
Showing posts with label ui. Show all posts

Monday, 3 March 2014

In my day...

Web development has changed a lot.

I was aware that there have been many changes in the last few years, and I’ve seen maturity come to web platforms in the form of standardisation and common reusable libraries and frameworks - and I don’t mean reusable in the way we used to “reuse” stuff by nicking it off other people’s websites when we saw something cool.

I used to be a web developer.  Sort of.  Some times I’ve been on the bleeding edge, and others… I remember using JavaScript to call back-end services with an XML payload before people were using the term AJAX, but I also remember working on an enterprise um… “classic”… JSP application only “recently” - in fact that was probably the last job where I did anything that looked like web development.

So this blog post is going to chart the progress of web development through my own experience.  Of course, this doesn’t by any means cover the whole spectrum, but I think my experience has been not unusual for a Java programming working through the noughties.

Over the course of my career I moved further away from the UI, because certainly early on the money and status was in “back end”, whatever that means, and not “front end”.  Which is ridiculous, really, especially as back then you couldn’t really follow best practices and clean code and test first and all that awesome stuff when doing front end development because none of the browsers played by the rules and frankly if you got it working at all you were a bloody genius.  And that’s not even considering the fact that as a “front end” developer you should be thinking about actual real human beings who use your product, and actual real human beings are messy things and understanding them is not (we’re told) traditionally a domain that we developers are naturally proficient in.

Anyway, I digress.  This was supposed to be a history lesson.  Or a nostalgia trip.  Or possibly Ranty Trish waving her walking stick in the air and shouting “You kids don’t know how good you’ve got it these days”.  If nothing else, I hope that it makes other “back end” developers like myself appreciate how much things have moved on.

Let’s go back to the olden days, before I’d even graduated: picture a time before smart phones - before phones were even common (I was horribly mocked at university for being poncy enough to have a mobile), before we knew if all this work we were doing to combat the millennium bug was going to stop the end of the world.  I was doing my first summer internship at Ford, and a contractor from Logica (who don't seem to exist any more??) told me that if I was messing around with web pages and HTML (my friends and I had geocities-and-equivalent sites) I should look at this JavaScript thing to make my pages “dynamic”.  I didn’t have to just use GIFs to bring my page to life, I could move stuff around on the page.  I think I wrote a “you are in a crowded room”-type adventure game, because my background was BASIC and that’s what you do.

Actually I haven’t even mentioned that we were creating these websites to stay in touch with each other.  We’d discovered guest books, and used them to write comments and share stories since we’d all moved out of our home town to go to different universities.  Man, why didn’t I invent Facebook back then?  That’s what we needed.

Anyway.

A year later, I was back at Ford doing my sandwich year-in-industry.  The first project I worked during this time was a web-based reporting tool that needed to dynamically display hierarchical data.  We chose JavaScript trees to render this data - my year of messing around with my website paid off, and I was able to use my “cutting edge” Javascript skills in a real production environment.  Yay?  The back end was CGI - I think I was writing in Perl, but don’t tell anyone that.  I was learning Java at university, but this was a new language and I don’t think Ford was using it yet.

The next project was a very ambitious one - be the first car manufacturer to sell new cars on the web.  Ford was well ahead of their time - the millennium bug had not killed us all, but people were barely buying books online, never mind spending tens of thousands of pounds on a car they’d never driven.  But it wasn’t just ahead of its time from a business point of view, technically it was very advanced too - we used lots of “DHTML” (as we were now calling it), a new-fangled technology called ASP, and we were writing modular, reusable COMponents.  We used XSLT to parse the XML from the COM objects, and the ASP figured out whether you were Netscape or Internet Explorer (Firefox wasn’t even a gleam in the inventor’s eye, and forget Chrome, I think we using Alta Vista (whaaaat? AltaVista got bought by Yahoo??) not some new-fangled search engine beginning with G) so it could use the right XSLT to turn the XML into HTML that was readable by the browser you were using.  My job was to get the DHTML pages rendering and animating correctly in both IE4 and Netscape 4.  That was a lot of fun for me, but also very challenging.  And imagine my shock when a few months later I tested the site from the university UNIX machines to find that Netscape rendered it completely differently under UNIX.  I learnt a lesson about how important it was to test on different platforms.

We had some smart Microsoft people helping us out with this project, and, because it was 2000 and the dot com crash hadn’t happened just yet, we also had a lot of young, overpaid, overconfident contractors who believed anything was possible.  I learnt a lot during this time, not just about the technology, but also about different approaches to shaping your IT career.  And about how much you could earn before you were 25.  I was definitely going to be a programmer when I left university the next year.

Yeah, so… I graduated in 2001.  If you were around then, you’ll remember that getting a job was a bit more difficult than I had anticipated, especially as these young, overpaid contractors were now desperately grabbing anything they could find.  But that’s a story for another day.

I didn’t go back to Ford straight away, I’d “been there and done that”.  I worked on the website for Common Purpose.  On the first day, they sat me down with a book on JSP and Servlets, and that was my reading material for the next few weeks.  If I’d been fresh out of university where we’d been doing Applets, and where I’d written a Swing app on the side for my Dad’s school, this would have been a big mindset change for me.  But having worked on the ASPs it wasn’t such a big shift.  I did, however, like how JSPs and servlets made the separation between the view and all-of-the-other-logic-stuff a bit clearer - back in ASP-land we’d settled on a convention of dealing with the form data from the previous page in the first part of the ASP, and rendering the new page in the second part.  To this day I still don’t know what we should have been doing instead.  But in JSP-land it only took me... I dunno, about 6 months I think, to get the website up and running.  The most difficult section was registrations.  And yes, I was a graduate, and yes, I was new, but that was a good turnaround for a web application “in those days”.

In my spare time I used what I’d learnt on the blews website.  I even had a section where people could log in and comment on photos - we had whole conversations on this website.  It was a way for me and my friends to stay in touch.  If I’d cracked the photo-uploading instead of it being a manual process for me, I would have invented Facebook.  If only I’d known….

The work dried up and there was nothing else for a graduate in the early noughties, so I went back to Ford.  My first role back I picked the same technologies we’d been using before - XML, XSLT, only this time we were using JSPs instead of ASP.  Our project had a very tight budget and we’d worked out that using open source Java technologies and running the application on one of the many UNIX machines lying around the place was a lot cheaper than the Microsoft solution.  I think we were the first team in Ford Europe to pick Java at a time when the recommended approach was Microsoft.  We delivered on time and under budget, and Java was the way forward for the department from then on.  But on this project I met a guy who would impact my career probably more than he even realises, a guy I’d work with again later.  He told me that in Java we no longer used Vector by default, but ArrayList (whaaat? What’s an ArrayList? I had no idea what the differences were between Java 1.1, which we’d learnt at university, and Java 1.2, which was now standard).  And questioned my choice of XML/XSL.  Although I’d been learning new technologies and growing, he was the one who made it clear to me that I needed to keep myself ahead of the curve with the technologies I was using, or planned to use, if I wanted to stay relevant and make my life easier.

On the next project I worked with a genius guy who was definitely keeping ahead of the curve - he was using JavaScript to send small XML payloads to the server (which was coded in Java), and rendering the response in place on the page instead of reloading the whole thing.  Mind.  Blown.  I didn’t even hear the term Ajax until a year or more later.  We were fortunate in that this was once again an internal application, so we controlled the browser.  This was back in the days when you wanted your users to be on IE5, as this was the only browser that supported this functionality.

The next few projects/jobs I worked on were all more pedestrian variations on the JSP theme - first I learnt Struts, which at least made us realise there was a model, a view, and a controller.  Then at Touch Clarity I learnt about Spring MVC, which actually put the validation errors next to the boxes which cause the error - by default, without you having to mess around.  Spring was a revelation too, a framework that really tried not to get in your way.  It was also frustrating because you needed to understand its lifecycle, but it did so much heavy lifting for you, it sped up standard CRUD-app web development enormously.

A couple of years passed, during which time I was still working on a web application (for an investment bank) but I can’t for the life of me remember what technologies we used (other than Java).  I know it was hard to test and I know the tricky stuff was “back end” not “front end”.

In the next project where I had any control of the technology, I picked Spring since I’d had such a good experience previously.  It took 4 developers a couple of months or so to develop an admin application for a trading app.  Given the previous timescales I’d worked with, this seemed pretty good.  Until a few months later and two other guys on the project produced an admin app for our bank users in a matter of weeks.  I can’t remember what they used, maybe Grails?  But it was another demonstration of how I really should have been researching the field instead of simply sticking with what I knew, especially when I knew my knowledge was a couple of years out of date.

Fast forward to LMAX, and we were using GWT, pre-2.0 - I think this probably feels natural if you’ve been a Swing or AWT developer, but I’m still not convinced it’s a sound web platform (although I know it has improved).  It was great because cross-browser was no longer an issue, but it was bad because it separates you from the underlying HTML, which means you can seriously mess up without realising.  It’s also hard to use CSS correctly when you don’t have access to all the HTML components.

So we come to more-or-less the present day, as it should be fairly obvious that during the time I’ve been working on the MongoDB Java Driver I haven’t done a lot of GUI development. I’m lucky because attending lots of conferences means I see a lot more of the current-trending technologies, but up until a couple of weeks ago I hadn’t had a chance to play with any of them.

So now I’ve been trying Angular.js, Bootstrap, and UI Bootstrap.  My goodness.  It’s a whole 'nother world.  I’m seeing at conferences and user groups that developers are increasingly polyglot, so maybe there’s no such thing as “just” a Java developer any more, but if you are “just” a Java developer, I think it could be… interesting… to get your head around some of the techniques.  Since we don’t have closures, our callbacks are ugly and we tend not to program that way.  Async is not something that comes naturally in a Java environment, I believe, although after working that way at LMAX I’m personally sold on it.  Old-world JavaScript developers like I am/was might also find it hard to understand you can have clean, testable JavaScript code which Just Works.  It didn’t even occur to me to worry about browser compatibility, and my app not only worked on my phone as well as my laptop, but looked really phone-ish and awesome with very minimal effort.

I’m currently on a plane on the way to QCon London where I’m going to demo this Brave New World of web development (together with a nice Java back end to prove how awesome Java is to work with and, of course, a MongoDB database).  So it is not my intention in this post to explore what this new world looks like.  But I have seen the Present, and it’s a lot better than the Past.  Kids These Days don’t know how good they’ve got it - they’ve never had to struggle, to fight the browser, to hand-craft their JavaScript like we have, or had to work with raw, low-level JSPs and Servlets.

Now things are easier.  There are standards, there are libraries, there are best practices and YouTube videos showing you how to create apps in 60 minutes (back in My Day I had to borrow someone else’s browser to use the Internet, and I debated for years the value of spending my own actual money on a Javascript actual paper actual book, which I could not afford).  Now, you can get something quite pretty and functionally interesting, working in a lot less time than I realised.  But that doesn’t mean the Kids These Days have it easier - it means there is so much more potential.  Instead of beating your head against trying to get a specific version of IE to do what you want, instead of having to write separate pages for different browsers (although maybe that still goes on), you can be exploring so much further into the possible, try things that no-one else has done yet.  It opens up so many interesting possibilities for apps on all platforms.

Exciting times.


So next time someone asks me “What is the de facto front-end framework for Java?” I’m going to say HTML5, CSS and JavaScript.

Tuesday, 12 April 2011

CSS for Developers: Horizontal and Vertical Centring

First, an apology.  I will be using the British spelling for "centre", because, well, I'm British.  But it gets really confusing because you have to use the American spelling in the code.  And doesn't "Centring" just look wrong?

Part Five: Horizontal and Vertical Centring
One of the most common things you want to do with blocks of content is to centre it.  In particular, you would think that vertically centring content would be straightforward, but it turns out that in HTML/CSS it just isn't.

5.1 Horizontal Centring
Centring a paragraph of text is clearly easy - all you need is text-align: center.  However, sometimes you want to centre a block, something like a div, without having all the text centred as well.  This is slightly trickier than you might expect, because the only CSS attributes you have are for centring text.


<html>
<head>
    <title>Horizontal Centering</title>
    <style type="text/css">
        #div1, #div13 {
            background-color: #DDDDDD;
        }

        #div2, #div14 {
            background-color: #BBBBBB;
        }

        #div3, #div15 {
            background-color: #999999;
        }

        #container, #container5 {
            border: 1px solid black;
            margin: 5px;
        }

        #container5 {
            text-align: center;
        }

        #to-center {
            margin-left: auto;
            margin-right: auto;
            width: 200px;
            border: 5px solid red;
        }

        #to-center2 {
            margin-left: auto;
            margin-right: auto;
            width: 200px;
            border: 5px solid red;
            display: block;
            position: relative;
            text-align: left;
        }

    </style>
</head>

<body>
<div id="container">
    <div id="to-center">
        <div id="div1">One</div>
        <div id="div2">Two</div>
        <div id="div3">Three</div>
    </div>
</div>
<div id="container5">
    <div id="to-center2">
        <div id="div13">One</div>
        <div id="div14">Two</div>
        <div id="div15">Three</div>
    </div>
</div>
</body>
</html>
Using margin-left: auto and margin-right: auto on the block you want to centre is a neat trick for doing this.  And it works fine in Chrome and Firefox.  However, it's not so great in IE 7:


The trick for getting it centred here (the second block) is to set text-align: centre on the div containing the block to centre (container5), then reset the text-align to left on the centred block (to-center2) so the text isn't centred.  Yes, a total faff.

However, there is some good news.  You can get IE to behave the same way as the more sane browsers by setting it into Strict Mode:


Remember kids: Strict Mode Is Your Friend.  And all you need to do is add the following to the top of your HTML file:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
5.2 Vertical Centring
<html>
<head>
    <title>Vertical Centering</title>
    <style type="text/css">
        #div1, #div4, #div7 {
            background-color: #DDDDDD;
        }

        #div3, #div6, #div9 {
            background-color: #999999;
        }

        #div5 {
            height: 40px;
            line-height: 40px;
            background-color: yellow;
        }

        #div2 {
            height: 50px;
            background-color: orange;
            vertical-align: middle;
        }

        #div8 {
            height: 40px;
            line-height: 40px;
            background-color: cyan;
            font-weight: bolder;
        }

        #container1, #container2, #container3 {
            border: 1px solid black;
            margin: 5px;
        }

    </style>
</head>

<body>
<div id="container2">
    <div id="div4">One</div>
    <div id="div5">Two</div>
    <div id="div6">Three</div>
</div>
<div id="container1">
    <div id="div1">One</div>
    <div id="div2">Two</div>
    <div id="div3">Three</div>
</div>
<div id="container3">
    <div id="div7">One</div>
    <div id="div8">Massive line of text that needs to wrap to show the centering totally doesn't work when you have more than one line of text.</div>
    <div id="div9">Three</div>
</div>
</body>
</html>
Given some of the problems with horizontal alignment, it shouldn't come as a surprise to find vertical alignment is not simple at all.

Us straightforward developer types would expect to be able to put vertical-align: middle on a div and expect all content inside that div to be, well, vertically aligned in the middle.  However this is not the case - see the orange block above.  A quick Google will tell you why this doesn't work, and I don't intend to duplicate the explanation here.

There is a nice hack which works for single lines of text though: if you set the height of the container and the line-height to the same value, the text will be vertically centred within that container (see the yellow panel, div5, above). This works really well for things like buttons or icons.

However, it doesn't work so well for paragraphs of text or sentences that might wrap, line-height is for a single line of text only.  See the cyan panel above for what happens if your text wraps.

I'd love to give you an answer on how to get this to work for text that wraps, but I haven't found a satisfactory solution yet.  What I usually do is set a fixed height on the container and then set the margin on the text so that it sits in a way that looks vaguely centred.  Not a solution I'm happy with, because a) it can sometimes render slightly differently on different browsers b) it's a very fragile solution if you're going to internationalise your page as some languages will have longer or shorter paragraphs and c) it feels like a massive hack.

If anyone has a nice solution for vertically centring paragraphs of text I'd love to hear it.

Friday, 28 January 2011

CSS for Developers: Cross Browser Table Border Behaviour

One of the aims of this series is to highlight some stupid gotchas in support for CSS in the different browsers.

Today's gotcha is table borders.

Yes, yes, I said don't use tables.  What I means is, don't use tables for layout. But you can use tables for, you know, tabular data.  Like, for examples, lists of instruments and their bid and ask prices.

But you should know that even when you use strict mode, Internet Explorer has slightly... eccentric... rendering behaviour for tables.  Actually to be specific, it's IE7 only.

<html>
<head>
    <title>Table Borders</title>
    <style type="text/css">
        table, td {
            border: 1px solid black;
        }
        td {
            height: 20px;
            min-width: 5px;
        }
    </style>
</head>

<body>
<table cellpadding="0" cellspacing="0">
    <tr>
        <td>first cell</td>
        <td>second</td>
    </tr>
    <tr>
        <td>
            <div></div>
        </td>
        <td>
            <div></div>
        </td>
    </tr>
</table>
</body>
</html>


The HTML here is a simple table with a border round all the cells (using CSS border, not the deprecated border attribute on the table) - a fairly common situation.

This is how it renders in IE7:


Note the distinct lack of a border around the lower two cells.  If a table cell is empty, or contains a div which is empty, IE doesn't render the cell at all.

The cheat to get around this is to add &nbsp; into every empty cell - either inside the div, if there's a div in there, or inside the td if there's nothing else in there.  Then IE wakes up and remembers to render the borders.

Tuesday, 25 January 2011

CSS for Developers: Column Layout Using CSS

This is a continuation of my series of CSS hints / tips / cheats for developers (and other technical-but-not-UI people).

The screenshots are in Chrome on a Mac.  The originals were on Firefox on Ubuntu so I can tell you the behaviour is identical.

Part Three: Column Layout Using CSS (or: still no excuse to use tables)

Today's example is a simple one, but worth knowing all the same.  The aim is, once again, not to use HTML tables to provide any sort of layout.  In most cases not only does using a div reduce the size of your DOM (and potentially help improve the performance of your page), it's actually a lot less complicated to organise your layout this way.

3.1 Display Elements or Text in Columns

<html>
<head>
    <title>Column layout</title>
    <style type="text/css">
        #col1 {
            background-color: yellow;
            /**have to know the width **/
            width: 30%;
            float: left;
        }
        #col2 {
            background-color: lightBlue;
            width: 30%;
            float: left;
        }
    </style>
</head>

<body>
<div id="col1">
    <div>1</div>
    <div>2</div>
</div>
<div id="col2">
    <div>3</div>
    <div>4</div>
</div>
</body>
</html>
Again you can see we're using float on the divs to get them to appear side-by side.

The code is much more intuitive organised this way - everything from a single column is grouped together in a single div.  If this was done using tables, you'd have the content for a single column scattered in different cells on different rows of the table.  Re-arranging the order of the columns in the case of tables is much more of a pain in the neck.  With a div, it's a simple move.

Friday, 21 January 2011

GWT: Why VerticalPanel is Evil

At LMAX we adopted Google Web Toolkit pretty early on.  One of the motivations for using it was so we only had to worry about recruiting Java guys, and then we could all work on every part of the application including the web UI.  Sure, you can learn a bunch of different skills if you want to, but it reduced context-switching and kept the skill set we were hiring for to a nice short list.

The problem is that GWT does a very nice job of pretending to be Java whilst actually compiling down to HTML and JavaScript.  If you don't have some understanding of the end result (the DOM the browser is going to be rendering) it's going to be hard to get the performance you need from a low-latency trading application.

My number one bug-bear with GWT is VerticalPanel.  To the uninitiated developer, this seems like the sort of thing that will be useful everywhere.  You often want stuff stacked on top of each other - think menus, lists, the layout of a dialog.  What is not obvious is that it uses tables for layout under the covers, and I've mentioned in the past that Tables Should Not Be Used For Layout.

A much less obvious way of getting the same result with (usually) no extra effort is to use FlowPanel.  This is rendered as a div, and most of the time the elements that get inserted into it will render in a vertical stack.

VerticalPanel Code
VerticalPanel panel = new VerticalPanel();
panel.add(/* your widget */);
panel.add(/* your second widget */);
VerticalPanel Rendered As HTML
<table>
  <tbody>
    <tr>
      <td>
        <!-- your widget here -->
      </td>
     <tr>
    <tr>
      <td>
        <!-- your second widget here -->
      </td>
     <tr>
  </tbody>
<table>
FlowPanel Code
FlowPanel panel = new FlowPanel();
panel.add(/* your widget */);
panel.add(/* your second widget */);
FlowPanel Rendered As HTML
<div>
  <!-- your widget here -->
  <!-- your second widget here -->
</div>
You can see that the DOM generated for a very similar-looking 3 lines of code is much much smaller for FlowPanel.

Who Cares?
Right, but we're only talking about a few more elements, and browsers are pretty smart about optimising these things.  Right?

Maybe.  But if you use VerticalPanel for all your containers, for every box which needs to be a slightly different colour, for every place you want to change the alignment slightly, things get very big very fast.  This is an example of real code from an early prototype, where we had several nested panels (not unheard of if you've got a complex dialog box with lots of elements in it.  Like, say, a deal ticket).  And I've stripped out a lot of the table attributes that made this even more heinous:

<table>
  <tbody>
    <tr>
      <td align="left">
        <table id="panel1">
          <tbody>
            <tr>
              <td align="left" style="vertical-align: top;">
                <table class="orders-input">
                  <tbody>
                    <tr>
                      <td align="left">
                        <table class="row">
                          <tbody>
                            <tr>
                              <td align="left">
                                <table id="container">
                                  <tbody>
                                    <tr>
                                      <table id="panel2">
                                        <tbody>
                                          <tr>
                                            <td align="left">
                                              <table class="controls">
                                                <tbody>
                                                  <tr>
                                                    <td align="left">
                                                      <!-- widget -->

For every table element and associated elements (tbody, tr, td), you would get a single div element instead if you simply replace every instance of VerticalPanel in this stack with a FlowPanel.

<div>
  <div id="panel1">
    <div class="orders-input">
      <div class="row">
        <div id="container">
          <div id="panel2">
            <div class="controls">
              <!-- widget -->

See? Much nicer.

This is exactly what we did do, and we saw a noticeable speed improvement across all browsers - noticeable to a real user, not just some millisecond improvement on a performance test.  Mind you, users' brains are amazing things and your system has to react in less than 0.1 seconds for a user to perceive it as instantaneous.  So even in a browser, every millisecond counts.

In addition to improved performance, you get a nice bonus: now the layout is no longer controlled by tables, you can really easily shove stuff around and make things look pretty with the clever use of CSS.  If you're really lucky, you can chuck that stuff over to your designers and not have to do another GWT compile when someone wants to move things 3 pixels to the left.  Which they will.

Wednesday, 19 January 2011

CSS for Developers: The Joy of Floats

As promised, the Long Awaited Follow-Up to CSS for Developers Part One! Well, long-awaited if you're as afflicted with NADD as I am.

Quick recap - the aim of this series is to provide a quick and easy how-to around the magic that is CSS.  It's primarily aimed at developers, although I would hope it's comprehensible to a range of tech-savvy people.

(Note: unless otherwise stated, the screenshots are in Chrome on a Mac - given an earlier version of this guide I can tell you the behaviour is identical to Firefox on Ubuntu).

Part Two: The Joy of Floats (or: why they don't do what you think they should)

Last time I stated that using float is a great way to position elements contained in a div.  Well, it has its downsides too.  Quite a few actually.

So this post documents the ones I ran into and what we did on the LMAX Trader UI to get it to look the way we wanted.

Disclaimer: There might be better ways to do a lot of this stuff - if you locate them via Google or work them out for yourself then well done!

2.1 Starting a New Line Using Floats

<html>
<head>
    <title>Horizontal flow</title>
    <style type="text/css">
        #left {
            background-color: cyan;
            width: 50%;
            float: left;
        }
        #center {
            background-color: yellow;
            width: 50%;
            float: left;
        }
        #right {
            background-color: red;
            width: 50%;
            float: left;
        }
        #next-line {
            background-color: green;
            width: 200px;
            clear: left;
            float: left;
        }
    </style>
</head>

<body>
<div id="container">
    <div id="left">Left</div>
    <div id="center">Center</div>
    <div id="right">Right</div>
    <div id="next-line">Next Line</div>
</div>
</body>
</html>
  • clear: left will reset any left float from before the div it is applied to. This will cause the div to be shown on a new line, although it can still have a float property as well
  • clear: right will put the div below any divs with a right float applied 
  • clear: both will do both. 

I usually do clear: both if I need to ensure the div will be on a new line.

2.2 Right Aligning Floated Divs

<html>
<head>
    <title>Float Right</title>
    <style type="text/css">
        #left {
            float: right;
            border: 1px solid gray;
        }
        #center {
            float: right;
            border: 1px solid gray;
        }
        #right {
            float: right;
            border: 1px solid gray;
        }
        #container {
            background-color: yellow;
            height: 26px;
        }
        #left2 {
            float: left;
            border: 1px solid gray;
        }
        #center2 {
            float: left;
            border: 1px solid gray;
        }
        #right2 {
            float: left;
            border: 1px solid gray;
        }
        #container2 {
            clear: both;
            float: right;
            background-color: #90ee90;
            height: 26px;
        }
    </style>
</head>

<body>
    <div id="container">
        <div id="left">Left</div>
        <div id="center">Center</div>
        <div id="right">Right</div>
    </div>
    <div id="container2">
        <div id="left2">Left</div>
        <div id="center2">Center</div>
        <div id="right2">Right</div>
    </div>
</body>
</html>
If you want to right-align a number of elements (for example, buttons at the bottom of a dialog), there are two approaches. One is to set float: right on each individual item (see the yellow panel above) - you'll notice that this means the divs are displayed in reverse order, because they're set to float to the right of each other. A better approach is to put the divs you want right-aligned into a container div and float that to the right (see the green panel). This ensures the correct ordering of the items.

2.3 Floating Behaviour to be Aware Of: float left next to float right (cross browser)

<html>
<head>
    <title>Float right next to float left</title>
    <style type="text/css">
        #left {
            background-color: blue;
            width: 50%;
            float: left;
        }
        #center {
            background-color: yellow;
            width: 50%;
            float: left;
        }
        #right {
            background-color: red;
            width: 50%;
            float: left;
        }
        #next-line {
            background-color: green;
            width: 50%;
            clear: left;
            float: left;
        }
        #float-left {
            clear: left;
            background-color: purple;
            float: left;
        }
        #float-right {
            background-color: cyan;
            float: right;
        }
    </style>
</head>

<body>
<div id="container">
    <div id="left">Left</div>
    <div id="center">Center</div>
    <div id="right">Right</div>

    <div id="next-line">Next Line</div>

    <div id="float-left">Floating Left</div>
    <div id="float-right">Floating Right</div>
</div>
</body>
</html>

In Firefox and Chrome (tested under Ubuntu and OS X), if you clear the float on a single div element, that div and all the ones after it will appear underneath all the previous ones.  For example, see the "Floating left" (purple) and "Floating right" (cyan) divs above.  The two divs appear on the same line, floating side-by-side.

This may even be the same behaviour in IE in strict mode (I don't remember if I tested it).  But by default, Internet Explorer renders this quite differently.


(Apologies for some of the inconsistency in screenshots - given my choices of operating systems, getting the cursed screenshots in IE was... challenging).

The point is that in IE the float: right is quite literal - it floats to the right directly underneath the last floated element, regardless of any prior clear commands.

If you want to get the same behaviour across all browsers, you need to be stricter with adding containers for different content areas:

<html>
<head>
    <title>Float right next to float left - correct</title>
    <style type="text/css">
        #left {
            background-color: blue;
            width: 50%;
            float: left;
        }
        #center {
            background-color: yellow;
            width: 50%;
            float: left;
        }
        #right {
            background-color: red;
            width: 50%;
            float: left;
        }
        #next-line {
            background-color: green;
            width: 50%;
            clear: left;
            float: left;
        }
        #float-left {
            background-color: purple;
            float: left;
        }
        #float-right {
            background-color: cyan;
            float: right;
        }
    </style>
</head>

<body>
<div id="container">
    <div id="left">Left</div>
    <div id="center">Center</div>
    <div id="right">Right</div>
    <div id="next-line">Next Line</div>
</div>

<div style="clear: both">
    <div id="float-left">Floating Left</div>
    <div id="float-right">Floating Right</div>
</div>
</body>
</html>

2.4 Floating Behaviour to be Aware Of: parent divs of floated elements do not resize to child

<html>
<head>
    <title>Floats in containers</title>
    <style type="text/css">
        #left {
            border: 1px solid blue;
            float: left;
        }
        #right {
            border: 1px solid red;
            float: right;
        }
        #container {
            border: 1px solid black;
        }
    </style>
</head>

<body>
<div id="container">
    <div id="left">Left</div>
    <div id="right">Right</div>
</div>
</body>
</html>
In the code above, we have a "parent" div, container, with two children, left and right.  Both of these children are floating, it doesn't actually matter that one's left and one's right.  What you might not be able to see clearly is that the parent, container, has zero height.  It's got a black border, you should be able to see that the top and bottom of the border are actually next to each other, showing the div has no height of its own.

However the children have a height, the height shrinks to fit the content, the text.

What I'm trying to get at is that if you want to place something underneath the left and right divs, you can't rely on the browser working out where the bottom is and placing other divs underneath them:

<html>
<head>
    <title>Floats in containers</title>
    <style type="text/css">
        #left {
            border: 1px solid blue;
            float: left;
        }
        #right {
            border: 1px solid red;
            float: right;
        }
        #container {
            border: 1px solid black;
        }
        #container2 {
            border: 1px solid yellow;
        }
        #left2 {
            background-color: green;
            float: left;
        }
        #right2 {
            background-color: purple;
            float: right;
        }
    </style>
</head>

<body>
<div id="container">
    <div id="left">Left</div>
    <div id="right">Right</div>
</div>
<div id="container2">
    <div id="left2">Left</div>
    <div id="right2">Right</div>
</div>
</body>
</html>
(You'll note this is not an article about design! I'm trying to use a combination of colours, outlines etc to make the point clear, not to make it look good)

Basically the floated divs are effectively absolutely positioned, and therefore take up no space on the document (more on this in a later post).

The way I've got round this in the past is to set a specific height on the parent div to force any following elements to appear underneath it. This works, but it can be fragile. In particular, it doesn't allow for wrapping text (more on this later too).

Still to come:
  • Position and Display: relative, absolute, block, inline... what does it really mean?
  • Horizontal and Vertical Centring
  • Strict Mode Is Your Friend
  • Column layout using CSS
  • Why "width: 100%" might go off the edge of the page
  • Cross-browser table border behaviour
Previously:

    Monday, 17 January 2011

    CSS for Developers: Horizontal Layout Using CSS

    I'm a Java Developer.  But I'm also a Web Developer.  Web Developers have been so badly maligned over the last decade or so that I always feel wary (and sometimes slightly ashamed) admitting this.  There's some sort of assumption that Web Developers (and Front End Developers) aren't real programmers. Similarly, "real" developers don't like to be tainted by coming into contact with that nasty "front end stuff" in case someone mistakes them for a designer.

    Trust me, no-one is going to mistake a Java Developer for a designer.  For a start, when designers wear geeky glasses it's ironic.  Or chic.  Or something.

    But developers will be forced to do something around the front end at some point in their lives.  Even if it's because they're sick of manually kicking off some process and want to give the users a big red button to press instead.

    So, as much to compensate for my own goldfish-like brain as anything else, I'm going to make a note of some of the CSS stuff I've used or found helpful during my mad scramblings to get the LMAX Trader user interface to a) look the way we wanted b) perform fast enough so our awesome back end performance wasn't totally invisible to the retail user and c) Not Suck Too Badly in Internet Explorer.

    Part One: Horizontal Layout (or: There's No Excuse For Tables Any More)

    You may (or may not) have heard that using tables for layout is a Bad Thing.  But to be fair, most of us don't care.  I've done it myself, it's usually the quickest way to lay stuff out on the page, especially if you're new to HTML / CSS and/or short on time.  There are loads of arguments all over the web as to why this is a bad thing, but the reasons I didn't want tables on the LMAX UI was a) we saw the performance improve by a really simple replacement of tables with divs and b) given the amount the UI was mutating, divs positioned with CSS was going to allow us a much quicker turnaround for the umpteenth re-design of the UI (ideally the upshot of this would be letting the designers mess with the CSS when they changed their minds and leave us developers out of it).

    Anyway let's assume Tables Are Bad.  Tables are only for tabular data, not for layout.  In my world.

    1.1 Simple Horizontal Layout Using Inline

    The most common use of tables for layout is where you put elements side by side - the default behaviour of divs is that they lay out underneath each other.

    However it's pretty easy to get divs to behave this way too, and using divs has some advantages over using tables.
    <html>
    <head>
        <title>Horizontal flow</title>
        <style type="text/css">
            #left {
                background-color: cyan;
                display: inline;
            }
            #center {
                background-color: yellow;
                display: inline;
            }
            #right {
                background-color: red;
                display: inline;
            }
        </style>
    </head>
    
    <body>
    <div id="container">
        <div id="left">Left</div>
        <div id="center">Center</div>
        <div id="right">Right</div>
    </div>
    </body>
    </html>
    The first option is to use display: inline.  This will lay div elements next to each other, similar to a span.  This is the simplest way to get divs to appear side-by-side.

    The disadvantage of this technique, however, is that inline elements can't be sized the same way as standard divs.  By default they contract to fit the content.

    The screenshot above is from Chrome on the mac - you'll notice by default the elements have some spacing between them.  Reducing the margin/borders on the elements doesn't seem to eliminate this, so that's something else you might need to consider if you use this mechanism to display elements side-by-side.

    1.2 Simple Horizontal Layout Using Floats

    
    <html>
    <head>
        <title>Horizontal flow</title>
        <style type="text/css">
            #left {
                background-color: cyan;
                float: left;
            }
            #center {
                background-color: yellow;
                float: left;
            }
            #right {
                background-color: red;
                float: left;
            }
        </style>
    </head>
    
    <body>
    <div id="container">
        <div id="left">Left</div>
        <div id="center">Center</div>
        <div id="right">Right</div>
    </div>
    </body>
    </html>
    
    Similar to using inline, floating a div will do the following:
    1. Make it shrink to fit the content
    2. Lay it out side-by-side with any sibling floating divs.
    You'll want to apply padding, margins, height, width and whatever else to make it appear less rubbish.


    1.3 Wrapping Horizontal Layout

    
    <html>
    <head>
        <title>Horizontal flow</title>
        <style type="text/css">
            #left {
                background-color: cyan;
                width: 50%;
                float: left;
            }
            #center {
                background-color: yellow;
                width: 50%;
                float: left;
            }
            #right {
                background-color: red;
                width: 50%;
                float: left;
            }
        </style>
    </head>
    
    <body>
    <div id="container">
        <div id="left">Left</div>
        <div id="center">Center</div>
        <div id="right">Right</div>
    </div>
    </body>
    </html>
    
    The advantage you have using divs over tables is that you can get the browser to work out how the elements should flow.  Tables require you to determine exactly how many cells appear on each row, but with divs you can determine a width for each element and have the browser work out whether to show it on a new line or not.  This will work with both percentage and pixel widths.
    • If you want a more table-like structure where you know exactly how many elements should appear on each line, use a percentage of the screen with.  
    • If you know the width of each element, you should set a pixel width on the elements and have the browser work out how many to show per line.

    The next CSS post will go over floating behaviour in a little more detail.

    Monday, 1 September 2008

    On the perils of Front End Design

    I'm reading Joel Spolsky's User Interface Design for Programmers. A thought that's struck me is about architecture. It's easy to get fooled into thinking building software is a bit like being the architect for a building. I'm not even going to go into the differences between engineering practices à la building design and good practice software design. I'm going to start from the easy point, the stuff you can see.

    There's often a pressure from your designers, from your steering committee, even from your CEO, to make your software look "pretty". I, too, with my DTP background, occasionally fall into that camp. You know, slicker fonts, curvy edges, funky this, fancy that.

    And you can look at buildings like the Woolworth Building, and think, "I want my software to be the equivalent of the Cathedral of Commerce". 
    But for all its Gothic detailing, its flying buttresses and gargoyles, you can still find the entrance. You can still find your way to the elevator and up to the floor you desire. The magnificent detail does not obscure the use of the building.

    The same cannot be said of user interface design. You don't simply wander past / through an impressive facade, whatever you think the "skip" button on your flash intro is supposed to do. The decoration, the clutter, is right there in front of the user, the whole time they're trying to DO something.

    Do architects design their entrances flush with the walls and the same colour?
    Are entrances to basilicas hidden behind flying buttresses?

    No (generally). Because the design of a building is supposed to enhance the "user"'s experience, not get in the way of it.

    If you're playing with acres of land there's a lot of detail you can fit in that won't hinder the ordinary person. In fact, rather sadly, many of them won't even notice it. If, however, you're coding for 800x600, or even if you're coding for a wide-screen Mega Television of Doom, there's limited space available. You want to make sure the "nice-to-haves" don't get in the way of the user's "must-dos". You want to make sure your entrances (buttons, links etc) are well marked.

    You don't want to find you've spent an awful lot of money on something that goes unused.