Archive for December, 2006

The death of * HTML

Wednesday, December 27th, 2006

As I’ve now started to look at how some of my sites work in IE7, I discover that the main thing that has gone wrong is that the hack where you prepend CSS selectors with * html is now disabled. Of course I could have found this out six months ago but frankly, learning the particular quirks of an as-yet-unreleased and sickeningly broken user agent is not something I am going to invest time in.

Obviously, this means that for any site that IE7 breaks, it is failing on the standards-compliant CSS. But equally, as I noted before, not as many sites break as was expected. So that’s pretty good news.

But for the sites that do break, and future sites in general, the situation is a mess. It’s now necessary to split IE7 styles into different, conditionally included files, either by selecting on UA (which is unreliable) or use a gut-wrenchingly sickening IE misfeature called “conditional comments”. IE6 rules need to be moved too, as IE7 will have significant common ground with IE6 and you don’t want to have to maintain two copied of any rule that is shared.

Having rules split between different files makes it harder to work with, because in CSS you need to literally compare selectors to work out the precedence. * html is much easier to work with because you can place your IE rule right next to your real browser rule, and easily cross-reference the differences. Or if you change the real-browser rule, you can also amend the IE rule at the same time. More annoyingly, if you already have a tidy collection of CSS stylesheets importing one another with the @import statement, you have to either collect your IE styles in one file, or duplicate the tree for IE. Neither is very maintainable. The @import statement is not very useful anyway though, because CSS’s precedence rules don’t allow CSS to be modularised in an elegant way.

In Microsoft’s defence, they are looking for a painless route to standards compliance that in all honestly does not exist. But I apportion the blame entirely to them, for two reasons. First, it was they who let the situation regarding standards compliance get so out of hand first; in effect, they are five years too late in starting to take this course of action. Secondly, bundling IE with Windows is one of the most devastatingly damaging things they have ever done. The cost to businesses worldwide could run into hundreds of millions, if not billions of dollars, and this money is not even paying Microsoft shareholders: it’s being flushed down the toilet. Web designers to some extent profit from it at the expense of other businesses, but even so, we would rather not have to do it because we would then simply be able to achieve more. We would probably charge more or less the same, but all sites would be stunningly beautiful with rich interactivity.

CSS, has its own problems, of course, but these would have been very hard to predict all that time ago when it was drawn up:

  • Selector-based stylesheets cannot be refactored without reference to a schema for the source document.
  • CSS cannot deal with varying capabilities across implementations.
  • CSS cannot be modularised, because selectors can very easily collide and supercede each other, dependent on the way the selector is described rather than the structure of the module. For modularised HTML/CSS ‘components’, you really need to prevent styles being overriden unless explicitly requested.
  • CSS units cannot be specified as an arithmetic operation on unknowns, such as ‘(1em-3px)’. This means dimensions measured in ems (useful for text) are incompatible with lengths measured in pixels (useful for images).
  • CSS has insufficient control of vertical positioning. The basic operations available are “the vertical order is the same as the document order”, “x is at this vertical position”, and with a bit of creativity with floating blocks, “x follows all of these”, plus one modifier, “all my descendants lay out relative to me”.
  • CSS doesn’t allow constants. This means that you have to repeat constants, say colour codes or border styles, and change them in more than one place.
  • CSS has some bizarre quirks. For example, it doesn’t include padding in the width and height dimensions, so if you increase the padding, you have to decrease the width correspondingly. IE for years did the opposite, which is totally wrong but much more intuitive.
  • CSS selectors are lacking tidy disjunctions and assertions, things that exist nicely in XPath. It’s possible to work around these, but not necessarily succinctly.

IE7 scores a point over FF2

Friday, December 8th, 2006

If anyone’s keeping score, I’ve found my first snippet of code which IE7 handles flawlessly but FF2 does not.

