Archive for the ‘code’ Category

The Rounded Corners of Tomorrow… Today!

Thursday, October 2nd, 2008

Hey, you know what can be a real pain in the tail? CSS rounded cor­ners. Of course there are battle-tested, work­horse solu­tions out there, like slid­ing doors, or a hand­ful of Javascript-based alter­na­tives. But rounded cor­ners are such a com­mon ele­ment of web design and seem like a nat­ural exten­sion of the designer’s exist­ing toolkit that it only makes sense that there should be a way to imple­ment them with pure CSS. The good news is that border-radius is indeed com­ing in CSS3. The bet­ter news is that you can start using it today, as long as you’re only tar­get­ing Gecko & Webkit. Before we get to that though, let’s look at the way it’s sup­posed to work accord­ing to the spec.

As you might expect, the border-radius prop­erty is used a lot like border. That is, you can spec­ify one value for each cor­ner (border-radius: 10px;), one value per cor­ner (border-radius: 1px 2px 3px 4px;), or val­ues for oppo­site cor­ners (border-radius: 5px 10px). It actu­ally gets more com­pli­cated, since in addi­tion to describ­ing cor­ners with one radius (i.e. those with semi-circular curves), you can make ellip­ti­cally rounded cor­ners by nam­ing two radii. For more detail on this, take a look at the draft spec. Lastly, you can use a prop­erty for each cor­ner, border-top-left-radius: 2em;, etc. So, assum­ing there aren’t any major changes in the spec, expect this to be what gets imple­mented as part of CSS3, and what you’ll ulti­mately using in your code.

But what about now? Here? Today? It hap­pens that two of the standards-aware, forward-thinking ren­der­ing engines have devel­oped pro­pri­etary exten­sions to CSS that should stand in for border-radius until cer­tain ambi­gu­i­ties in the spec can be resolved, and the prop­erty is implented accord­ing to the stan­dard. So if you want to use border-radius in your code today, you’ll have to use both the Mozilla– and Webkit-specific CSS prop­er­ties. For­tu­nately, both of the pro­pri­etary exten­sions work in the cur­rent major releases of their respec­tive browsers.

If you’re mak­ing a box with four cor­ners of the same radius, the syn­tax is the same in Mozilla and Webkit:

-moz-border-radius: 10px; /* 4 corners of radius = 4px*/
-webkit-border-radius: 10px; /* Same as Mozilla */

To spec­ify dif­fer­ent radii for each cor­ner, things diverge somewhat.

/* Mozilla: */
-moz-border-radius: 1px 2px 3px 4px;
/* Webkit:
    (The four declarations below amount to the
    same thing as the single rule above) */
-webkit-border-top-left-radius: 1px;
-webkit-border-top-right-radius: 2px;
-webkit-border-bottom-right-radius: 3px;
-webkit-border-bottom-left-radius: 4px;

And that’s the guts of it. So to make a tabbed nav­i­ga­tion list, you would use a dec­la­ra­tion along the lines of the fol­low­ing (and see the below code in action.):

li {
  border: 1px solid #587402;
  border-bottom: none;
  border-radius: 0 10px 0 10px;
  -moz-border-radius: 10px 10px 0 0;
  -webkit-border-top-left-radius: 10px;
  -webkit-border-top-right-radius: 10px;
  list-style-type: none;
  float: left;
  padding: .5em 1em 0 1em;
}

There you have it. But there are just a cou­ple of other things I want to point out. If the con­tainer you’re round­ing the cor­ners of has only text con­tent and a back­ground in it, the back­ground will clip to the rounded cor­ners. And indeed, accord­ing to the spec, any the con­tents of a block-level ele­ment on which a border-radius is set should clip do the same as long as you set overflow: hidden on those con­tents. How­ever, the imple­men­ta­tions just aren’t there yet. Instead, with any­thing over and above plain HTML text (for instance, an img or iframe) inside such a con­tainer, the square cor­ners will peek out­side of the rounded con­tainer. (Exam­ple)

One solu­tion would be to make the bor­der thick enough that the cor­ners of the inner ele­ment can’t poke through the outer bor­der (like so). Though inel­e­gant, this will work just fine if you don’t need every­thing to round nicely. And this method should suf­fice for what­ever kind of con­tent you’re try­ing to stuff into your nicely rounded box.

How­ever, if it’s an image you’re putting in the box and you need the inner cor­ners to be rounded as well as the outer cor­ners, then the only answer (for now) is to set the image as a back­ground. Still, if the lan­guage of the spec is any indi­ca­tion, it won’t always be this way.

For the poor soul who is try­ing to squeeze iframe con­tent into a rounded cor­ner box, you’re essen­tially out of luck at the moment. You can cer­tainly use the thick bor­der method I described above, but short of that, you’ll have to look to the bleed­ing edge. That is to say, you’ll need some­thing which isn’t yet in any production-quality browser, but that is cur­rently in the Webkit nightlies. I speak of the arcane meth­ods of -webkit-mask-image. This prop­erty can take a png or an svg as its url, and pretty much any­thing you apply it to will play nice and clip to the shape of the image. See for your­self. Still, this last bit is obvi­ously not any­thing any­body will be using in pro­duc­tion code for some time to come.

