Using the :first-of-type pseudoselector instead of :first-child

Consider this case: you have a blogpost with an image, a heading, and some text. You want a little margin on the top of every heading to divide the different sections. Your HTML might look like this:

<article>
    <img src="photo.jpg" alt="A nice photo" />
    <h3>My heading</h3>
    <p>Text. Bla bla bla</p>

    <h3>Another heading</h3>
    <p>Even more bla bla</p>
</article>

Your CSS might looke like this:

img {
    float: right;
    margin: 0 0 10px 10px;
}

h3 {
    font-size: 24px;
    margin-top: 24px;
}

p {
    font-size: 16px;
    margin: 12px 0;
}

Now here’s a problem. The very first <h3> will have an ugly margin at the top, so it doesn’t line up with the image. How would you style it so that it won’t have a margin at the top? My first guess was to use the :first-child selector:

article h3:first-child {
    margin-top: 0;
}

However, that doesn’t work. The spec is not very clear about it: but here’s the problem: :first-child only selects the very first element and doesn’t care about the element you give it. That’s great if all your elements are the same (such as <li> elements in a list) but it sucks when having a case like this.

Fortunately, there’s a new CSS3 property that’s perfect for this case. It’s called :first-of-type and does exactly what you want.

article h3:first-of-type {
    margin-top: 0;
}

Browser support is mostly pretty good, although you’re out of luck on Internet Explorer 8 and earlier.

Fixing ‘OS Process Error’ in CouchDB Single Server for Mac OS X

When i downloaded the Couchbase Single Server 1.1.2 for Mac OS X i tried replicating a database and tried to view a view. Unfortunately all i got was endless errors in my log:

[error] [<0.159.0>] OS Process Error <0.17372.0> :: {os_process_error,{exit_status,1}}
[error] [<0.159.0>] OS Process Error <0.17375.0> :: {os_process_error,{exit_status,1}}
[error] [<0.159.0>] OS Process Error <0.17378.0> :: {os_process_error,{exit_status,1}}

When i looked in the configuration i noticed this value in my ‘query_servers’:

bin/couchjs /Users/dustin/tmp/master/build/share/couchdb/server/main.js

When you change this to:

bin/couchjs share/couchdb/server/main.js

Everything works again.

Vote on the ticket to get it fixed for the next release :)

HOWTO run multiple versions of Firefox side-by-side on Mac OS X Lion

Cross-browser testing is pretty essential when developing web sites. Most of the bugs you need to fix are probably in older versions of Internet Explorer. Both Chrome and Firefox have a very fast release cycle, where new versions are released every six weeks or so.

However, there are still many people using the older 3.6 version of Firefox. Firefox 3.6 has a few bugs, and because of its big installed base you probably need to run some tests on it as well.

There’s a problem here: Firefox doesn’t like it when two different versions are run side-by-side. Fortunately there are a few tricks you can use to make this happen. This should also work on Snow Leopard, provided you have at least 10.6.2, because the --args parameter was introduced in that version.

  1. Download the Firefox 3.6 release from Mozilla.com.
  2. Unzip and mount the DMG file.
  3. Drag the file from the DMG to your Desktop instead of to the Applications folder.
  4. Rename the .app to ‘Firefox36.app’ and move it to your /Applications folder
  5. Run this command from a Terminal (found in /Applications/Utilities):
    /Applications/Firefox36.app/Contents/MacOS/firefox-bin -ProfileManager
  6. Add a new account. Call it ‘test’.
  7. Run Automator. From the ‘Choose a type for your document’ menu, select ‘Application’.
  8. Drag ‘Run Shell Script’ to the action area.
  9. In the content area (where ‘cat’ is displayed) copy-paste this line:
    open /Applications/Firefox36.app --args -P test
  10. Save the document to /Applications as ‘Firefox 3.6′
  11. Drag ‘Firefox 3.6′ application from the Applications folder to your dock for fast access.
  12. You’re done!

For a nice icon to differentiate your current Firefox version with the old one get the full resolution PNG from above this article right here. Open it in preview, select all (Cmd-A) and press copy (Cmd-C). Open up the Automator .app by right-clicking and selecting ‘Get info’ or hitting Cmd-I. Select the icon in the topleft corner so that it is outlined and press Paste (Cmd-V).

Basic HTTP authentication in Node.js using the request module

Here’s an easy way to use basic authentication while using the request library for Node.js.

Unfortunately request doesn’t come with an easy convenience parameter you can use, so you need to provide it by yourself. The common way is to add it as an extra HTTP header.

Let’s say you need to login to example.com using user and pass as your username/password.

var request = require('request'),
    username = "john",
    password = "1234",
    url = "http://www.example.com",
    auth = "Basic " + new Buffer(username + ":" + password).toString("base64");

request(
    {
        url : url,
        headers : {
            "Authorization" : auth
        }
    },
    function (error, response, body) {
        // Do more stuff with 'body' here
    }
);

This is pretty verbose. Fortunately, you can use a trick using the URL itself, as specified in RFC 1738. Simply pass the user/pass before the host with an @ sign.

