Posts from 2009

@meyerweb *wondering just how many of your followers follow @zeldman and vice-versa*

I had no idea. Furthermore, I didn’t know of a tool that could tell me. So I built one: Followerlap.

As it turned out, the Twitter API made answering the specific question pretty ridiculously easy, thanks to followers/ids. All it takes is two API requests, one for each username. The same would be true of friends/ids, on top of which I suspect I’ll fairly shortly build a tool quite similar to Followerlap.

Why not list the common followers? Because followers/ids returns a list of numeric IDs. Resolving those IDs as usernames would require one API hit per ID. If there are 15 followers in common, that’s not such a big deal, but if there are 1,500, well, I’ll run out of my hourly allotment of API requests very quickly. Maybe there’s a better way; if so, I’d love to hear about it, because that would be a great addition.

Why can’t I find out how many people follow both Stephen Fry and Shaquille O’Neal? Past a certain number of followers, somewhere in the 200,000–250,000 range, the API just dies. You can’t even count on getting a consistent error message back. There are ways around this, but I didn’t want to stress the API that way, so it just fails. Sorry.

How can I link to a specific comparison?At the moment, you can’t. I hope to make that happen soon, but I decided that a tool this simple should have a similarly simple launch. Ship early, ship often, right? Anyway, it’s on the list of things to add soon. Use the new “Livelink to this result” link underneath a result. (See update below for more.)

So that’s Followerlap. Any other questions? I’ll do my best to answer them in the comments, though for a number of reasons I may be slow to respond.

Update 6 Jul 09: as noted in the edited point above, livelinking of comparison results is now, um, live. So now you can pass around results like the number of people who follow both God and the Devil (thanks to Paul M. Watson for coming up with that one!). I call this “livelinking” because hitting a result URL will get you the very latest results for that particular comparison. “Permalinking” to me implied that it would link to a specific result at a specific time, which the tool doesn’t do and very likely never, ever will.

It’s taken me slightly more than a month to write this post. It’s about people at their best.

Last month, just after speaking at a conference in Amsterdam, my laptop was stolen.

Actually, to be more painfully accurate, my laptop case was stolen—and inside it at the time was the laptop, my mobile phone, and my wallet. Plus the usual assortment of stuff that goes into a laptop case.

Because I still remember to this day advice Tantek gave me just before we boarded a bus to Narita airport, I had my passport on me. I happened to have picked up my camera to take some pictures of the conference hall. My clothes were still in my hotel room. Everything else was gone.

I can’t really describe the feeling. Maybe you’ve felt it. Shaking and stunned and self-blaming and nakedly vulnerable. All that magnified by the complete loss of funds and communication with my family.

And the data. The lost data. I have backups, but they’re never as current as one would want. (Which reminds me: if you aren’t backing up, and you aren’t doing so regularly, learn from my loss and start.) Besides, at that moment, as the full realization of what had happened slid coldly into my gut and started its slow, merciless expansion throughout my entire body, I didn’t think “Oh, I have backups until that date, and all my work mail is on the mail server, and I’ve been uploading the best pictures to online services.” Those things didn’t occur to me. They were completely blocked by the continual, sickening, endlessly looping thought: IT’S ALL GONE.

And that’s when people started pitching in to help me out.

In addition to helping me look for the case in hopes that it had just been moved somewhere non-obvious, Khris Loux of JS-Kit let me call home from his iPhone without a second thought, so I could tell Kat what had happened and get her immediately started on contacting banks and credit card companies. And the honest concern in his eyes helped snap me back from near-paralysis, touched by the regard coming from someone I’d only met an hour before.

Then Gabe Mac, having heard what was going on, came up to me with a fully charged mobile phone I could borrow so that I could remain in contact with my family until I went home. He didn’t ask me how I would get it back to him, because I don’t think it had occurred to him. He just said, “Eric, I have a spare phone. You need it. Take it.”

So I did. And much, much later that same night, it was nearly a lifeline.

