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.

Thursday, 27 January 2011

My Experiences with Android Development

Because I was missing coding, and because my friend and I had an awesome phone app idea at the weekend, I thought I'd try my hand at developing an Android application this week.

I want to give a quick overview of my preliminary thoughts on getting started on this endeavour.

Background: I've got more than 10 years Java experience, but any UI for the applications I've worked on was always a web UI.  I am completely new to mobile app development.

Getting Started
I spent maybe a day and a half reading the excellent Android developer documentation and attempting to hack out a quick 'droid app.

I was surprised to find the Application Fundamentals section actually made sense to me.  There appears to be a clear architecture with design guidelines laid out for developers to follow.  This shouldn't really be a surprise I suppose, but years of hacking around with web UIs with poorly implemented MVC architectures must have left me thinking that all frameworks are less "frame" and more "work".

Setup
I remember the disaster of trying to get my first JDK working on my 486 - what a nightmare!  And getting Tomcat 3 installed and running?  Forget it.  I also remember the last time I made a serious stab at a learning a new technology.  I tried develop a Grails/Groovy application in Eclipse.  The IS guys had to rescue my laptop from me during that enterprise before I could do it any serious damage.

Installing the SDK on my mac was surprisingly simple, especially bearing in mind I'm new both to OSX and to mobile development.  I don't know if it's because Android development has been well thought out and well supported, or if it's a function of both the industry's maturity and my own experience.

The integration with IntelliJ was much slicker than I expected, especially since I'm using the freebie Community edition.  I don't remember the exact steps to tell it I wanted to create an Android project, but it must have been ridiculously easy otherwise I would remember the trauma.  I do remember a little confusion around installing the Android platform - I hadn't understood the difference between installing the SDK and then installing a specific API for it.  But the documentation and the android application got me on the right track in the end.  And then when I clicked the "run" button in IntelliJ, hey presto!  The emulator appeared and there was my app!

I loved the emulator.  I had some confused idea that I would have to plug my own phone into the laptop to see my application.  Instead, the emulator looks enough like my actual phone to give me decent feedback on how the app is going to behave.  The downside is I was trying to play with the camera, and I couldn't see how that would really work in the emulator, but I got a fair idea.