var request = require('request'),
    username = "john",
    password = "1234",
    url = "http://" + username + ":" + password + "@www.example.com";

request(
    {
        url : url
    },
    function (error, response, body) {
        // Do more stuff with 'body' here
    }
);

Nice one huh?

jQuery 1.5 and JSONP requests

jQuery 1.5 adds better support for JSONP requests. As you might know, JSONP is a way to avoid the same-origin policy and do cross-domain requests by adding a method call around the JSON data.

Because browsers don’t return data from requests that fail, error handling is tricky compared to normal AJAX requests. There is a workaround by using a timer, which is the way the popular jquery.jsonp plugin solves it.

jQuery 1.5 adds this workaround, so you don’t need this plugin. All other features of the plugin, such as custom callback naming, are possible in jQuery now as well.

Here’s an example:

var req = $.ajax({
    url : url,
    dataType : "jsonp",
    timeout : 10000
});

req.success(function() {
    console.log('Yes! Success!');
});

req.error(function() {
    console.log('Oh noes!');
});

The timeout parameter is essential, because this indicates when a request should be considered ‘failed’. Because of this extra parameter you need to use $.ajax instead of $.getJSON.

The req variable contains the jqXHR object, which can be used to attach multiple callbacks and error handlers.

Koffie + Wifi: Centrale Bibliotheek Utrecht

De zogenaamde digitale nomade is in opkomst: geen kantoor meer nodig, je werkt op je laptop vanuit een koffiebar. Of zoiets. Nu zou ik mezelf helemaal geen digitale nomade willen noemen, maar ik vind het wel fijn om af en toe wat mails weg te werken op een andere plek dan mijn eigen huis.

De eisen zijn simpel: koffie en wifi. Maar dat te vinden is nog niet zo makkelijk. Ik probeer af en toe een locatie uit en ik blog hier mijn bevindingen.

Deze keer: de centrale bibliotheek in Utrecht.

Wifi

Wisselend. Hotspot van KPN die gratis is voor alle bezoekers (dus ook niet-leden). Inloggen op ‘KPN’, willekeurige webpagina openen en ‘akkoord met de voorwaarden’ en je kunt internetten. Meestal. De snelheid wisselt nogal: als je eenmaal verbinding hebt werkt het meestal ok (Spotify gaat prima), maar soms gaat het ook tergend traag. En niet overal bereik: bijvoorbeeld bij de leuke tafeltjes bij het raam. De tafeltjes bij de koffiecorner lijken goed bereik te hebben. Wel een voordeel: weinig geblokkeerde poorten: SSH, VPN, Secure IMAP en zelfs IRC doen het.

Voor de nerds: hier is het grafiekje van speedtest.net:

Koffie

Uitstekend, bij de koffiebar. Lekkere latte voor 2.10. Gratis water en prima broodjes en koekjes.

Stroom

Stopcontacten zijn sporadisch en niet altijd makkelijk te vinden. Goed zoeken of met een volle accu binnen komen.

Toilet

Begane grond. 50 cent.

Omgeving

Locatie is prachtig, in een mooi pand boven de Broese met uitzicht op de Stadhuisbrug. Voor een bibliotheek enigszins rumoerig, maar rustiger dan bijvoorbeeld bij Seats2meet. Redelijk wat werkplekken, maar het is soms even zoeken naar een plek met én goed wifi bereik én stroom. Kans op zwervers die naast je gaan zitten en in slaap vallen of draaiorgels die op straat ‘Shalalieshalala’ van Sieneke en Vader Abraham spelen.

Openingstijden

Maandag en donderdag tot 21.00. Anders tot 18.00. Niet open op zondag. Alle openingstijden.

Oordeel

Als de wifi het doet is de centrale bibliotheek een prima plek, zeker vanwege de koffie en goede locatie. Jammer het trage internet, de vroege sluitingstijden (en niet open zijn op zondag) en het gebrek aan stopcontacten.

Cijfer: 7,5

Locatie: Oudegracht 167. Kaartje.

De ultieme chocolademelk

Foto: Jukka Zikking / CC-BY

Vanwege het winterweer het ultieme recept voor warme chocolademelk

  1. Vul zoveel kopjes als nodig met (halfvolle) melk.
  2. Gooi alle melk in een klein pannetje. Laat een beetje melk over in de kopjes.
  3. Verwarm de melk op een laag vuurtje. Niet laten koken!
  4. Roer in elk kopje 2 en een half theelepeltje cacao (b.v. Blooker of Droste) en 1 theelepel suiker.
  5. Roer het restje melk, cacao en suiker goed door elkaar zodat het een gladde massa wordt.
  6. Voeg de warme melk toe in elk kopje en roer nog even goed door.
  7. Voor het extra feestelijke element kun je nog slagroom op de melk spuiten.

» An overview of all articles can be found in the archive.

Hi! I'm Hay. I make art, do projects and blog here. Read more »

Projects

More Hay at...

Archives by month