Throughout all this, Boris and Patrick, the conference founders, were working to find out if one of the tech crew had accidentally picked it up, or it had been turned in to venue staff. And when it became inescapably clear that the case was well and truly gone, they sent one of their staff to get a SIMM card for the phone Gabe had loaned me and 200 euros in cash so I could get home. Just did it, because they could see that I would need those things even when I couldn’t. They also arranged a ride for me to get to my evening’s social appointment.

That appointment was with Steven Pemberton and his lovely family, who fed me a great dinner in their fabulous top-floor flat and were more than gracious about my disordered mental state. After dinner, Steven took me to the nearby police station and acted as translator as I filled out a report. And then he loaned me use of his home phone to call a couple of credit card companies that I had to speak with personally in order to make sure my business credit cards were cancelled.

It wasn’t the relaxed evening of dinner and shop talk I’d been hoping to have, but I did several things that needed to be done and Steven made it possible. And we did get in a tiny smidgen of (very interesting) shop talk near the end.

At every step of that evening, someone was there to help push me forward, help me lower the unexpected barriers just a little bit, help ease the situation however they could. So many people coming together to help out someone they’d known for years or never before met. Thanks to them all, I was able to get home without further incident. Thanks to them all, I had a major yang to the theft’s yin, a powerful reminder of just how good people can be.

There’s something about the Diggbroglio that has left me scratching my head: how is it that so many people are up in arms about the DiggBar when they’ve had nothing to say about the framing bars of StumbleUpon, FaceBook, etc. etc.?

Now, please note that I’m not saying the DiggBar, or any other framing bar, is cool and we should all love it. I’m not. I absolutely, completely, totally get all the reasons why framing bars are bad for breaking bookmarking and navigating and search engines and copyright and hijacking content and so on. But that’s precisely why I’m so confused, because we’ve known for years now that framing bars are bad mojo—and yet StumbleUpon, for example, is based on bars. There is a browser extension/plugin StumbleUpon thingy you can install, but there’s also a web-based framing bar thing (see this link, for example) that they offer, and I bet people use. You don’t have to be a member to use it: I hit that link in a browser that allows cross-site frame loading and I get the bar and the page it’s framing, and I’ve never been a StumbleUpon member. The source shows it’s using iframes to make it happen. So far as I can tell, it’s not really different from the DiggBar.

So why do we have people writing JavaScript and PHP and Ged-knows-what-else that specifically busts out of the DiggBar framing, instead of busting out of all framing? After all, site framing is universally agreed to be objectionable; even yet-to-be-discovered life forms orbiting distant stars think it’s a bad idea. So why is one instance of it being targeted while the rest are tolerated? Why are we all not just using if (top != self) {top.location.replace(self.location.href);} and other-language equivalents? Yes, I know, some of you do just that, but why isn’t everyone?

Perhaps because I have yet to eradicate a stubborn streak of faith in the rationality of my peers, I assume that there’s some technical difference here that I’m missing and that, once understood, would let me understand the source of the outcry. So can someone please explain to me, or point at an explanation that states, the technical ways in which the DiggBar is worse enough than already-extant framing bars that it’s triggered this outrage? Again, nobody has to enumerate the complete list of the DiggBar’s sins; I understand. A list of any different and more egregious sins would be just fine, though.

Also, if anyone comes up with a way to bust out of the frames while still preserving the bar—that is, correcting the problems framing bars cause while preserving their functionality for the people who want to use them—that would be extra-cool. After all, people who use those services like the bars. If we could let them browse the web the way they prefer while fixing bookmark/SEO/etc. problems framing bars can cause, that would be a win all the way around.

In creating the combo-bar charts for the survey report, I stumbled into an Explorer bug that I didn’t remember ever seeing before, and Google didn’t turn up anything that seemed to be related. This could easily mean that I’m the only person who ever did something this insane and thus found the bug. It could just as easily mean that my Google-fu has failed. Either way, I’ll write it up here so it can enter the collective memory. (And surely someone has already noted that Google is positively Jungian?)