After read­ing all of this, if noth­ing else, I do hope that you’ve come away with a bet­ter idea of some of the great things that the CSS work­ing group has in store for you, the devel­oper. But even moreso, hope­fully there’s some­thing in all of this mess that you’ll be able to put to use today.

What I’m Reading: 3/24

Monday, March 24th, 2008
  1. Nine Tech­niques for CSS Image Replace­ment: If you spend any time at all play­ing with CSS, you know that there are a full bajil­lion tech­niques for replac­ing text with an image. It’s a lot to remem­ber, and I’ll fess up that I tend to use what­ever one I hap­pened to have read about most recently rather than tak­ing a con­sid­ered approach to which of them might be the best solu­tion for a given sit­u­a­tion. No more! The above-linked post does a great job of run­ning through the pros and cons of the 9 (9!) major tech­niques, and from now on you (mean­ing “I”) no longer have any excuse to not use the best, seman­tic, most acces­si­ble one at every opportunity.
  2. Drugs, Bugs, and IE8: A pre­dictably good read from Eric Meyer, but I link to it mainly to have an excuse to echo the fol­low­ing point: There are a lot of beta browsers out there right now (one less, now that Safari 3 has shipped). If you’re test­ing your sites in them and some­thing ren­ders in any way other than what you were expect­ing, sub­mit a bug report. Don’t change your code.
  3. Opti­miz­ing Page Load­ing in the Web Browser: For the browser builders, net­work latency is at least as big a prob­lem as con­nec­tion speed.
  4. A Japan­ese RPG Primer: The Essen­tial 20: Last week, Gama­su­tra pub­lished this list of the best of the best in Japan­ese RPGs through­out the ages. It’s a top-20, so it’s not exhaus­tive, but it’s sure as hell exhausting–i’ve been chip­ping away at this beastie since last week. Any­way, if you’re at all into JRPGs, it’s a really fun read. It’s also neat to see some old favorites put into con­text along­side some sem­i­nal games that you may never have been exposed to.

Front-end Development Link Roundup

Sunday, January 20th, 2008

Here are just a few arti­cles that have come out in the last cou­ple of weeks that might be inter­est­ing and/or use­ful to some folks.

  1. What CSS Did We Learn in 2007
    SEO site Search-This lists the CSS tech­niques they cov­ered through­out last year. It’s a lot of use­ful, basic, meat-and-potatoes stuff.
  2. 101 CSS Tech­niques Of All Time– Part 1
    Noupe begins a multi-part list of what they find to be the most use­ful CSS tech­niques. Again, a lot of great basic stuff for those who may be new to CSS, but it should also be pretty handy as a ref­er­ence for the griz­zled vets out there.
  3. Acid 3 Tack­les ECMAScript
    Resig lays out exactly what Acid 3 is test­ing. Very inter­est­ing, and some nice insight into some edge cases in Javascript
  4. Thoughts on Fire­fox 3.0
    Nice overview of some of the changes in Fire­fox 3. He men­tions some improve­ments to the DOM imple­men­ta­tion (and links to Mozilla’s more exhaus­tive list).
  5. Reset­ting Again
    Eric Meyer once again pushes the state-of-the-art in CSS resets.
  6. IE6CSS Bugs and Fixes Explained
    Another nice ref­er­ence post. Dave Woods looks at a rogues gallery of cross-browser ren­der­ing issues.

That’s it for now. Hope­fully some­one will find some­thing use­ful in here.

Stupid Ruby Problem

Wednesday, January 9th, 2008

Like I said, I’m work­ing on get­ting my Ruby chops up to snuff. I thought it might be fun to do that by port­ing all of the code in Joseph Adler’s fan­tas­tic Base­ball Hacks from Perl to Ruby.

I’m com­ing back to this project after let­ting it go for a while, and sure enough, the prob­lem I was hav­ing when I put it down is still vex­ing me.

One script is intended to grab all of the play-by-play data from retrosheet.org. The files all have urls like this:


http://www.retrosheet.org/1957/1957al.zip

http://www.retrosheet.org/1957/1957nl.zip

http://www.retrosheet.org/1957/1957ml.zip

The snip­pet below is a sim­pli­fied ver­sion of the code I’m using to build the urls. It’s intended to print the urls of each zip file for each league from 1957 to 2006:

year = 1957
leagues = ['al', 'nl', 'ml']leagues.each do |league|
  while year <= 2006
    url = "http://www.retrosheet.org/#{year}/#{year}#{league}.zip"
    puts url
    year += 1
  end
end

How­ever, it doesn’t do that. It only gen­er­ates the urls for the AL files, and I can’t get my brain around why.

I’ll be sure to add the solu­tion when I fig­ure it out, but for now I wanted to just doc­u­ment some of the strug­gles of a Ruby n00b.