Did it work?
I managed to get a rudimentary application running, with a button and some descriptive text (it's not about to win any awards).  The button was supposed to launch the camera viewer, but my first few attempts just resulted in the crash notification.  It didn't take long to figure out how to use logcat to see the stack trace and see I hadn't set the permissions correctly to use the camera, so I rooted through the CameraPreview example in APIDemos to figure out how to set up the AndroidManifest.xml correctly, and rather amazingly it all worked!

Any downsides?
I was surprised (and slightly disappointed) at the amount of XML configuration.  I've seen plenty of evil Spring and Ant XML in the enterprise and I thought frameworks were moving away from that.  The manifest I can understand I suppose, but it felt a bit weird to be defining the UI in XML.  It seemed like a bit of an afterthought tagged on after all the well-defined architecture behind the scenes.

But maybe this will make more sense to me as I develop my application further.

In Summary
  • I was pleasantly surprised to be able to get an Android application (albeit a very basic one) working in only a few hours.
  • Development in IntelliJ was much easier than I expected.
  • The documentation is actually very good.
We'll see how I feel about it when I start trying to do more than a very simple example application.

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.

Monday, 24 January 2011

On Changing The Image Of Programmers

Gah!! This is exactly what I was talking about - it's pink, it mentions shoes, and it's about as patronising as you can get.

Would the chart be different if your possible outcomes were Bill GatesSteve JobsMark Zuckerberg, and Linus Torvalds?  I bet for a start it wouldn't mention Jimmy Choos or choice of handbags.  And it probably wouldn't be in baby blue either.

Which leads me nicely onto the next subject I have strong opinions on: Role models.  Why do we need them? Do we need them?

If there is any good to be salvaged from that horrific infographic, it's that it gave me what I've been trying to research - some female role models in technology. Unfortunately it hit the other button I was ranting about earlier - they're all very presentable and polished.  I don't doubt their value as role models, it's great to have people like that to try and emulate.  But surely there must be IT women out there who look like real people?  And how many of them started as programmers?  I know there's a wider issue around women in technical professions, and women at the top of organisations in any business domain, but I'm trying to keep focused on the issues faced by girl programmers specifically.

Do we need role models?
I feel almost a responsibility to be a role model.  I joined ThoughtWorks because I felt it would give me a better platform for greater visibility, so I could show that girls could do this job.  I feel passionately that the industry desperately needs excellent role models to overcome the stereotypes kids are absorbing (in our western society) about what it means to be a programmer(/developer/techy).

My friend Mazz feels quite differently.  She doesn't see why she should have a greater responsibility to be a role model simply because of her gender.  It wouldn't be expected of her co-workers.  She suggests that by making a career in programming an option for all, or worse, by targeting specific groups (e.g. women) we're devaluing the industry.  Surely we're stronger if we only attract people who are interested in the first place?

During a week long trip to Vegas (it's a hard life), Mazz and I realised we actually agreed on fundamentals:
  • Mazz doesn't believe we need female role models to tempt women into programming
  • I believe we need more diverse role models than we currently have.

If Mazz doesn't want to be a role model because she's perfectly happy getting on with doing her job bloody brilliantly, then that's totally cool - after all, if minorities are expected to do stuff which distracts them from their day job, it's going to make them less appealing to employers.

My aim in being a role model was not specifically to get more girls into programming, but to show to the world that we're not all speccy asexual white boys.  Some of us are speccy white girls.  And this shows the ridiculousness of trying to encourage girls to be role models - you've only changed one dimension. And having a token bisexual black disabled older lady is only going to narrow the field you're appealing to.

So what do we need to change?
Back to the question that started this off - "what do we need to do to encourage the girls?".  The answer, it would seem, is not to roll out the girls, dress them up and parade them around.  After all, we got here with no female role models.  And we may very well have been put off by role models like us - a teenage Mazz and a teenage Trish would probably not identify with the heel-wearing blonde I've become, despite my all-round awesomeness.

When I worked at Ford they used to tell us a story about marketing.  They told us that Harley Davidson understood that to market something, you had to market it at the person your customers wanted to be.  A Harley is a statement, a lifestyle choice.  They focused on promoting that lifestyle, promoting the image of the Harley biker, all leather and macho attitude.  They knew that the majority of their customers were CEOs, lawyers, doctors.  Guys who'd made it in life and had the cash to spend. But if they'd marketed Harley Davidson directly to the stereotypes of these guys they would have lost their market.  These men did not buy a Harley as part of their CEO persona.  They bought them because they aspired to be the leather-wearing macho guy.

I don't know how true that story is, but I do know Harley Davidson revitalised their failing business by focusing on creating a community around their brand.

So back to the question: How do we get more girls into programming?

And the answer is: We're asking the wrong question.

The real question is: How do we attract more than just the "typical" geeks into programming?  

And when you ask that question, you realise it's absurd to assume that attractive female role models and women-centered events are going to fix the problem, or even make any significant headway on it.  You're narrowing your field of appeal instead of broadening it.  You're being exclusive instead of inclusive.

Where can we find appropriate role models to represent us?
We have diversity amongst geeks.  We've got diversity along the typical dimensions (age/race/sexuality/gender etc etc).  But in addition we're all individuals and we're going to appeal to other individuals.  I might appeal to someone who likes shoes.  I might appeal to someone who likes photography.  I might appeal to someone who thinks Java developers should give a toss about the user experience.  I might appeal to someone who is massively OCD about the names of their variables.

We shouldn't care what little boxes those people tick on the dimensions that make absolutely no difference to their ability to program.  In fact, if we focus less on this and more on our general awesomeness as geeks, we might find so-called minorities are happier to represent us.

Even with diverse role models we might have trouble getting the media to let go of their stereotype of the geek programming in their bedroom.  But we might not - I did a search for "geek" on The Sun's website, and I found a lot more references to geek chic, and celebrities claiming to be geeks, than to stories of the lonely computer programmer who went crazy and killed everyone.

It is the time of the geek.  Let's ride the wave and bring other people to the party.

So who should our role models be?
Everyone.

All of us.

You.

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.

Thursday, 20 January 2011

On How Not To Target Girl Geeks

(First, let me say this post contains opinion, stereotyping and sweeping generalisations.  But that's sort of the point.  Also I don't pretend for one moment to speak for all girl programmers, I can only speak for myself)

When I first started this blog, I wanted to just post "proper" technical information.  I wanted to prove that there are girls out there doing "real" programming.

I specifically didn't want to talk about my gender.  I wanted to prove by silence that gender is incidental to what I do.

But, it doesn't really work that way, does it?

Firstly because one of the first things I get asked by guys when I meet them in this industry is "why aren't there more girl programmers?" (that's after they ask "do you work in HR?" followed by "are you a real programmer?" - I'm not joking, this happened this week).

And secondly because I'm pretty passionate about the gender issue.  To be specific: I'm passionate about diversity.  It's just that I'm more qualified to bang on about gender rather than something like race, sexuality, age etc.

What's started you off again this time?
The London Java Community got me thinking by asking "Is there anything we can do to attract more girls to the events?"

The thing is, the reason people (boys) keep asking this question is because they want more girls in the industry / at events.  They want them to feel involved and included.  I've said it before, but I mean it - I've never come across malicious sexism at work.  Yes there is subconscious sexism.  But the boys want the girls to come and play.  Why wouldn't they?  How many boys really want to work in a team which has 12 developers and only one is a girl?

But think about it: who is the worst person to ask why girls don't like being developers?

Yep.  A girl developer.

Because we love it.  We're here because we like programming, we like our jobs, we're good at it.  We weren't stopped by sexism (assumed or real), by boys clubs, by not having female role models, by... well, any of the myriad of reasons posited as to why girls don't become programmers.

I have no idea why a girl wouldn't want to be a programmer.  It's brilliant!  It's problem-solving, logical and creative, you're usually surrounded by intelligent people who are striving toward the same goal as you, and you get to meet a lot of boys :-)

So, back to the question at hand: how do we appeal to girls, as a user group and ultimately as an industry?

There are lots and lots of ideas kicking around this area, and I'm going to start by ranting about the things I think we shouldn't be doing.  This, of course, is totally my opinion so helpings of salt might be required.

No Pink
I get so angry about this!!  As if the pinkification of our little girls wasn't bad enough, "people" (I have no idea who) think that they can inflict this upon grown-ups too!

Why, WHY, would a website that is aimed at professional technical women be branded in childish hues of the hated colour?  I didn't even click on a single link, I'm not sure what service it's supposed to provide, because I was so disgusted by the colour palate I closed the browser.

In particular, if your target demographic is the somewhat unusual creature the girl-geek, or at least the lady technologist, what makes you think that ultra-feminine colour is going to appeal to us?  Apparently "The November 2009 Times/Lady Geek Female Appeal Study showed that only 9% of women want technology to be feminine, let alone pink."

What do you think, that your average (female) maths graduate is going to decide Computing Is For Me Because It's Pink?  Really?

I worry about this: are these sites (phones/consoles/cars) designed by men, and that's what they think women like?  Or were they designed by women who really believe that's what ALL women like?

Please.  Stop it.  Now.  It's embarrassing.

Be careful about your role models
Take the gadget show, for example.  I don't actually watch it, I'll be honest, because I really don't need someone tempting me to spend money on things I don't require.  But as an example of this point it's perfect - just the picture at the top of the page says it all to me: two reasonably attractive women (I know not everyone floats your boat but they're not ugly), token black guy and two white guys who certainly don't float my boat.  If only one of them was gay, their diversity tick sheet would be perfect.

