Kenneth Auchenberg

I make stuff happen in the browser you didn't think was possible.

Word wrapping/hyphenation using CSS

| Comments

A few days back I spent most of my afternoon looking into how I could achieve proper word wrapping within elements with a dynamic width.

At Podio, we have a fluid layout, with a dynamic width, to deliver a responsive user experience. This means no element is having a fixed width, instead width’s are defined as percentages. This causes some headaches, now and then. Word wrapping caused a major one.

Initially I thought: It’s a no-brainer, just add word-wrap: break-word to the element, and it should do the wrapping.

It’s not.

When you have an element with a dynamic width word-wrap: break-word, isn’t having any effect. Today’s browsers don’t use the calculated width to enforce the wrapping. Instead they seem to ignore the declaration.

Wonders of a dynamic width.

In this example I used a generic layout for a two column layout, using table-cell and floats.

As you can see in this example, the long word isn’t wrapped into multiple lines, it breaks the layout. So how do we make it look more like this?

So what are the options?

In my research I found a lot of proposals on how to fix this issue. Most of them was a suggestion to add a fixed width to the element. Sometimes you need the dynamic width, like when you use the media-block from OOCSS, so what’s the alternative?

<WBR> and &#8203; tags

The past years I’ve been using <WBR> and &#8203; tags to insert optional line breaks into long paragrahs of text. This solution became quite made popular after Quirksmode, made documented it.

This technique is is widely used around the web, including places like Facebook. And there seem to be wbr-encode implementation for all major languages functions, but they all have one common problem. As soon you are outputting markup, and want to break up long words within tags it starts to get messy. To overcome this, it ends up in a lot of regex nightmare, and ultimately, a slow HTML parser, to ensure proper breaking.

This slows down rendering dramatically.

What about CSS?

Wouldn’t it be better, if the browser could do the work?

In my search for a working CSS declaration, I found word-wrap, which isnt working with a dynamic width, so I continued and found a new CSS3 declaration word-break, which is described as: “This property specifies line break opportunities within words.”

Great, so let’s try it out in a WebKIt-based browser:

Bamn, we got it. word-break: break-all; is the way to go for WebKit..

But then I fired up IE8 and Firefox, and realized that it didn’t work, so I continued my search…

It seems like the word-break declaration is prefixed in Internet Explorer 8 standards mode, so you need to add a prefix:

 -ms-word-break: break-all;
     word-break: break-all;

But what about Firefox? The Mozilla guys has chosen not to implement word-break support into Gecko. Instead they focused on supporting something new and exciting, the CSS3 Hyphenation specification.

CSS3 Hyphenation

Hyphenation is the better word-break. It’s locale aware, and inserts the hyphen character at the correct place, when breaking the words.

The support of CSS3 Hyphenation has started in Firefox 6 for the english languages, and several other langugages was added in Firefox 8.

It’s already supported in WebKit, currently prefixed, which means Safari 5.1+ and iOS 4.2.

CSS3 Hyphenation isn’t supported in Chrome, since Chrome doesn’t ship with any hypenation dictionaries, but since Chrome supports word-break: break-all; we are good.

To support hyphenation in Safari, Firefox (and future Chrome versions), you will need to do:

-webkit-hyphens: auto;
   -moz-hyphens: auto;
        hyphens: auto;

Webkit and mystic “word-break: break-word”

When using the word-break: break-all; property, is has the sideeffect, that words are being broken up at weird positions, because the break-all, means all words needs to be broken up.

An example of this looks like this:

To fix this, I discovered, that you can use word-break: break-word; which seems to be an undocumented and non-standard property value in WebKit. This makes the word wrapping behave like word-wrap: break-word, but works with dynamic widths.

As you can see in the above example, the word wrapping looks much better using word-break: break-word;. This leaves us behind with IE, which still would wrap the words at weird positions.

Luckely CSS Hyphenation is supported in IE10.

The solution

So the cross browser solution for doing word wrapping using CSS only is a combiation of word-break, word-break: break-word; and hyphens:

 -ms-word-break: break-all;
     word-break: break-all;

     // Non standard for webkit
     word-break: break-word;

