September 2008 in the Life of Ben (Blog)
Mobile Web Bugs (29th September 2008)
Today I tested how Calthorpe Park School fares in mobile phones. We recently did a redesign (actually more of a realign) and that included a complete rewrite of the handheld stylesheet.
Handheld Simulation
In Firefox with the Website Developer Extension, you can simulate what a handheld device should do with your CSS. From the extension’s toolbar:
- CSS
- Display CSS by Media Type
- Handheld
This applies any stylesheets using media="handheld"
or @media
method for handheld
devices and disables all others. Rather than resizing your browser to a tiny width and reducing the text, you can add this temporary CSS:
html {
background: #808080 !important;
}
body {
max-width: 240px;
color: #fff;
font-size: 10px !important;
background: #fff;
}
This only uses 240 pixels of the viewport, making the rest of the viewport a dark grey. Should look quite familiar if you use Windows XP. It also sets a fairly typical small-screen text size and ensures normal colours.
Exactly how you add this is up to you. If you include it in your handheld
stylesheet, make sure you remove it before uploading to your actual website. If you don’t, you could be screwing over dutiful handheld devices which differ in width, resolution, user preferences and so on.
Opera also has a Small Screen Rendering (SSR) which is also fine for testing what handheld devices should do. But I’m quite fond of Firefox and the Web Developer Extension.
Handheld Testing
Nokia E90 Communicator
My Dad’s phone, in which the styles were pretty messed up. The wide inner screen has 1,024 pixels of width, so it applies the screen
stylesheet.
The complex positioning for <fieldset>
and <legend>
in the header seem to have been half-applied. So I guess this is a CSS implementation bug.
Sharp GX15
My phone uses Openwave from quite some time ago. I applies the handheld
stylesheet and ignores all the others. It has a normal size screen for a mobile phone from a few ago, so this is good. It applies colours, text formatting and some of the margin
settings.
However, it doesn’t apply display: inline
to the navigation lists and gives them a massive indent. This makes the navigation hard to use. The sublist of items is almost unusable as only a few characters fit on each line. It breaks words so all the text remains visible, albeit difficult to read.
Worse still, it doesn’t apply display: none
to the <legend>
, slogan and “You are here” portion of the breadcrumb trail. The skip links only work once the whole page has loaded. But at least the “Skip to Main Content” link is automatically focussed on each page load.
Thoughts
Mobile browsing of standards-compliant websites with lightweight markup and styles optimised for various media can be great experience. But it relies on the device supporting the standards.
These two devices represent two different generations of mobile browsing. Each of them does a fine job with the resources they have but a couple of CSS bugs detract from their usability.
Better standards compliance in handheld browsers, please.
Hengistbry Head (28th September 2008)
Mum, Dad, Zoe and I spent just about the whole day:
- strolling around the beach;
- riding vintage diesel-power boats;
- riding in a similarly quaint road train;
- strolled, jogged and joked along around on the beach;
- successfully skimmed stones a short distance across the English Channel;
- ate seaside food and refreshments;
- took in the sea air;
- and got baked without burning under bright sunshine.
The journey down there is quite long. Dad’s recently purchased Ford Ranger has the Wildtrack trim level with an after-market load box. The long journey was entirely bearable in the back. More legspace than his previous truck, the Nissan Navara. But you do need a rolled-up towel to soften the door armrests, which have very hard plastic on the handle part.
Zoe’s life has been pretty dramatic recently and mine has been pretty boring. I think everyone enjoyed having a day out.
Haircut 5 (26th September 2008)
Had my hair cut today. Same place as before. This time the conversation was more positive. My hairdresser had visited the area of France where W3C TPAC 2008 will be held.
2-part Cycle (26th September 2008)
After reaching the Pondtail passage I veered off to the right and explored a fire alley.
Damp Track with Post
Can’t remember quite where it led now but there was a damp track with a post in the middle that I followed from it. This led to a clearing.
Spider Web
Another fire alley was on the right. Some way down it I could see the first threads of a very ambitious spider’s web glinting in the sunlight, which was bright but not glaring. I continued along the track a bit further and noticed the left looked out across the prehistoric landscape which the Pondtail passage circumnavigates.
New Path
Amongst the trees on the right I noticed a narrow path which I hadn’t ridden before. I like to go exploring along new routes from time to time, so I trundled in to see where it went.
After a while it forked, with the left leading back to the clearing and the right being blocked by a small, fallen Silver Birch trunk. After deliberating for a while I decided to continue exploring by going right.
The track was very narrow and clearly not used very often. It may even have been an animal track but it was worn smooth and clear, more like a little-used human path. After many turns and kinks it exited onto a grassed-over track which was also new to me.
Grassy Track
Not sure why but I turned left and this led up a hill, with trees either side. Near the top it opened into the prehistoric clearing. A little further on it joined into a track I recognised. Turning right would take me to a cattle grid on the path which trackes the boundary between Fleet and this forest.
A keen mountain cyclist whizzed past me, heading down the hill. For a moment I wondered whether to ask if I could ride with him. But he was gone before I could get the words out of my mouth. From the pace he was maintaining, I imagine he took cycling a bit too seriously anyway. All the same, I decided to follow his route in case there were interesting areas to the right of where I joined the grassy track.
After passing the exit of the new path, the grassy track forked in two. The route on the left look kind of soggy and lame. I chose to go right as I could also see this led to the clearing. I didn’t want to risk getting lost or getting blocked by a flooded area.
Across the Clearing
Seeing the keen cyclist in the distance, I decided to sprint across the clearing. A closely cropped area of grass ran the whole width of the clearing, which I hadn’t noticed before. By the time I reached the far side the keen cyclist was long gone. But at least I’d found some new routes.
While crossing Basingstoke Canal (using the small, old bridge near Pondtail) I decided to follow the towpath towards Pyestock. So I swooped down and nearly ran over an unsuspecting woman! Good thing I changed my brakes and got them adjusted. I needed all the performance they could offer to stop in time.
This stretch of canal is in the open and had sunshine on it all day, so it was pretty hot. The overflow was leaking and the canal’s water level had visibly dropped several inches.
Big Hill
Managed to get all the way up the big hill that rises from the towpath to the level of the main road. In fact, it seems to exceed that level by quite some way, making it even more daunting.
My gearchange from Medium to Low was rather botched and I lost a lot of speed. But I’d gotten so far up the hill it was level enough to change. But Low 3 was still too high and I had to crunch down to 1 quite brutally.
Pit Stop
While riding gently along a smooth, soft track I heart a very faint but constant and extremely high-pitched squeak. It was coming from behind and to my right, so I guessed that the chain had dried out. I think this was near Pyestock
My last ride ended with fording the stream, then a ride along some main roads. The water probably combined with dust and fine dirt from the road to absorb the oil off the bearings.
When I got home, dad’s truck was blocking the driveway. I went inside and he was just leaving, so I didn’t have to wait long before I could get past. Was going to oil the bike up on the top patio but the sun was actually quite hot, since it’s South-facing.
The paved area in front of dad’s home workshop, which was shaded by the tall trees. For some reason, oiling the wheel bearings seemed incredibly awkward. Maybe I’ve gotten so used to standing the bike upside down with the seat and handlebars protected against scrapes by a couple of rags.
Holding the bike over at an angle when giving each bearing a brief squirt of oil definitely helps the lubricant penetrate more deeply. I could hear the dust clumping up and being pushed away by the bearings.
Immediate Effect
Riding slowly back up the garden path, the difference was instantly noticable. It was like riding a different machine! Suspecting this may just be a placebo effect, I held off my internal celebrations until I’d covered some more mileage.
Straight to Pondtail
This time I didn’t explore. The oiling seemed to be wonderfully smooth, so I just kept going. Used the roads to cut out the towpath, as I was probably even hotter by now. Also, that big hill is really tough!
Peyestock Track
Did the wiggly embankment track that runs along the perimeter of Pyestock. I took a right where the track forks which takes you past a big hole. The track eventually drops down sharply then rises up, into the fire alley between the woods and the Pyestock fence.
A woman was walking two black dogs. She didn’t react immediately when I said “Excuse me” and seemed surprised when she eventually looked around. The breed of dog seemed too decorative to be assistants.
No Ford
Rejoining the gravel track took me to the ford. Having only just gotten the bike properly oiled, I took the bridge.
By this time I was totally convinced the oil had transformed the riding experience. The thing just loved to freewheel and pedalling was easy as pie. Plus, the squeaking had gone.
Pondtail to Airport
Returning to along the outskirts of Pondtail, I followed the track all the way back to the canal. Instead of going up the big hill I went under the double bridge, looking for the route up my parents had taken last time. This turned out to be more like a climbing trail than a path, so I rode on further.
Eventually found a route with some steps made out of tree trunks. Seemed impossible to cycle up and difficult to walk the bicycle. But I made it, joining into a car park. I crossed the roads and was back in the woodland. I took the left of the 3 routes instead of the central one we’d taken as a family.
Airplane!
The route turns right to stay inside a main road. But there was a grassy knoll out the outside of the turn with a faint track through it. I took this and it led to a tricky and obviously not human-made track down and across a steep slope. The slope fell towards the main road, so good control was very important.
It joined back into the gravel track and I found the crossing point for the road. Went across and took a more direct route to the airport view. Thought I had blogged about this view before but I can’t find it.
Anyway, it seemed like some commercial pilots were practicising their landings and takeoffs. A couple of other planes landed. One was sat on the taxiway for ages whilst other planes circulated.
After a while, a posh helicopter came in to land. It came in from the left and made a short, curved approach to follow the runway. Then it reduced altitide and actually landed on the runway in the spot planes to! It taxied along and turned off just like a plane did. Is this what normally happens when a helicopter with wheels wants to land at a location with a runway but no helipad?
Homeward Bound
Must have watched planes for half an hour or so. This part of England has a lot of trees, so being on a hill gives you a rare Big Sky Country feeling. In particular, you suddenly notice how distinctly hemispherical the sky is. The sky was blue with just a hint of white clouds starting to form in a few spots.
After soaking it up, I went back home. I had been out for a couple of hours. It’s a bit lame without company but still relaxes, energises and enthralls me.
Opera’s Website (26th September 2008)
(In belated reply to Opera’s Web Standards Curriculum from Accessify Forum.)
(Update 2013-07-04: Opera has donated the project to the W3C Web Platform Docs initiative so nearly everything below is now obsolete. Opera have not created redirects, instead choosing to break the old shortcuts and retain the original articles.)
Putting the TOC on the start page definitely helps! Thanks for getting that done. It’s easier to criticise than to create but the following makes some suggestions to improve the things I’ve noticed more recently.
List Marker Indention
The number for each double-digit list item pokes outside the left edge of the content. From Opera 9.5:
Usually, list markers are indented rather than outdented. In IE7, outdented markers get clipped:
IE6 renders the page in Quirks Mode (BackCompat
) and the markers are greatly indented:
Tracing the Styles
There is much confusion between the various CSS files. In my experience of doing cross-browser compatibility professionally, this is inevitable on every site that has multiple stylesheets for the same media. Using Firefox 2.0.0.17 with the DOM Inspector, it’s time for a tale of mystery and intrigue as we delve into the murky underworld of Opera’s website styling…
To begin, margin
and padding
is zeroed on <ol>
and <li>
at the start of template.css
:
ul, li, ol, dd, dt, dl {
margin: 0 0 0 0; padding: 0;
}
Line 106 of screen.css
sets a margin-left
on <ol>
:
ul, ol {
margin-left:20px;
}
Line 184 of screen.css
then zeroes margin
and padding
from <ol>
and <li>
for a 2nd time:
ol, ul, li {
font-size:12px;
padding:0;
margin: 0;
}
This undoes the indention line 106 had dutifully set.
Line 195 of screen.css
adds vertical margin
to <ol>
and zeroes the horizontal margin
:
p, ul, ol {
line-height:1.4em;
margin:1em 0;
}
(Watch out for that if you try rationalising the CSS.)
A little before it, on line 190, <li>
is given a margin-left
:
li {
margin:0.1em 0 0 20px;
list-style-position:outside;
}
This is equal to that which was set on <ol>
at line 106…before it was zeroed. Twice.
The saga continues as download.css
swoops in from nowhere and zeros all margin
and padding
from <li>
once again! Here, at line 265:
#thanks ol, li {
margin: 0; padding: 0;
}
I’m guessing this was an accident caused by using li
instead of #thanks li
?
Anyway, there’s one last twist in the tale: Web Standards Curriculum screen.css
arrives in the nick of time to make a desperate last stand. It heroically re-applies some indention just before its EOF:
#wsc_content li {margin-left:20px;}
Tragically it’s too little, too late: 20px
just isn’t enough for double-digit list markers. Maybe it should be done with em
so the indention increases (or decreases) with text size?
I’m not sure what’s happening in IE6 but I bet it’s an even crazier story!
Bogus XML
The markup for that page starts with this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
The pages are sent as text/html
so they can’t be processed as XML. As such, an XML prolog is wrong. Having something before the doctype is what puts IE6 into Quirks Mode. Finally, it’s only using the Transitional level of conformance.
Article 14 discusses these points, including this:
The presentational markup that isn’t allowed shouldn’t really be there anyway, since you should use HTML to define the structure and meaning of your documents, and CSS to determine how they are presented. Using a strict doctype will help you with that, since the validator will alert you of any presentational elements or attributes that have sneaked its way into your code.
Roger Johansson, et al.
(Sneaked their way, surely, as that sentance is in plural?)
Something along these lines has already been reported. Yet every part part I’ve checked of Opera’s website starts with the same bogus XML and a Transitional doctype.
I agree with using <ol start>
for the TOC, btw. But even that page should be Strict to help check for other things creeping in. As well as setting a good example by following your own curriculum.
We’re on the Scroll to Nowhere…
Not sure if Quirks Mode is the culprit, but the border between the columns is placed beneath the right-hand edge of the right-hand column in IE6:
That picture also shows how IE6 gets a horizontal scrollbar, which is shared by IE7:
Neither IE6 nor IE7 have a horizontal scrollbar on the Opera’s homepage:
Navigation Wrap
The main navigation wraps to a new line in IE7:
It’s correct in IE6:
The problem does not occur on Opera’s homepage:
I take it there’s no cross-browser testing for the curriculum?
Jarring Incremental Rendering
On the homepage of the Curriculum, there’s a very big image. The markup for it is this:
<img src="/education/images/header_wsc.jpg" alt="Opera Web Standards Curriculum" />
When arriving at the page without that image in the cache, the “Learn to build a better Web with Opera” subheading is just after the “Opera Web Standards Curriculum” main heading. But when the image starts to load, the headings jump apart from each other unexpectedly while the big image fills that space.
Setting the width
and height
on the <img>
would reserve the space. This keeps the headings apart even before the image has loaded, so there’s no “jump” while the page loads:
<img width="780" height="330" src="/education/images/header_wsc.jpg" alt="">
Some other <img>
elements on the page already have this, presumably in the templates. I also removed some XML fluff since this is a text/html
resource.
alt
Text
Incidentally, that big image doesn’t include the text “Opera Web Curriculum”. So why was that in the alt
? It shows a Google Search results page and some scribbled notes…which I must concede are far neater than my own scribbled notes! But that imagery seems unimportant to learning about web standards, so I think alt=""
works best here.
Heading Elements Missing
In the Making Opera Work for You section, the subsections are marked up as a single paragraph:
<p><strong>For educators</strong><br>
Pass on Web Standards and good development practices to the next generation of Web developers. Opera’s <a href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur/">Web Standards Curriculum</a> deconstructs Web Standards into modules you can teach either in order or as part of your own lesson plans.</p>
This is a subheading followed by a paragraph. The markup should be this:
<h4>For educators</h4>
<p>Pass on Web Standards and good development practices to the next generation of Web developers. Opera’s <a href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur/">Web Standards Curriculum</a> deconstructs Web Standards into modules you can teach either in order or as part of your own lesson plans.</p>
The same mistake is present in the sections below the 2 columns, after <div style="clear: both;"></div>
. Those could be <h3>
or <h4>
, depending on how significant the visual end of the right-hand column is.
Text Size Differs
Between the TOC and the actual articles.
WSC IA
The articles are in a whole different area to the Curriculum’s homepage! This means the URLs are not “hackable” and don’t make sense when reading them from the address bar. Indeed, http://dev.opera.com/articles/view/
is a 404.
Specifically, the curriculum seems to be scattered around several parts of Opera’s website:
http://www.opera.com/wsc/
http://dev.opera.com/articles/view/foo/
http://dev.opera.com/articles/wsc/
http://www.opera.com/education/curriculum/
Truncated URLs
The curriculum URLs are being truncated at unhelpful places. Such as href="…/1-introduction-to-the-web-standards-cur/"
in the previous sample. I suggest using a much shorter end to them, like Joe Clark’s slugs. (Or, to a lesser extent, my own.)
Simple URLs as Only Location
Specifically, I suggest using http://opera.com/wsc/n
as the only location for each chapter, where n is the chapter number.
- Current URLs use chapter number. So would the the new URLs.
- New URLs remove:
- text which is hard to guess or remember;
- truncated URL problem;
- non-hackable 404 portions;
- unnecessary
www.
subdomain; - and the
dev.
subdomain since that looks like a development version of the website, rather a section of the website which is for developers. (That might just be me, though.)
- New URLs re-use the simplest path which is already public.
The result is short, logical, hackable, memorable and guessable (to varying extents).
Old Page
The main navigation links to a strange old curriculum homepage. The TOC isn’t on it and it has the promo-looking button. Specifically, you reach that page by doing this:
- Hover over Company.
- Click Education.
- The page loads.
- Scroll down to the row of 4 images.
- Click the 2nd image link or the “Web Standards Curriculum” text link below it.
- The strange curriculum homepage loads.
Instead, I suggest this should go to the /wsc/
area.
Image Links
The alt
text for the image link’s in step 5 (above) is different from that link text, even though they go to the same place. Also, the image comes before the heading of the section it is part of:
<a href="/education/curriculum/"><img src="/education/images/th_studies.jpg" alt="Opera in your curriculum" /></a><h3>Opera in your curriculum</h3>
I suggest putting the <img>
inside the <h3>
, like this:
<h3><a href="/education/curriculum/"><img src="/education/images/th_studies.jpg" alt="">Opera in your curriculum</a></h3>
Since the heading text now provides complete link text, alt=""
is correct.
By making the heading into a link, the text which grabs the user’s attention is the text they can click to find out more. See it, click it. It also makes the clickable area huge: Fitt’s Law ftw!
Sidebar Links
When viewing an article, the right-hand navigation has an Article Categories section. This is a list of links (good) where the bullets change colour as you hover anywhere over each item (good) but you can only click on the actual text of each link (bad).
The list includes a Web Standards Curriculum link which goes to yet another TOC. The link which points to this page gets the special bullet (good) but remains a link (bad). Anyway, this TOC has a rather…erm…imaginative order for the articles:
The first article is in the top-left (good). But the rest of the articles are in reversed order (bad). This page could be removed and the sidebar link could go straight to the Web Standards Curriculum homepage, since that now has a TOC. Indeed, its TOC is better since it groups the chapters into sections and summarises the aspects they cover.
Copy & Paste
Opera’s markup is compacted to save bytes. Efficiency is good but they still use:
- a new line with a trio of horizontal tab characters in the “Making Opera WSC work for you” column;
- optional end tags;
- quotes around attribute values which don’t need them;
- XML fluff which does nothing in
text/html
; - a trio of stylesheets applied to the
screen
media, causing unnecessary HTTP thrashing; - long URLs which cause long
href
values; - and a slightly (but only slightly) excessive use of
<div>
and<span>
.
By producing legible markup, developers could learn from what Opera does as well as from what it’s curriculum says. The convenience of that learning opportunity seems far more valuable than saving an ounce of bandwidth. Clearly showing that you practice what you preach makes sense when you’re releasing a high-profile project telling people how they should make web pages.
Desynchronised TOCs
Article 4 has an “Is XHTML the adult-rated version?” link in its TOC. But this points to a “What is XHTML?” heading.
I guess the heading was edited to be less controversial but the TOC wasn’t updated? There’s a rogue <
entity at the end of the “An example page” link in the TOC, too.
“…and it’s goodnight from him.”
Opera’s website is good, for sure. But it “could do better” and really should do better, imho.
- Cross-browser compatibility testing is painful but necessary if you use standards right now.
- Rational IA aids straightforward navigation.
- Clean URLs should be a no-brainer for clueful websites.
- Link text,
alt
and clickable areas are basic aspects of usability and accessibility.
Lead by example by getting all of it right. Make improvements which exceed my suggestions.
Untangling Bad Tables (5th September 2008)
When I sent detailed analysis about headers
+id
, I thought it would put the thread back on track. There have been 10 replies since mine, several of considerable length. Precisely 0 were replies to the facts my analysis provided.
I echo a request made during the telecon to see the real table these tests were derived from. Complete and “in situ”, as they’d say on Time Team. This would enable better analysis about which columns are actually redundant and how the data is best arranged.
Story of the Redesign
In the small hours of 31st August 2008, I realised nobody has put forward an actual redesign of the Test File 3 data table. I spent several hours over the next couple of nights figuring out how it can be untangled. I kept notes of each observation, design change and rationale.
During the next week, I gathered peer review while writing headers
Issue “Resolved” and also this blog entry.
Peer Review
Ranging from a quick skim-read to detailed fact-checking:
- Anne van Kesteren
- Henri Sivonen
- Ian Hickson
- James Graham
- Lachlan ‘Lachy’ Hunt
- Shawn Medero
- Simon ‘zcorpan’ Pieters
Lachlan Hunt and James Graham recommended that I include all the columns in some Redesign tables, just in case they had highly varying values. I did this and covered a couple of other likely scenarios.
Comparison of Techniques
The improvements to a table can be studied numerically even before users test it.
Number of Cells | Rows | Size in Bytes | |||||
---|---|---|---|---|---|---|---|
Total | Headers | Data | Empty | ||||
Test File | |||||||
No scope or headers | 50 | 9 | 41 | 0 | 8 | 1,704 | |
Only scope | 50 | 14 | 36 | 0 | 8 | 1,872 | |
headers +id | 50 | 20 | 30 | 0 | 8 | 2,625 | |
Corrected | |||||||
<th> | 50 | 20 | 30 | 0 | 8 | 1,659 | |
<th scope> & <td scope> | 50 | 20 | 30 | 0 | 8 | 2,020 | |
headers +id pointing to <th> and <td> | 50 | 20 | 30 | 0 | 8 | 2,927 | |
10 rows, headers +id pointing to <th> and <td> | 202 | 52 | 150 | 0 | 32 | 9,615 | |
Redesign | |||||||
Redesigned <th> | 52 | 21 | 30 | 1 | 5 | 1,212 | |
Section headers replace 2 columns, redesigned <th> | 47 | 20 | 26 | 1 | 6 | 1,139 | |
Section headers replace 2 columns, footnotes replace 3 columns, redesigned <th> | 38 | 17 | 20 | 1 | 6 | 905 | |
<caption> replaces 2 columns, footnotes replace 3 columns, redesigned <th> | 37 | 16 | 20 | 1 | 5 | 879 | |
10 rows, redesigned <th> | 180 | 29 | 150 | 1 | 13 | 3,188 | |
10 rows, section headers replace 2 columns, redesigned <th> | 160 | 29 | 130 | 1 | 15 | 2,935 | |
10 rows, section headers replace 2 columns, footnotes replace 3 columns, redesigned <th> | 127 | 26 | 100 | 1 | 15 | 2,461 | |
10 rows, <caption> replaces 2 columns, footnotes replace 3 columns, redesigned <th> | 125 | 24 | 100 | 1 | 13 | 2,383 |
Footnotes
- Test File tables are from
headers
+id
Testing (Bug 5822). - Corrected tables are what I consider fairer versions of them.
- Redesign tables have a variety of cell re-arrangements and footnotes.
- Redesign 1 is the nearest to the original and they get further away after that.
- Comparing tables with the same number of investments makes the most sense. All tables have 2 investments unless the link text starts “10 rows”.
Overall, Redesign 3 and Redesign 7 (its 10-row version) are my favourites.
Cell Count
Each investment in Test File 3 has a row header and 3 row subheaders. Corrected 4 extends Test File 3 (with corrections) from 2 investments to 10 investments. The table goes from having 2 row headers and 6 row subheaders to having 10 row headers and an astonishing 30 row subheaders! This demonstrates the terrible effect bad design can have on table complexity.
Redesign 1 and Redesign 2 stay the most faithful to Test File 3. Because the row subheaders were converted into column headers, each investment has 1 row header and 0 row subheaders. Their 10-row versions, Redesign 5 and Redesign 6, go from having 2 row headers and 0 row subheaders to having 10 row headers and 0 row subheaders.
Moving those row subheaders into column headers may have seemed like false economy. But as the amount of data in the table becomes plausible, the improvement is remarkable.
Byte Count
The tests had an HTML4 DOCTYPE and were delivered as text/html
. Removing optional end tags is consistent with that.
Notice that Redesign 7 has 10 investments and still takes fewer bytes than Corrected 3, which has 2 investments but uses headers
+id
. Corrected 4 is just Corrected 3 with 10 investments. It takes nearly 3 times more markup than Redesign 7.
Test File 3 uses row numbers as part of the values in id
and headers
. The amount of markup per row increases when the row number reaches double figures. It increases again if the row number reaches 3 digits. This accelerating growth is avoided in Redesigns and they use less markup in the first place.
Judgement Calls
Each pair of Redesigns suits a different scenario for the original data.
If the Running Costs area is about how the Actual value changes each week, I think the column headers can be flattened to 2 levels and 4 more columns can be removed (the 2 duplicates per investment of Budgeted and Forecasted).
Redundant Columns
Columns where all the values are identical add unhelpful repetition to the table:
- Type
- Status
- Allocation
- ROI
- NPV
Columns are useful for comparing values. If the values are identical, no comparison is required. The shared values could be provided as a footnote below the table, removing 5 whole columns.
If the Type or Status vary, I imagine there would be many shared values. Instead of being in columns, full-width sectional headers could be used to group the table. This is compatible with Smart Headers and is a design pattern on the web and in print. The 5 columns are still removed.
If the other 3 columns (Allocation, ROI and NPV) vary, I imagine they would have many unique values. In this case, it would be best to retain those columns.
Column Headers above Row Headers
The top-left cell is the Child Investment header. The <title>
of the page already describes the data is about child investment portfolios and the cells below it are header cells. This header can be removed.
After pondering the table for some time, the Properties header cell started to look weirder and weirder. Each cell below it is a sort of row subheader. They seem unrelated to land ownership and real estate, so why “Properties”? Eventually I realised it’s meant in the sense of programmer jargon: each row subheader introduces one aspect of the Running Cost column group.
By removing the Properties header this area starts looking like a standalone table, with column headers and row headers. The row headers in column 1 are only required to tell which investment each aspect is for. But each investment shares the same aspects. These aren’t row subheaders, they’re column headers!
Row Subheaders to Column Headers
Making Budget, Aquired and Forecast into column headers beneath each date would create 3 levels of headers. Since column groups cannot be nested in HTML4 and scope="col"
isn’t smart about colspan
, this cannot be expressed using scope
in HTML4. Here’s what WCAG suggests:
- HTML Technique 5.1.2 of WCAG 1
headers
+id
is required for 2 or more header levels, even though HTML4scope
can cover 2 levels in a regular table.- H51 for WCAG 2
- Plain
<th>
for a single level of column and row headers. - H63 for WCAG 2
<td scope>
is fine for a similar table.- H43 for WCAG 2
headers
+id
is used when multiple header cells are associated with a data cell. The example uses a regular arrangement of cells.
The “Smart Colspan” aspect of the Smart Headers algorithm proposed for HTML5 understands the significance of colspan
. As does the algorithm presently in HTML5. They require neither scope
nor <colgroup>
for this case work. A fine example of how accessibility features in HTML5 look set to make accessible content genuinely easier to author than HTML4, WCAG 1 or WCAG 2 currently permit.
Header Proliferation?
3 levels of column headers may seem like a terrible proliferation of header cells. But it’s only 1 more header cell than the table had originally, since I removed Child Investment and Properties.
The rowspan="2"
for each column header preceeding Running Cost is incremented to 3
. This does not change markup size. In the data area, 14 rowspan attributes are removed from only 2 rows of data, reducing markup size. This reduction grows with the number of rows.
Test Files use 1 row branching into 3 after several columns. The absence of rowspan
in the redisgned data means each investment uses 1 continuous row. This simplifies the markup, making it easier to read and to generate. The structure is also simplified, which I imagine makes it more intuitive to move around in non-visually.
Arrangement Differences in Detail
In the Test Files, the value for an aspect of an investment has 2 rows between it and the same aspect of a different investment. For example, there are 2 rows between the Forecast value of Partner Portal and the Forecast value of Partner Portal 2. You must skip past 2 rows each time, which causes slight delay. I found doing this for a minute straight really draining, even as a sighted mouse user.
I expect the difficulties would be worse still a screen magnifier. If the structure of the table were understood, perhaps it wouldn’t be so bad in a screen reader. Then again, figuring out the structure would be that much harder in the first place.
In contrast, flat rows means 1 type of comparable data down each column. This makes like-for-like comparison between adjacent investments a single movement.
Unhelpful summary
Test File tables provide summary="Child investment portfolios with budgeted, actual and forecast running costs for dates"
. The <title>
of the page already says it“”s about “Child investment portfolios”, so this is redundant. The Running Cost column header has dates below it, making clear it’s “for dates”.
The row subheaders are a peculiar arrangement. Warning non-visual users about them may well be useful. Avoiding peculiar arrangements in the first place removes the need for any warning, though.
As such, summary
is unnecessary for the Redesign table.
Useful <caption>
The Test Files are given a <title>
and <h1>
which only makes sense for a Test File.
My example adds a <caption>
which seems plausible for what the table would use in a genuine web page. By including the year in the <caption>
, it becomes redundant in the column headers. I imagine this would cut out a fair bit of repetition in text-to-speech and visibly saves space.
Human Date Format
Test File tables use MM/DD/YYYY
format for dates, which is commonplace in the USA. To a Brit like myself, putting the middle unit (months) before the smallest unit (days) and putting the biggest unit (years) after that is an unnatural sequence. To a European, putting the biggest unit at the end may not make sense. If the now redundant /YYYY
portion is removed, the remaining DD/MM
becomes nonsense to just about everyone.
You could keep the /YYYY
portion in the header, with the repetition that goes with it.
Instead of that, I wondered if this was an opportunity to pick a less ambigious representation of dates in the table. When I noticed how wide the date column headers were, I realised ordinal dates with full month names would fit quite well. So that’s what I used.
Later, I realised they were all in December. But moving “December” to the <caption>
leaves behind a simple ordinal number for each cell. This might not look or sound like a date. So I kept the month names to help these cells stay clear and usable for all.
Thoughts
Other approaches to redesigning the table probably exist and may be even more effective. This is just the route I took (during the small hours of 2 mornings, I hasten to add!) with what context is available from the Test File versions (which isn’t very much). I encourage others to try redesigning the original table Test Files…and provide corrections to the numbers in these notes. c{:¬P
As the number of rows increases, the improvements I devised had a greater and greater impact. Even with a 2-row Test File, I was able to make significant simplifications to the markup and arrangement of the cells. Growing it to plausible size (10 rows of data) increased the benefits dramatically.
Redesigning a table does require expertise. Then again, so does headers
+id
. But where headers
+id
can only paper over the cracks for users of one AT, an expert redesign can help everyone.
Conclusion
All the above considered, I’d call turning bad tables into good tables a plausible and desirable solution.
Reponse to headers
Feedback (5th September 2008)
The replies to my last Public-HTML message don’t quite add up.
scope
Errors in Test Files
It is not a requirement that when
Gez Lemon, Re:colspan
orrowspan
are used thatscope
associations must becolgroup
orrowgroup
.headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
My first analysis linked to the relevant part of HTML4:
row
:- The current cell provides header information for the rest of the row that contains it [...]
It says “the row” rather than “the rows spanned by that cell”. Also, a cell is only contained by one <tr>
.
It’s a similar situation with scope="col"
, as described in that same part of HTML4:
col
:- The current cell provides header information for the rest of the column that contains it.
Again, it says “the column” rather than “the columns spanned by that cell”.
The
Gez Lemon, Re:scope
attributes on the test file are correct.headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
No, they are wrong. Just as my first analysis showed. Hopefully this is clearer to you now.
Standards Compliance of Implementations
The “corrected” markup examples don’t work with screen readers - the incorrect columns are announced the same way as the “bad ” examples.
Gez Lemon, Re:headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
(Referring to the example tables I published previously.)
Test File 2 uses scope
wrongly. Corrected 2 uses scope
properly.
When a device gets scope
wrong, that’s a bug in the device. When a device doesn’t implement scope
, that choice was made by the manufacturer of that device. In either case, the markup in Corrected 2 is still correct.
Comparison Concerns
Your redesigned tables make it far more difficult to compare budgeted, actual, and forecasted data for a particular date - the primary purpose of the table.
Gez Lemon, Re:headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
Those values are adjescent in left-to-right order on the same row, beneath the column headers for that date and aspect. What is “far more difficult” about that compared with the Test Files? They arrange the values top-to-bottom, beneath the column header for date and to the right of the row header for that aspect.
Comparing Between Dates
In the Test File data, values for Budgeted and Forecasted never change with date. As such, there are no useful comparisons can be made between dates. Indeed, I considered collapsing them to a single column each and mentioned this in the analysis.
The values for Actual do change with each date but this comparison isn’t primary, according to Gez’s message. It’s trivial to re-arrange the cells to achieve this whilst keeping the table regular, though. Henri Sivonen suggested (off-list) an alternate arrangement for the Running Costs area to do this.
Users as Designers
The table I put forward for the bug is one example of how the user wants to view the table, which underwent usability studies by our client. Redesigning it so that it’s more difficult to read without any kind of user testing is not an improvement.
Gez Lemon, Re:headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
The work was reviewed by 7 people (not counting myself). The reviewers who expressed a preference were unanimously in favour of the redesigned versions.
As such, I disagree with your claim that the Redesigns are “more difficult to read”.
Re-arrangements & Simplicity
As for rearranging the data table to simplify the problem - the example Gez provided is a user generated table. The user wants to view the table like he wants to view it, as it allows user’s to quickly get an overview in order to make timely decisions.
With the
Laura Carlson, Re:headers
+id
approach. Any table with any relationship between heading cells and data cells can be defined directly by addingid
attributes andheaders
attributes to the cells - not touching the structure of the table.headers
issue resolved - allowing a<td>
to be referenced by a header to be in the HTMl5 spec.
Corrected 1, 2 and 3 do not re-arrange the cells. They merely correct errors and unfair shortcuts made in the corresponding Test File 1, 2, and 3. This allows accurate comparisons to be made between the techniques, such as those in the comparison table I provided last time.
The comparison table, along with View Source, show how much simpler and more intuitive the plain
scope
or headers
+id
.
I’ve since had an off-list conversation with Gez about the origin of the Test File table. It revealed that:
- The original has hundreds of rows, yet the Test Files only have 2 rows.
- The 3 aspects are given for 25 dates, yet the Test Files only have 3 dates.
- The arrangement of columns is different.
- The data was scrambled.
The Test Files, particularly Test File 3, were presented as being genuine during the telecon. Yet this off-list discussion has revealed they were falsified, with massive alterations from the original. I find this shocking.
Genuine Research
In my tables study from 2007, the original source is linked to directly or an exact snapshot is given. Some of the directly linked tables have changed since I collected them. But they were all correct in early 2008, when Ian Hickson analysed them to produce the table header association we currently have in HTML5.
Genuine tables were analysed so that accurate conclusions were made. The openness of the collection lets reviewers check the tables for themselves, unmodified and “in situ”. These tables, pure and real, are what Smart Headers and the HTML5 algorithm were developed from.