I am not for one second suggesting any of these guys don't know their stuff.  That is not the point at all.  I just wonder - if one of the women looked like someone's mum, would they have got the job?  The subconscious message here is that yes, it's totally fine to be a girl and a geek.  But you still have to look good too.

And there's another message there - if you're a guy and you're into technology, you don't have to be hot. In fact, the role models we see are definitely on the Not Hot end of the scale.  Bill Gates anyone?

So girls get a double-whammy - I have to know what I'm talking about and look good (whilst also trying to prove that girls who look good have brains); and there are no hot guys in the industry.

Hmm, no thanks, I think I'll get a job in marketing.

Don't assume all women are the same
In fact don't assume anything about the girls you want to attract.  Actually, assume they're people.  Like you.  And geeks.  Like you.

For example.  I actually do like shoes and clothes.  But plenty of my fellow girl-geeks are about as bothered about that stuff as their male counter-parts.  So trying to appeal to girls with iPhone apps that help you pick you next pair of Jimmy Choos might not be the approach you want to take.  You'll attract a subset of women, sure, but they might not be the ones you want.

Imagine if you wanted to get more guys into programming, and you decided to do it by using football as the hook.  Yes, you'd get certain guys interested. But I've met more guys who are utterly disinterested in football in IT than I've met girls who dislike it.