You can see both the problem and two workarounds if you visit this test page using IE6 or IE7. In brief, the problem occurred when I had a table cell containing a paragraph with an explicit width set. I did this through the style attribute, though tests show that for this bug, it doesn’t matter whether you use the attribute or assign it via a style sheet. Around these explicit-width paragraphs were div elements with width: 200%;, for bar-drawing purposes (it’s a little complicated). Everything was fine in 99% of cases. But as soon as the header text at the beginning of the row went to two lines of text, the explicit-width paragraphs doubled in width. What was 80.1% wide would be drawn as though it were 160.2% wide.

My hopefully understandable reaction was to say, “Whuh?”. I threw a few hasLayout triggers at the offending paragraph (relative position, zoom, etc.) and got nowhere. In the end I worked around the problem by telling IE6 and IE7 to not wrap text in the row headers of combo charts. (The bug is not present in IE8.)

I mentioned all this in my announcement post, and the ever-awesome Dan Wilkinsondiscovered that the problem could be fixed by setting all of the table rows to, say, height: 3em. Armed with that breakthrough, I experimented a little more and found that I could actually set the offending table row’s height to 2.75em and still have things work as intended. Below that and the paragraph widths doubled.

Then I lowered the line-height of the headers to 1 and found that I could take the overall row’s height as low as 2.33em before triggering the bug. And that’s when it dawned: the bug was triggered by the layout height of the header cell’s content being taller than the content of the cell containing the paragraph, and not explicitly declaring styles that would make the data cell as tall as or taller than the height needed to have the header cell contain its content.

Okay, that’s a little dense. Let me step through the symptoms and two found workarounds to see if that clears it up:

The data cell always has a single line of text. The bug is triggered by having the header cell go to two lines of text, whereas it is not if the header cell has a single line of text.

If the row’s height is explicitly set to a value equal to or greater than the header cell’s content, the bug is not triggered.

Alternatively, if the height of the data cell is set or forced to be equal to or greater than the height of the header cell, the bug is not triggered. This can be done with an explicit height or with added top and bottom padding or by adding top and bottom margins to the paragraphs in the cell.

Some side tests I did indicate that the header cell is not needed to trigger the bug. In other words, the problem could happen even if there are only data cells in the row. Furthermore, I found that the width-scaling was directly affected by the width of the wrapping div, and thus the widths were doubling only because I had the div‘s width set to 200%. If I set it to 150% instead of 200%, then the paragraphs only got half again as wide instead of doubling. That seems to make sense until you see it in action. When I say the paragraphs got half again as wide, I mean that instead of being 75% as wide as the div, they were 112.5% as wide as the div. If I set the div‘s width to 200%, then they were 150% the width of the div.

So. As I say, this bug does not affect IE8, so that’s good, and it can be worked around in IE6 and IE7, which is even better. The problem would be if you didn’t know how tall your cells might get—in my case, I can be (reasonably) sure that the tallest a cell’s content will ever get is two lines of text, and by setting an explicit line-height on the headers I can know how tall I have to make the rows in order to avoid the bug.

There are a great many reasons why it took so long to get this out the door. A big part is that it’s almost entirely a volunteer effort, which means it happens in our “free time” (and there the word “free” has a couple of meanings). I say it’s almost entirely a volunteer effort because the detailed analysis is actually done by a pair of professional statisticians, who are paid for their time and expertise. They did a great job once more, and did it in a reasonable time frame. It just took us a while to get them the data to analyze, and then a while longer to take their report and findings and process them into report form.

The biggest change this year is that we’re publishing the results as HTML+CSS instead of a PDF. This greatly increased the challenge, because it was important to me that the data be presented using styled tables, not images. That’s easy like cake if all you’re doing is putting them up as visual tables, and we certainly do that for some of the figures. In the other cases, where we have bar charts of varying kinds, things got difficult. I managed to devise solutions that are 99.9% effective, and I’m both proud of and frustrated by those solutions. Proud, of course, because I managed to wring three-stack bars out of table markup; frustrated because of the markup I had to construct to make them possible. I think this report represents more than half my lifetime usage of the style attribute, but unfortunately there’s no way (using just CSS) to say {width: content;}.