It’s code for creating multiple recipient email fields with Javascript, such that creates as many as necessary and keeps the last field spare. Specifically this code is for deleting fields, which happens when you backspace or delete from a field which you’ve already emptied. This is modelled on how Thunderbird/Icedove’s compose window behaves.

function autoCompleteContact(e)
{
    var event=(window.event)?window.event:e;
    var target=(window.event)?window.event.srcElement:e.target;

    //catch backspace or delete on an empty field as deleting the field
    if (target.value == '' && (e.keyCode == 8 || e.keyCode == 46))
    {
        //don't delete the last field if it's empty
        if (target == recips[recips.length -1])
            return;

        //find the container element for all recipient input fields
        var recips_container=document.getElementById('recipients');
        if (!recips_container) return;

        //Javascript doesn't seem to provide an array remove()
        //so do effectively newrecips=recips.remove(target) manually
        var newrecips=new Array;
        for (var i=0; i < recips.length; i++)
        {
            if (recips[i] != target)
                newrecips.push(recips[i]);
        }

        //Don't remove the last field
        if (newrecips.length > 0)
        {
            recips_container.removeChild(target);
            recips=newrecips;
        }

        //Focus the last field
        recips[recips.length-1].focus();
    }

    ...

IE7 does it perfectly, FF2’s layout breaks and it starts showing the contents of the INPUT elements in the wrong place.

GnuCash Accounts

Thursday, December 7th, 2006

The past couple of days have been spent tidying up my accounts in GnuCash. It’s great when it all comes together and your accounts reconcile perfectly with your statements.

I like GnuCash a lot actually. It’s slightly harder to get your head around than just listing your accounts in a spreadsheet, but much more powerful when it’s done. Because money always has to go from somewhere, to somewhere, you can view transactions from both ends immediately. So every time I pay for a domain name on card, I see the money transfer from my credit card, with the net cost going to the registrar, and the VAT value going to my VAT account and reducing my debt to the VAT man. And then I can turn it round and see the actual cost to me of the domains, or track my VAT debt.

The other neat thing is that accounts are nested, so for example, I can create an account for each client within Accounts Payable, and see how much each client owes, plus clients’ debts to me can be included within my assets. GnuCash’s own customer invoice tools don’t do use subaccounts though, which makes them actually harder to work with than doing it manually, I find.

At first I found GnuCash kind of quirky, and I did struggle with it. But the new 2.0 series is better on the UI front (now a GTK2 app) and now I know what I’m doing with it, it’s actually quite easy to get everything to work and incredibly useful when it does. It becomes quite frustrating that all the other accounting information I receive is in a simple flat transaction list, like a spreadsheet or a bank statement or some printed accounts. It’s not wrong; there may be no other way to do it; but it’s simply not so elegant and right.

All I need is some way to get the accounts data to my accountant.

I tried a few different ways:

  • Linux VM with GnuCash and accounts, burned to a CD along with VMware player. Couldn’t get Ubuntu VM to fit on a CD; Debian and Damn Small Linux wouldn’t install properly.
  • Converting to QIF with a Java tool. Tried importing this into Grisbi and it looked a mess.
  • Importing GnuCash directly into Grisbi (with the intention of exporting to QIF or CSV or something). Seemed to make a mess of it, not as much as the Java exporter, but the account balances were all wrong.
  • Transforming to Gnumeric sheet with an XSL stylesheet and sabcmd. No account balances, but these can be added quite easily within the spreadsheet app. Required me to install Gnumeric.

I sent the QIF and the spreadsheet (saved as XLS) to the accountant. Other ways that occurred to me:

  • Hand them an Ubuntu CD and my GnuCash files. This would require them to reboot into Ubuntu and GnuCash isn’t even included on the CD anyway.
  • Hand them an Ubuntu CD, an empty VMware VM and my accounts, and let them install everything. Probably too technical and overkill.
  • Set up a VNC server that they can log into to access a copy of GnuCash. Security aside, I don’t know what kind of connection they have. It could either be too slow for them or it could DoS my outbound connection.