-webkit-hyphens: auto;
   -moz-hyphens: auto;
        hyphens: auto;

This is working in Internet Explorer 8+, Firefox 6+, iOS 4.2, Safari 5.1+ and Chrome 13+.

The end result is simpler markup, and faster rendering, since we don’t need encode our strings with <WBR> and &#8203;.

Goodbye <WBR>, I don’t need you anymore.

Updates

I updated the article to include a section about word-break: break-word in WebKit. Added proper references to word-break: break-all;, and highlighted that CSS3 Hyphenation isn’t supported in Chrome. Thanks goes to Mads Kristensen and Baldur Bjarnason

Slides from my HTML5 & browser extensions presentation at ProData Consult

| Comments

Thursday last week (27th january 2010) I hosted a “evening-event” at ProData Consult for their consultants, where I spoke about HTML5 & Browser extensions. My HTML5 talk was a short recap of the recent changes in the specification, the W3C logo, and a showcase of the semantic changes, new tags and attributes and the HTML5-related JavaScript API’s.

The presentation was a bit of an experiment, because I was the first time I coded my presentation in HTML, JavaScript and CSS instead of using the regular tools such as PowerPoint or Keynote.

To “code” my presentation I used a small sinatra-based ruby app called ShowOff, which is using markdown for its templating.

The advantage of coding my slides is really obvious in my presentation where I show how the new form controls is being rendered, how HTML5 validation works, theres even an embedded google maps, canvas demo, pushHistory etc.

Normally I embed the presentation into the blog-post, using an embedded SlideShare presentation that is using flash, which allows resizing. But because I this time hardcoded the layout in HTML/CSS, then I’m not able to embed a resized version of my slides.

To see my slides (which is hosted on Heroku), just click the thumbnail below:

Diving into photography.

| Comments

Lately I’ve been quite hooked on getting a DSLR, because I wanted to explore the world of photography from another angle than just looking at beautiful pictures.

To begin with I started looking at high-end camera’s (top-model or no-model mentality), but after a lot of research I ended up buying a Canon 550d, which is also known as T2I or KISS X4. It’s very similar to Canon 60D and Canon 7D, but the main difference is the physical body, which is in plastic and is lacking some quite nifty navigation buttons compared to 7D/60D.

So why did I buy the 550d?

Of couse, if I had unlimited resoruces I would had bough the Canon 7D, simply because it’s “just nicer”, but I came to the conclusion, that this is my first DSLR, and therefore I could live with the lack of weather sealed body, and the nifty navigation buttons, simply because I first need to learn the very basics of photography.

So I decided to go for the Canon 550d body, but which lens should I buy? Should I go for the kit?

After some more research in various places I came to the conclusion that my first lens should be a prime in about 50mm. But since my 550d has a smaller APS-C sensor, it also has a crop-factor of 1.6, which means a 50mm lens would become 85mm on the 550d.

Therefore I ended up buying a Canon EF 28mm 1/8 USM lens, which is going to be equal 45mm on the 550d, got 1/8 aperture, and is using the EF-mount, which means I also can be used on the Canon pro-cameras (if I should end there some day).

The lens was a bit expensive 450$, but got some pretty good reviews, and the sample photos I found in the 28mm group in Flickr is simply stunning.

In addition to the 550d and 28mm lens, I also bought a filter, lens hood and a battery grip, so totally I ended up with

  • Canon 550D body
  • Canon EF 28mm 1/8 USM lens
  • Canon Lens Hood EW-63 II
  • Phottix Battery Grip for 550d
  • Hoya 58mm Pro-1D UV Filter

I’m still waiting for the lens, battery grip and filter to arrive, so hopefully when all the parts has arrived I’m going to be thrilled about photography ;)

New version of CSS Reloader for Chrome is out

| Comments

It has been a long time since I did changes to my CSS Reloader browser extension. This evening I had some time, and pushed a updated version of CSS Reloader for Chrome out in the public.

The new version contains a revised code-base, which is way more well structured and cleaner, and I also added som new features:

  • Much requested options-page has been added - allows you to change the keyboard shortcut.
  • CSS Reloader got a nice new logo (credits goes to Everaldo Coelho for the lovely icon.)