So why not use JavaScript to do that, or to just replace the tables with canvas-drawn charts? I did consider both, but decided that I would push as far as I could with plain HTML+CSS.

A few implementation notes:

I used HTML 5 in order to step around some previously unrealized limitations of HTML 4—did you know tfoot has to come before tbody in HTML 4? I didn’t. I did not use elements like header and footer due to known problems in Firefox 2 and related browsers, which mangle pages containing those elements. Instead, I took the same path Jon Tan recommends, and classed divs using those names for later, easier conversion.

The tables which underlie the charts do not have summary attributes. If a group of civic-minded individuals would like to write useful summaries, please let me know in the comments and I’ll let you know how best to submit them. Similarly, I did my very best to make sure all the table headers had accurate scope values, but if I botched any, let me know.

I’m aware that Opera shows horizontal scrollbars on most chapters of the report. This is due to its refusal to apply overflow to table boxes, which according to my recent reading of the CSS 2.1 specification is the correct thing to (not) do. Every other browser I tested does apply overflow to table boxes, though, which I found most useful. I tried applying overflow: hidden to a few other boxes, and that got rid of Opera’s horizontal scrollbars, but it also cut off actual content in some other browsers. I chose a cosmetic problem in one browser over loss of content in others. The best fix I’ve devised is to wrap the tables in divs and apply overflow: hidden to those divs, but I didn’t want to rush the fix and botch it, so it didn’t make it in time for first publication. I expect to get it in shortly after publication.

In a like vein, there are a few combo charts where a bar goes shooting off the right side of the chart in IE7. This appears to be due to some kind of width-doubling problem that’s only invoked on elements with a style attribute when the row header goes to two lines instead of being just one. Googling for an explanation yielded no joy, and a lengthy series of attempts to hack around the problem came to nothing. If anyone knows how to counteract that problem other than preventing the header text from going past a single line, I’d love to hear it. (Update: I’ve implemented the “fix” of preventing line-wrapping in the report, so there aren’t any off-the-page bars right now, but you can see an example of the problem on this test page.)

Surprisingly, the charts mostly work in IE6. The exception is some of the triple-stack charts, where data points overlap when the rightmost sub-bars get too small, and also the double-width bars mentioned in the previous point. I don’t really have a fix for this short of upgrading the browser, but if somebody finds one, I’d be happy to test it out.

On that last point, if there are questions or suggestions surrounding the implementation of the report, we can certainly discuss them here. With regard to the survey and report itself, though—that is, the questions asked and the results we’re publishing—please direct those thoughts to the comments section of the ALA article announcing the report. I’m hoping that we’ll have the 2009 survey up within a few months, so comments on what we asked and how we asked it, what we didn’t ask but should have, and that sort of thing could well have a direct impact on the next survey. But please put those on the ALA site, where more people are likely to see them.

It’s done, it’s out, it’s yours—both the report and the data, about which I’ll soon write a little bit more. Read the report, or produce your own report using the data. Just always know that when we publish these reports, we do not mean for them to be the final word. No, what we always mean is for them to be the first words, a starting point, a place from which to grow. What comes next is as much up to you as anyone else, and I can’t wait to see what you do.

One of the things that I’ve found mind-bendingly annoying about Leopard (besides its complete refusal to allow classic window management) is the “this file was downloaded from the internet, are you sure you want to open it?” dialog box. Yes, damn it: I just downloaded the file with the express intent of opening it. Stop bothering me. Keep it up and I might mistake you for PC.

What’s even worse is that the dialog requires mouse input to get past. It would be just within the limits of acceptability if the dialog buttons responded to keyboard input; if I could hit command-O or something to invoke “Open”, then I’d probably keep the safeguard in place, because I could just charge past it with a quick twitch of the fingers. Since I can’t, I want it gone. And of course there’s no “don’t ask me again” checkbox to tick.