We're not all the same.  We're interested in all sorts of different stuff.

Be very very careful about women-only events
My personal feelings are that there should be no need for all-girl conferences or all-girl line-ups.  To me, it implies that girls want something different to boys, and that girls only listen to other females.

I think there are places for these sorts of things, especially if you're aiming it at girls who might be more uncomfortable with guys around (e.g. some sort of mentoring).  So I'm not going to say flat-out they're wrong.

It's just I think it's not the right angle to attack the problem.  And you're segregating based on one dimension only, but as I said we're all different and we all have different problems.  The issues a non-white (am I allowed to say that?) lady might face could be different to those a middle class white girl like me has to deal with.  And do you want all-black conferences, and all-gay conferences, and so on and so forth?  Why are we special?  Why are we allowed to exclude the boys?  It's sexist.

Also, as a girl-geek, I get a bit freaked out when I'm surrounded by women, even if they're all geeks like me.  I'm much more comfortable talking to a guy, they tend not to try to read between the lines of everything you say or wonder if you're bitching about them behing their back </gross generalisation>.

Diversity is about being inclusive, not exclusive.

In Conclusion
Lots of the girl-geek, women-in-IT movement often appears to me as if women are "special" and need different treatment. This is not helping our cause at all. It causes resentment amongst our male peers and it puts off women who don't define themselves by their gender - people like the girls who are already in our industry. We like technology, we love programming, and we're good at our jobs.

So.  I don't know why there aren't more girls in programming.  And I don't have the answers as to what will tempt them in.