Technically  I was quite fun to add the options-page, because the settings is persisted in LocalStorage, which is only available for the background-pages in  the extension, and not the content-script that is injected into every tab. To expose the settings for the content-script I have taken advantage of the message passing implementation in Chrome, that allows the extension-parts to communicate using events.

Get the updated version of CSS Reloader for Chrome, or check the source-code out, to see the funky-ness

Slides and code from my ANUG jQuery CodeCamp at Vertica

| Comments

This saturday I hosted a jQuery CodeCamp at Vertica in Århus, Denmark.  The code camp was arranged by ANUG, a local .NET user group in Århus, which is one of the most active .NET user groups in Denmark. It was really awesome to see that many people meetup on a saturday to do some jQuery hacking!

My intention with the CodeCamp was to give a brief introduction to jQuery, and do a presentation about all the things you can’t read about in the documentation. But since this was a CodeCamp I also had a mission for the attendees.

The mission was that all the attendees, by the end of the CodeCamp should had been building they own chat client, which connected to a chat-server I had build using socket.io and node.js.

I knew from the very beginning that the mission was quite ambious for a crowd that wasn’t used to do jQuery/JavaScript stuff, but we succeded! All the attendees managed to build a chat-client that connected to the server, and one even managed to implement a google-maps mashup that showed the location of each connected user!

Here’s the slides from the CodeCamp:

The source code for the chat-server can be found right here: http://github.com/auchenberg/jquery-codecamp

How to disable accidentally text-zooming in browsers when using Magic Trackpad/Mouse in OSX

| Comments

One thing has lately annoyed me, and it has been the accidentally text zooming in my browsers (Google Chrome, Firefox and Safari), when using the Trackpad, Magic Trackpad or Magic Mouse.

The text zooming happens because the pinch-gesture (zoom) has been enabled for the trackpad/mouse, which by default, is mapped to text-zooming in the browsers.

To disable the text-zooming I used a tool called MultiCluch, which is a input-filter that monitors all multi-touch-input and remaps the gestures to keyboard-combinations. So what I did was to map the zoom-in and zoom-out gestures in Google Chrome to a keyboard combination that is doing absolutely nothing.

Introducing Auto-Check-in

| Comments

The past few days I worked on a new mashup-project I wanted to realize since the day I started used Foursquare…

Let me introduce Auto-Check-In. It’s a new service that removes the hassle about remembering to check-in, since it’s doing to for you. Auto-Check-in does not require (yet) another app running in the background, since it’s using Google Latitude to get the your location (Google Latitude is build in into all Android devices, and with an iPhone you need to run one app in the background).

The service is asking for users location every 5min, and if the user has been at the same spot for the configured timespan, the system is asking foursquare for the near by venues and finally checking the user into the closest one.

For the technical interested, I’ve build the service in Python, and it’s running on Google App Engine, with a true async architecture, which takes advantage of the newly released Task Queues in App Engine.

I teamed up with my friend and colleague Morten Just, which had a lot ideas on how the service should work, and the same afternoon he had a user interface ready.

Auto-Check-In is currently running in a public alpha, and is having about 100 active users that each and every day is checking into a lot of venues, without they need to remember it.

Roadmap:

  • Ranking of near-by-venues, to select a more qualified venue than the closest one.
  • Black/white-listing.
  • Geofencing.
  • Add support for Gowalla, Yelp, Brightkite, etc.
  • Gather location from more sources than Google Latitude.

Let the new adventure begin…

| Comments

About a month ago I tweeted that I had made a LIFECHANGING DICISION.  I had accepted a position at Hoist, a startup located in Copenhagen.

Hoist is an online organisation and collaboration application for professionals and organisations. It’s the Facebook equivalent for the workplace, and it has enough functionality to compete with the best guys out there in the current market with its out of the box tools. But not only that, it has an in-built platform to simply create your own online ‘apps’ that cater to your individual business needs. Hoist recently won the MIT Global Best Startup award, and if you spend a few minutes playing around with it it’s quite easy to see why. At the moment it’s only for cool kids via invites, but very soon you are going to hear a lot more about Hoist.