After a plea on Twitter, I got pointers to a couple of ways to disable this annoyance (as well as a ton of “oh God, I hate that too; let me know if you find an answer!” replies). The first way is done as a Folder Action. For a variety of reasons, I’m not that thrilled by folder actions, so I gave it a pass. The other approach is to write your own preference file. Ah, much better! (Why is this better? I don’t know. It just intuitively feel like the better approach to me.)

Now, one way is to just disable the warning for all public.item files—which is to say, every type of file. I was tempted, but it turns out there’s a finer grain that can be applied: listing specific file types to be ignored. Better still! That way I can switch this off for the file types that I download all the time, like HTML files, and keep the safeguard in place for file types I almost never download, like executable scripts.

Doing this means you need a list of OS X’s Uniform Type Identifiers, so I dug around to find that listing, which appears to have moved in the not-too-distant past. Here’s the preference file I’ve put together with that listing as a guide. This file lists all of the file types I don’t want to be nagged about.

I led with public.text because it encompasses not just regular text files, but HTML files as well; public.xml appears to cover XHTML, though I’m not 100% sure where those files fall. public.audiovisual-content covers all audio and video files, as you might guess. There are probably a few other types I’ll add over time, as I encounter enough resistance on certain types of files that I don’t need to be safeguarded. I’ll probably never add public.script or public.executable to the list; personally, I prefer to be warned about that sort of stuff.

To make the magic happen, save the above file (or your own variation) as ~/Library/Preferences/com.apple.DownloadAssessment.plist. Then log out of and back into your account. Finito.

So if you’d like to get your Mac to be less of a nag about opening downloaded files, there’s how. As the links above show, I’m standing on the shoulders of giants here, so my thanks to those who paved the way. I hope that you will be able to benefit from both their work and my small additions thereto.

Update [13 Mar 09]: Potentially very bad news, folks. I just tried this on my 10.5.6 machine and it failed utterly. As did the Folder Action approach. Older versions of Leopard apparently didn’t have this problem. Anyone else seeing the same kind of thing on their machines? If either way is still working for you under 10.5.6, can you tell us which one it is in the comments? Thanks.

Update [18 Mar 09]: Great news, folks. Ben Millett kindly sent me a copy of his working-under-10.5.6 file and I tried it out, and it worked! The difference seems to be that the version I was using was encoded as “Unicode™ (UTF-8, no BOM)” whereas the encoding of the file Ben sent me is “Western (Mac OS Roman)” (both according to BBEdit). So if your copy doesn’t work, check the file encoding. Next I’m going to experiment with adding file extensions, and will report back if I meet with success.

My few thoughts on the “Graphical Effects” part of the feedback document. A lot of what was mentioned by the community is already in the pipeline, so there’s not a lot to say about those except “hurry ’em up, willya?”.

Gradients — like rounded corners, no surprise these came up. (All we need is to define wet-floor-reflect and we’ll complete the Web 2.0 design tricks hat trick.) I’d like to see them myself, and I don’t think defining them is quite as hard as the commentary implies:

Imagine, for example, applying a gradient to the text of a <span> broken across two lines. Do you apply the gradient to each part individually? Glue them together as if they were all on one line first? Draw a rectangle around both parts and apply the gradient to that? (CSS3 Backgrounds and Borders has a control for this.)

I’d say the answer is right there, in the form of background-break, but let’s assume for a moment that said property never existed and we still had to deal with this problem. I can think of two solutions:

Only allow gradients to be applied to non-inline boxes. This would not be my preference, but it could be so defined. There’s already precedence with CSS for that sort of limitation: width, height, text-align, and other properties are restricted to non-inline boxes.

Treat gradients the way backgrounds and borders are already treated on inline boxes. I’d be much more in favor of this. In other words, lay out the inline box as though it is all on one line and then break it in pieces as needed to fit into the actual text flow. (This is the behavior of continuous, the default value of background-break.)