But, just for me, next time you're creating an advert or a website or something aimed at geek-girls, can we have more hot guys please?

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:

    Tuesday, 18 January 2011

    FogBugs and Kiln World Tour

    Last Thursday I was fortunate enough to get a place on the FogBugz and Kiln World Tour.  I booked it before I moved jobs, and I'll be honest I had no real interest in the software.  I've been reading Joel's books and blogs since my friend Brent bought me Joel on Software and made me read it (he had the foresight to know I'd want to hang on to his copy if he'd lent it to me!).  I wanted to see the man in the flesh and hear what he had to say about his software.  Because really, do we honestly need yet another bug-tracking / project-management tool?

    Who would benefit from FogBugz?
    Joel's demo was really good at demonstrating exactly how you might use the software - the processes you might follow, how to raise / update a ticket and chase it, and how you can see what's going on with the projects tracked.

    I can actually think of a number of companies I've worked for, or friends have worked for, that would see an improvement in productivity from using FogBugz for bug tracking / project management.  When I worked at Touch Clarity (later swallowed by Omniture, which was gobbled by Adobe) I was desperately looking for a product to help us:
    • Record defects
    • Capture new feature requests
    • Assign tasks to developers
    • Estimate tasks
    • Track progress - both at a project level and for individual developers
    • Provide us with a lightweight process which was easy to follow
    • Generate reports for management.

    From the demo I saw, FogBugz will do everything we wanted at that time.  We were using Bugzilla back then, and badly.  I'd also investigated XPlanner, VersionOne and a bunch of other defect/project management tools, and not really seen anything that did what I wanted (certainly that was cheap enough).  But this was back in 2004/5, we were doing a half-hearted version of eXtreme Programming, and we didn't have a lot of cash to burn.  It was hard then to find a lightweight, customisable, inexpensive tool.

    The things I saw in FogBugz that I thought would be useful were:
    • Nice UI - usability of these things is so frequently under-valued.
    • Really easy to track what's going on with a defect, to add and edit comments etc.  I actually liked that the edit feature still tracked versions of the comments, I can see how some organisations would need that audit trail.
    • Evidence-based scheduling - I liked the way that it uses past information to have a good guess at how accurate an estimate will be, and therefore the soonest, likely and latest times a feature might be delivered by.
    • Visibility over an individual developer's workload.
    • Visibility over work at a project-level
    • Loads of charts/reports to let you slice and dice the stuff you have in there.
    • Dependency management
    • Neat integration to source control - yes, I know you can get this for loads of management tools now, it doesn't mean it's not useful. It seemed pretty slick here.
    • It seemed quick.  But then it could have been a locally-running instance with about 3 defects in it.

    The things I thought would not be so useful in a more Agile environment:
    • Evidence-based scheduling
    • Visibility over an individual developer's workload.
    • Lots of the ways the data can be sliced and diced
    • Dependency management

    So, you like it and you don't like it?
    Yeah yeah, I've gone all multiple-personality again.  The stuff I liked about the product would be dead useful for the types of projects that work that way - where you assign work to individual developers who estimate the work; where developers are assigned to specific projects; where stories / features might not be broken down into small, independent tasks.  These places might be running waterfall, or some agile-ish process, or no process at all.  A tool like this will give them much better visibility over what's going on, over which deadlines won't be met, over who's estimates are flaky and who's are generally reliable.

    However even before I joined ThoughtWorks, before I joined LMAX, I was sold on Agile as a more natural way to run development teams (this is despite having worked with Touch Clarity's sort-of-XP and A Very Large Media Organisation's ScrumBut).  The problems that some of the features in FogBugz tries to address are similar to the problems that Agile (XP/Scrum/Kanban or some hybrid of these) is also supposed to address.
    • Evidence-based scheduling: I totally agree with getting statistical about this - teams and management should have a good idea how reliable estimates are.  But one of the ways to reduce the variation is to have the estimates done by the team.  At LMAX, we would have three developers estimate every story.  With any luck at least one of those would know enough about it to provide some solid technical guidance on what was involved, but if there wasn't someone in a group of three that had that knowledge, chances were pretty good the team generally were going to be pretty vague on it.  Granted, if you're using FogBugz you can enter the team estimate instead of just the individual who is going to implement it and then your evidence-based scheduling will be for team-estimates instead of personal ones.  This is totally fine, in fact it's a good thing - I just think we shouldn't use evidence-based scheduling to "fix" the problem that estimates are just that - an estimate, a guess.
    • Visibility over a developer's workload: If you're doing pair programming (XP), if the team takes ownership of the implementation of features / stories (Scrum), there's no need to look at how busy an individual developer is.  Yes, there are lots of organisations that do allocate work to individuals.  In many (most?) Agile-practicing teams, this will not be happening.  So really you only need visibility over a team or project level.
    • Reporting: Ah, I love reporting.  I love data, statistics, pretty charts. Maybe I'm secretly a project manager.  But it's SO easy to get hung up on the stats, on one tiny measurement, rather than the bigger picture - are we getting closer to "done" or not?  I think you should be able to get at all that data, but not get carried away micro-optimising for metrics which may be hiding bigger problems.
    • Dependency management: another thing that is dead important in some types of teams or organisations.  But the last few Agile projects I've worked on have not tracked hard-link dependencies at all - each story should stand alone, should be estimated on the basis of just doing that piece of work.  Yes, this is idealistic, and even in the projects where we did not officially track dependencies, we'd have a good idea of a very general order things should be done in (or an idea of the order things could be done in to make life easier).  But these things can be fluid, if a specific feature needs to be done now, you shouldn't have to do every single story that might have a tiny piece of functionality this story is dependent on - just tackle this story and everything you need for it.  
    All of those points could be blog posts in their own right, I know it's taken me years to get my head around the way I personally see Agile.  But you get the idea, or maybe you don't - that's fine, maybe you're in exactly the sort of place that could use FogBugz to improve your productivity.

    FogBugz vs Mingle
    I started at ThoughtWorks last week, so I'd better mention that ThoughtWorks Studios have a competitor product, Mingle.  I'm reasonably well-qualified to talk about it since I've been using it in anger for the last two years in a maturing agile environment, and I had my Mingle indoctrination induction last week.

    To me, the main difference is the angle the two products are taking to approach the same problem: how do you provide a tool that
    1. is easy and lightweight enough to use that people (particularly developers) will keep it up to date;
    2. tracks just the right amount of data that people have visibility over the state of development (What are we doing?  Are we going to hit our deadlines? What are our blockers?)

    To me, it seems FogBugz is coming from the traditional development model - it might not be anything as formal as waterfall, but it may not be based on short iterations and assumes individuals rather than teams are assigned work.  Mingle was developed for the Agile team, e.g. collective responsibility, pair programming, short iterations.

    Mingle is highly configurable, and while FogBugz has a number of templates and custom work flows, Mr Spolsky specifically stated at the demo that these really shouldn't be used.  That they've worked hard to find a process that works, and we should all follow that.

    So, Mingle embraces the differences between teams/processes and FogBugz specifically discourages it.

    I reckon these things are actually also the potential downfalls for both products too:  Mingle can be abused so badly that it adds no value; FogBugz could be so prescriptive it slows down productivity.

    But it's horses for courses, every tool has its advantages and disadvantages.  Or should I be pushing Mingle at this point until I pass my probation??

    Kiln, and an introduction to DVCS
    Good Lord, I've written all that stuff and that's only from the short demo at the start of the day.

    Fortunately I have a lot less to say about the latter part.  It was an introduction to Distributed Version Control (DVCS), and it was pitched absolutely right for someone like me.  

    I've never used a DVCS; most recently I've been using Subversion, but I've also used PVCS, ClearCase, VSS and a bunch of others (in fact, I'm pretty sure I've had to learn a new source control system every time I've switched project or company!).  I've been introduced to Git over a lunchtime, and I read Martin Fowler's blog post on version control tools.  The intro provided by FogCreek was spot on for me.  It showed me:
    • The differences between a DVCS and something like Subversion (OK, specifically svn, which is fine for me);
    • Advantages of using a distributed source control system;
    • Some mindsets that you need to change when switching from svn to a DVCS like Mercurial;
    • The FogCreek way of setting up the repositories.

    The last point was particularly useful in giving some real-life examples of how to use a DVCS and why.

    Then there was some stuff on why Kiln might give you more than just the freebie Mercurial install.

    It was more useful in a general fashion than the FogBugz section.  However, like the FogBugz talk, I got a good feel for the types of teams/companies Kiln might be good for, and why you might use it.  Personally it convinced me that using a DVCS in general is probably better than Subversion (insert usual disclaimer of different tools being appropriate for different situations).  It certainly encourages working practices that will lead to a) less accidental loss of code (after all, that's what source control is for) and b) if well organised, better separation of bugs / features / stories and better integration across versions and branches.

    If you want to know what I've been blathering on about in this section, check out Joel's excellent introduction to Mercurial.  OK, I admit it, I haven't read it all.  But it seems to cover everything that was covered in the conference session, with Joel's usual wit and appeal to the developer mindset.

    In Other News
    In terms of an education session, the "World Tour" was excellent - succinct, easy to digest, and (to my mind) aimed exactly at the audience.

    However.  I actually ended the (half) day being slightly disappointed, and not just because these tools don't seem to be ideal for the Agile team. 
    • I didn't get enough of a chance to network.  Now, I'm happy to admit this is a problem I regularly have - because, like many developers, I find it difficult to talk to new people in a big room full of people I don't know.  However, given that this was a big room full of developers, I wish there had been more of an effort made to help us to mix and network. Before the talks we were on tables in another room having coffee etc, which I liked because it did lead to some conversation in small groups.  But I would have been nice if there had been a chance at the end of the talks to chat to people and dissect the session (if there actually was, it was so badly publicised I missed it).  I went with a stack of business cards and didn't give a single one out.
    • The half day didn't seem like enough.  But this might be more a reflection of the above point since I got what I wanted from the talks, any more would have been too much info.  So maybe I just wanted more time with the attendees and with the FogCreek guys.
    • I was shocked by how few women there were.  I'm no tech newbie, I've been to training sessions, conferences, user groups, seminars, and worked on site at a lot of different types of places.  I was very surprised to see that in a room of several hundred people I counted 5 women (myself included).  This seems low even for gathering of techies, it seems very low for a presentation on a piece of software that is effectively project management software.  I don't have the stats to hand, but in my personal experience any technical event with even a sniff of project management stuff is better represented across both genders.  I wouldn't normally comment on it because it's something I'm used to myself, but I've been asked a bunch of times in the last two weeks "what do we need to do to encourage more participation by women?", and I have my eyes open for stuff which might help me answer that.

    In Conclusion
    1. A generally good, well-run event, especially as it was free (if I recall correctly).
    2. FogBugz and Kiln are excellent tools for a certain type of organisation / team, and I'm not talking about a small minority of teams here.
    3. If you're Agile, these tools are probably not for you.  You can get them to work, and if you're "kind of" agile they're probably better than a lot of your options.  But true agile teams running an effective process might find themselves hindered more than helped.
    4. I'm going to download and install a DVCS the very next time I have to write a line of code.


    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.