At Hoist most of my time is going to be spent on web development, with a focus on HTML5, CSS and JavaScript, but I’m also going to have a look at the user experience around the web-product. It’s going to be damn exiting.

I’m looking forward to be a part of a new (quite impressive) team, with a vision that’s mind-blowing. I’m ready! Hoist-me-up!

Update: As my fellow colleague Morten Just kindly pointed out at Twitter today, the italic paragraphs is kindly borrowed from my upcoming colleague Pete Lacey’s blog post about his join to Hoist.

Slides from my Browser Extension session at Community Day 2010

| Comments

This week I had a session about Browser Extensions in Mozilla Firefox and Google Chrome at Community Day 2010 in Copenhagen. The event was a cross community primary arranged by Microsoft Denmark. The event had a lot of different sessions subjects with everything from Browser Extensions to Dependency Injection in C#

Here is the slides from my session:

If you attended the session, any feedback is appreciated! Please rate my session http://www.doodle.com/6yscng5fcut6gbyu, or write a comment to let me know how I did.

How to use desktop icons in Google Chrome - the HTML5 way.

| Comments

Today I wondered how Google Reader and Google Mail was having nice high resolution icons when I saved a application shortcut to them in Google Chrome (currently a windows only feature).

I searched a bit, but had trouble finding documentation on this functionality. Even the Google Chrome/Chromium developer pages didn’t contain anything. But after some more research, I discovered a small Webmaster FAQ for Google Chrome that contained a single example on how to add icons, application name, description and application urls.

The code example:

<!DOCTYPE HTML>
<html>
 <head>
  <title>Gmail</title>
    <meta name="application-name" content="Gmail"/>
    <meta name="description" content="Google's approach to email"/>
    <meta name="application-url" content="http://www.gmail.com"/>
    <link rel="icon" href=gmail_32x32.png sizes="32x32"/>
    <link rel="icon" href=gmail_48x48.png sizes="48x48"/>
 </head>
 <body>

When I saw this code example the first thing that hit my mind was “This code is invalid!”.

Take a look at the sizes-attribute. This attribute isn’t a part of any final HTML specification, but then I had a look at the HTML5-specification, and it seems to be that Google Chrome is following the HTML5-specification for external icon resources (an obvious choice!).

The HTML5 specification 4.12.3.7 Link type “icon”,  defines as following:

The specified resource is an icon representing the page or site, and should be used by the user agent when representing the page in the user interface.

You might wonder what the correct values of sizes-attribute could be, and luckyly the HTML5-specification tells a bit more about the sizes-attribute.

If specified, the attribute must have a value that is an unordered set of unique space-separated tokens. The values must all be either any or a value that consists of two valid non-negative integers that do not have a leading U+0030 DIGIT ZERO (0) character and that are separated by a single U+0078 LATIN SMALL LETTER X character (x)

This means if you have two options for defining a size of an icon. You could either use “any” that represents that a resource which contains a scalable icon, or you could use a size in this pattern “[width]x[height]” with non negative integers that represents the icon size in pixels.

You are able to define multiple resource links for icons in various sizes.   Take a look at this example from the HTML5 specification:

<!DOCTYPE HTML>
<html>
 <head>
  <title>lsForums — Inbox</title>
  <link rel=icon href=favicon.png sizes="16x16" type="image/png">
  <link rel=icon href=windows.ico sizes="32x32 48x48" type="image/vnd.microsoft.icon">
  <link rel=icon href=mac.icns sizes="128x128 512x512 8192x8192 32768x32768">
  <link rel=icon href=iphone.png sizes="59x60" type="image/png">
  <link rel=icon href=gnome.svg sizes="any" type="image/svg+xml">
 </head>
 <body>

As you can see this page would support a broad range of icon sizes form the commonly known favicon to a scalable svg icon.

We can only hope that future browsers, and existing ones (Safari Mobile on iPhone, currently having it’s own resource type) will start supporting this specification, since it would save us, web developers, a bit of work.