But since background-break exists, you just treat gradients as you would any other background in accordance with background-break‘s definitions.

The somewhat trickier problem is how to define the value syntax for background-gradient so that’s both powerful and extensible without being unusable. I think that’s solvable, but not easily, and probably not in a way that will satisfy everyone.

(Though this would be a fabulous place for the cardinal-point values from pre-CSS1 days, which you can still find in the specification if you look hard enough, to make a roaring comeback, wouldn’t it?)

Unidirectional background repeats — I say yes. Here, have some values: repeat-up, repeat-right, repeat-down, and repeat-left. In each case, the image would be repeated in the indicated direction from the origin image (the one placed by background-position). Ironically, really old versions of IE did half of this by not correctly supporting repeat-x and repeat-y, treating them instead as if they were repeat-right and repeat-down.

There are occasions where this would be very useful, especially if you can combine the values into something like repeat-down repeat-right, and most especially in conjunction with multiple backgrounds. So you could put an image stripe across the top of the element background, another one down the left side, and then fill in the rest of the background with a repeat-down repeat-right image. Not a particularly common case, but the only way to handle it at present is with multiple nested elements, each with its own background and possibly a lot of negative margin trickery, and nobody wants that. (Which may also be why it isn’t a particularly common case.)

You could also put an image in the center of your page and then a single stripe that goes only downward from behind it. Like a golf ball on a tee, say; or a tree trunk below the leafy crowm; or a stem from a flower.

Slanted corners — sure, why not? The issues are all the same as with rounded corners; the only difference is that you have a flat corner instead of a rounded one. It makes joins between different borders styles/colors more obvious, but that’s a good thing: any solution that works well for the slant corner should work as well for the rounded corner. Besides, if we’re already going to the effort of rounding corners, this seems like a pretty easy add-on.

Multiple borders — I think this would be quite useful. I occasionally fake this with a border and an outline (as in my diagnostic styles) but that only works for two; if you want three or more nested borders (or two or more in IE/Win) you have to start nesting elements. Also, having multiple borders lets you define your own gradient borders like you were a pixel artist, and who doesn’t like pixel artists?

At the same time, though, I do feel that this should be fairly low on the implementation totem pole. And, as pointed out in the document, if image borders get implemented then a lot of the need for multiple borders goes away.

Alpha channel image masks — the problem I have here is what happens if you, say, try to use an image to alpha-mask a non-replaced element? How does it scale? Or does it? Will there be a mask-stretch property? Who really wants to stretch an image over a great big div anyway? (From a visual-results point of view, I mean.)

Allowing masks might help in figuring out how to do non-rectangular float areas, in that you could use the alpha image to define the area used for float exclusion. Combine that with a stretch ability and SVG support, so you can draw scalable vector masks, and I think you’re really getting somewhere. (As does Matt Wilcox; he and I have been chewing this over in the comments on the previous post in the series.)

When I was in Boston earlier this month, one of the people I’d thought to hang out with was Jared Spool, and of course he was on the other side of the country while I was in his hometown. This was a bit of a downer but I figured, hey, we both speak a lot, so I’d see him again somewhere at some point.

And how right I was: the week after my return home, Dopplr informed me that he and I would both be in London for the first weekend in March. I’m there for the Carson Workshop I’m giving (and there are only a few seats left, so you should grab one while they’re still open) and he’ll be in town for reasons of his own. As will Dana Chisnell, it turns out.

How could we not act on this? So I pinged the folks at Carsonified and asked them if they knew of a venue where we could arrange some kind of meetup. They were not only glad to help out, they offered to organize the whole thing. The result: a Web Geek Gathering at the Pitcher & Piano Trafalgar on Sunday, 8 March 2009. Jared, Dana, and I are all planning to be there. You should plan to be there too. You should also RSVP because, unlike the web, there isn’t infinite available space. Not to mention I’ve heard rumors that there might be some manner of free drinks. I mean, I’m just sayin’ what I heard.