June 22, 2010

BBC News, pt II

In part two of our attempt to rewrite the BBC News app with web technology, we’re going to move onto the page structure itself. Some of you may have been left cold by last week’s trawl through what was happening behind the scenes, so let’s get up front again, and try and at least capture the main UI elements of the app in both portrait and landscape mode.

At this point, I am going to work with a single static HTML file. I’m not going to be pulling any dynamic content yet, and nor am I going to confuse things by trying to get too clever too soon. Hopefully a simple file will make it easier to understand my thought process.

The first thing to notice when looking at the app is that the landscape/portrait rotation changes the layout quite considerably. So most of what we’ll try to do first is understand how that can be done elegantly with a bit of CSS and maybe Javascript. Although the page as a whole looks quite different, the same panels are more or less present, so it’s more a matter of moving things around than changing functionality fundamentally.

Page topography

If you have the app open in front of you, take a look at how it’s laid out.

The BBC News iPad app in portrait mode

The portrait mode of the app is basically a series of horizontal panels, starting with the red control bar at the top. It has a 1px highlight at the top, 41px of slight gradient red, then 2px of dark shadow at the bottom. Beneath this is a grey bar continent the news ticker. It also has a 1px highlight at the top and then 30px of solid grey. Then there is the category selector (‘Top Stories’, ‘Americas’ and so on), which is 36px of solid black. After this is the news story selector: 152px of dark gray, with a 1px border at the bottom. Finally we’re into the page itself, 614px high, and scrollable. At the end of the page is a fixed 90px ad (although not always), and a 36px footer, containing a horizontal scroll indicator.

(Let’s just check all that adds up. 1,004px, which, yes, with the 20px iPad bar at the top of the screen gives us the device’s full 1024px).

The BBC News iPad app in landscape mode

In the landscape mode, we have a slightly more interesting layout. The control bar and news ticker are exactly the same as the portrait mode (although, of course, wider), followed by a 1px black rule. After that, on the left of the screen, 507px wide, we have the full height of the screen dedicated to combined category and news story selectors. These are 168px in height each, with a single 1px shadow underneath. Below these ‘open’ panels are the headings of the other news sections. These include red bars (18px plus 2px highlight above and 2px shadow below) and larger collapsed panels (40px plus 2px highlight above and 2px shadow below). The very bottom of the left hand pane is a hatched area of 106px containing copyright and help links. Between the left and right panes is a single pixel grey separator, and then we have the main news page, 516px wide by 636px high. The 36px footer rounds off the right hand side of the page.

It’s interesting to note that the designers have actually made the main reading pane narrower in the landscape mode than in portrait.

At first blush, neither page layout alone seems too hard to reproduce with HTML and CSS. The challenge will probably be moving and removing portions around when the device rotates between the two.

Some markup

Let’s start with the outer part of the page’s HTML. We want to make sure it’s nice and standard, and declares viewport settings correctly.

<!DOCTYPE html>
<html>
 <head>
  <title>BBC News</title>
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
 </head>
 <body>
  ...
 </body>
</html>

The apple-mobile-web-app-capable setting in the first <meta> tag removes the thick browser navigation bar from the page when the user has added it as a bookmark on their home screen. This will give us exactly the same real estate as the native client app (i.e. the whole page with the exception of the black 20px bar at the top). The second <meta> tag disables the pinch and zoom scaling on the page, which is not present on the app we are trying to emulate.

Taking the portrait view first, we’ll create some nice semantic panels for the structure of the page:

<div id='bbc_controls'>BBC</div>
<div id='bbc_ticker'>News ticker ...</div>
<div id='bbc_category_selector'>Top Stories, Americas ...</div>
<div class='bbc_article_selector bbc_category_selected'>War, Pestilence, Famine ...</div>
<div class='bbc_article_selector'>Oil, Budgets, Taxes ...</div>
<div id='bbc_article'>Blah blah ...</div>
<div id='bbc_banner_ad'>Buy ...</div>
<div id='bbc_scroll_footer'>o o o o</div>

You’ll see I didn’t spend too much time on the copy. We just want to get the right panels in the right place. Also notice that I use HTML id attributes to strongly identify these panels as they are unique within the app. The one exception is the article selector, which I have indicated with a class attribute because there are going to be many of these selectors (one for each news category) – certainly in the landscape mode where they are stacked on the left hand side, but also in portrait mode, where I think I’ll have multiple panels too, although only one will show at a time.

I suppose I could have used class attributes for all of the panels, but this seems sensible enough until the semantic police haul me in. Also notice that I prefix every id or class with ‘bbc_’. This sort of thing prevents collisions with any other styling or behaviors when you’re mixing and matching CSS and Javascript libraries. (Not that we’re likely to do so here, but I guess it’s habit).

Wait! This is HTML5. Let’s do something more interesting than using <div> tags.

<nav id='bbc_controls'>BBC</nav>
<ul id='bbc_ticker'><li>News ticker ...</li></ul>
<nav id='bbc_category_selector'>Top Stories, Americas ...</nav>
<nav class='bbc_article_selector bbc_category_selected'>War, Pestilence, Famine ...</nav>
<nav class='bbc_article_selector'>Oil, Budgets, Taxes ...</nav>
<article id='bbc_article'>Blah blah ...</article>
<aside id='bbc_banner_ad'>Buy ...</aside>
<nav id='bbc_scroll_footer'>o o o o</nav>

Many of our panels are predominantly there to provide navigation, so let’s promote them to be <nav> tags. The main article can be an, er, <article> tag, and the ad (which is fairly auxiliary to the matter at hand) seems a good candidate for being an <aside>. The footer is not a <footer> tag, since that implies meta information about an HTML5 section, and in our case the footer is merely a navigational tool to scroll through pages – which just happens to be at the foot of the page. Finally I set the ticker to be an unordered list tag <ul>, which will ultimately include multiple headlines (in their own <li> tags) that we will rotate through.

OK. let’s fire up the iPad browser and take a look.

Unstyled HTML version of BBC News web app

Not too inspiring yet. Let’s see what a little CSS can do.

<style>
 * {
  -webkit-text-size-adjust:none;
  padding:0; margin:0;
 }
 #bbc_controls {
  display:block; width:100%;
  height:44px;
  background:#ff0000;
  color:#ffffff;
 }
 #bbc_ticker {
  display:block; width:100%;
  height:31px;
  background:#cccccc;
  color:#ff0000;
 }
 #bbc_category_selector {
  display:block; width:100%;
  height:36px;
  background:#000000;
  color:#ffffff;
 }
 .bbc_article_selector {
  display:none; width:100%;
  height:153px;
  background:#333333;
  color:#ffffff;
 }
 .bbc_article_selector.bbc_category_selected {
  display:block;
 }
 #bbc_article {
  display:block; width:100%;
  height:614px;
  background:#ffffff;
  color:#000000;
  overflow:auto;
 }
 #bbc_banner_ad {
  display:block; width:100%;
  height:90px;
  background:#ff00ff;
  color:#000000;
 }
 #bbc_scroll_footer {
  display:block; width:100%;
  height:36px;
  background:#000000;
  color:#ffffff;
 }
</style>

Which looks something like:

Styled portrait version of BBC News web app

Ah… that looks a little better – although I’m not trying too hard to match the colors yet. Notice how I’m defending against the iOS browser’s tendency to auto-scale fonts with the -webkit-text-size-adjust style, and resetting the margins and paddings at the start too. (We’ll get all that stuff pixel perfect later). I’ve also learnt something new here: HTML5′s new <nav> element is treated as an inline element by default, so I need to set them as blocks so that they can be styled to the whole width.

Also I hide the article selectors by default and simple display the one that is marked as bbc_category_selected. In portrait mode, you only see one at a time.

But I have hit a snag here. The bbc_article block itself has the right height, and the ad and footer are fixed to the bottom of the page as a result. But when I try to load it up with a large amount of content, overflow:auto does not do what I expect. In a desktop browser that would normally add scroll bars to an element whenever it spills outside of its constrained dimensions. On the iPad, the height is honored, but the scroll bars never show, even when the page is longer than 614px. What’s more, a single finger doesn’t scroll the article (as it does in the native app): two fingers are required, and I can’t guarantee that users will figure that out.

I try playing with position:fixed to hold the top and bottom parts of the page to their physical positions on the screen in the hope that I can use the normal page scrolling to make it seem as though the article alone is scrolling, but that also does not work (Apple’s viewport philosophy has it that the fixed position means ‘fixed to the page’, not to the screen). But storming to the rescue is Matteo Spinelli’s iScroll library which replaces what seems to be the browser’s oddly missing feature in this regard.

We’ll look in more detail at this when we come to integrate the content into the design. Suffice to say I can breathe easy again on the article scrolling, not to mention the category selectors and other scrollable elements in the page. (Chris Barr has a simpler implementation, but I want to see scroll bars as the pane moves, so iScroll it is.)

Landscape styling

Now onto the landscape mode. In the CSS above, I’ve assumed that portrait is the default mode. But when the rotation changes, some of the elements need to change shape and position. What I will try first is to register a small piece of code on the rotation and page load events, and use it to toggle a class onto the page’s body tag. Then I can use that class to create priority CSS styling for the landscape mode:

<script type='text/javascript'>
 window.addEventListener('load', setOrientation, false);
 window.addEventListener('orientationchange', setOrientation, false);
 function setOrientation() {
  var orientation = Math.abs(window.orientation)===90?'bbc_landscape':'bbc_portrait';
  if (document.body.className == '') {
   document.body.className = orientation;
  } else {
   document.body.className = document.body.className.replace(/bbc_landscape|bbc_portrait/, orientation);
  }
 }
</script>

When the page loads, and when the device is rotated, the new orientation is placed into the class, or the existing one replaced. Simple enough. Let’s test this out by adding a temporary CSS rule:

.bbc_landscape #bbc_article {
 background:#00ffff;
}

And indeed, it goes cyan when I rotate the iPad. But this is a technique I’ve used on the iPhone for some time… and I’ve heard a rumor that CSS media queries now work on the iPad. Using these, I can specify that a CSS rule only fires when some condition or other is true. Well then, how about orientation? I remove the script and replace the temporary CSS rule with:

@media (orientation:landscape) {
 #bbc_article {
  background:#00ffff;
 }
}

Rotate and… ah! Genius. It works a treat, just as before. Not only can I save myself a few lines of script and an unnecessary class on the <body>, but this syntax allows me to nest all my landscape rules into one nice block in the CSS. More importantly I am having fun the bleeding edge of contemporary CSS3 support.

So let’s add a few more real rules inside the @media braces and see if we can get things to move to their landscape positions.

#bbc_ticker {
 border-bottom:1px solid #000000;
}
#bbc_category_selector {
 display:none;
}

The ticker gains a bottom border, and the category selector doesn’t show in landscape mode. But it is replaced with a small title at the top of each article selector, so I add those into the markup too, interleaving the article selectors. I also group up all these article selector pieces into an outer wrapper that I can use to held them all to the left-hand side of the screen in the landscape mode:

<div id='bbc_article_selectors'>
 <h2 class='bbc_article_selector_title'>Top Stories</h2>
 <nav class='bbc_article_selector bbc_category_selected'>War, Pestilence, Famine ...</nav>
 <h2 class='bbc_article_selector_title'>Americas</h2>
 <nav class='bbc_article_selector'>Oil, Budgets, Taxes ...</nav>
</div>

I also remember to make sure the titles don’t appear in the portrait view, and insert this into the main part of the CSS (i.e. not inside the portrait braces):

.bbc_article_selector_title {
 display:none;
}

The rest of the landscape CSS, including the styling for these new article selector elements is as follows, and we also place these inside the @media braces:

#bbc_article_selectors {
 display:block; width:507px;
 height:672px;
 background: #111111;
 border-right:1px solid #666666;
 float:left; clear:left;
}
.bbc_article_selector_title {
 display:block; width:507px;
 background:#333333;
 color:#ffffff;
}
.bbc_article_selector {
 display:block; width:507px;
}
#bbc_article {
 width:516px;
 height:636px;
 float:right; clear:right;
}
#bbc_banner_ad {
 display:none;
}
#bbc_scroll_footer {
 width:516px;
 float:right; clear:right;
}

…most of which is ensuring that the two-column view works correctly and will be scrollable. The new left-hand container also serves as a useful way to provide the 1px vertical bar between left and right parts of the screen.

Finally I personally don’t get the ad in landscape mode, so I nuke that too. Let’s fire it up:

Styled landscape version of the BBC News web app

Not bad, not bad. It’s not beautiful by any means, but it’s structured correctly, and it serves as a basic wireframe for the app from here on in. More importantly, the orientation works a treat: the CSS media query is applied quicker than the eye can detect, and feels snappy. (I’ll be using plenty of Javascript for all the scrolling I think, so it’s nice to know that this is already taken care of without it.)

Wrap up

So that’s it for now. I’ve put the HTML and CSS in a single static file and it’s up on this server here, so you can go and check it out in an iPad for real. Just don’t forget to add it to the home screen to make the full-screen mode work properly.

We’ve shown that the basic structure of the app is very feasible with HTML5 and CSS alone, and now we need to move on to loading up the dynamic data, and then, I suspect, the panel scrolling. At that point, things should really start to come together. It’s exciting stuff, right?

Comments (19)

  1. June 22, 2010

    [...] This post was mentioned on Twitter by Dion Almaer and James Pearce, aki. aki said: RT @jamespearce: The next part of my adventure to rewrite the BBC News iPad app in HTML5 & CSS: http://is.gd/cYEfo – going OK so far. [...]

  2. June 22, 2010
    Matteo Spinelli said...

    good luck for your project. Any native app hater is my friend. I’ll follow you closely (so you better watch your back =)

  3. June 22, 2010
    Paddy said...

    I’m trying to make a HTML5 webapp at the moment too but coming and coming across similar issues. The iPhone doesn’t support fixed positioning so trying to get a div/nav element to stick to the bottom of the page is next to impossible.
    I see what you did here was set the article area a fixed height and let everything flow round it, then set it to auto overflow, however I don’t know if that’ll work once there is content in the box. I’d love to see if there was a suitable solution or if iOS 4′s browser supports fixed positioning.

  4. June 22, 2010
    Ms2ger said...

    “We want to make sure it’s nice and standard, and declares viewport settings correctly.” Just unfortunate that that isn’t possible, as the viewport meta element is non-standard… But you’re clearly doing a great job here!

  5. June 22, 2010
    James said...

    > standard, and declares viewport settings correctly

    Haha, I see what you mean ;)

  6. June 23, 2010
    John said...

    Until that distant day where everyone supports media queries, here is my take on device orientation JS – the change is to make sure we don’t mangle any pre-existing bodyclasses on the document:

    http://gist.github.com/387650

  7. August 19, 2010
    James Hurley said...

    Something that worries me is how iOS specific this is. Does it work on Android, Blackberry, Symbian/Maemo and so on. In my own tests there is no “native icon” functionality on any other OS, no chromeless browser experience, and other iOS specific CSS/JS issues.

    • August 19, 2010
      James said...

      To start with, much. It’s specifically the iPad app that I’m trying to replicate.

      But… of course the HTML-based approach would be quite applicable for any capable enough OS platform. I’ll let you know :-)

  8. August 21, 2010

    [...] This post was mentioned on Twitter by aslund, aslund. aslund said: BBC-News-iPad-App-Nachbau: http://whitherapps.com/bbc-news http://whitherapps.com/bbc-news-pt-ii http://whitherapps.com/bbc-news-pt-iii [...]

  9. August 22, 2010

    [...] app into a web app based on HTML5. He has already started 3 blog post on the BBC News apps, Part1, Part2 and Part3. If you see the screenshot below he has gotten pretty far. BBC News (HTML5) BBC News [...]

  10. August 26, 2010
    John Holdun said...

    My heart sank when you unveiled all those DIVs and it grew three sizes when you turned them into luscious HTML5 tags. This is fascinating; I’ll be watching closely!

  11. August 30, 2010
    Armin said...

    Good work, I am converting an native app (android) to an web app and was looking to see what others are doing and found your site. Nice job.

  12. March 18, 2011
    blowjobs said...

    oidi juxkq sexy handjobs vznwts j na l mgj

    onse lyxlu [URL=http://www.sexyhandjobs234.com – blowjobs[/URL – cxassp w eg h yha

  13. April 20, 2011

    Watch the most beautiful female exhibitionists on the web!

  14. June 21, 2011
    Tameka Blasing said...

    Great post. I was checking continuously this blog site and I’m amazed! Very helpful info particularly the last part :) I care for such information a lot. I was seeking this particular information for a very long time. Thank you and good luck, Tameka Blasing

  15. November 14, 2011

    Attractive portion of content. I simply stumbled upon your weblog and in accession capital to say that I acquire in fact loved account your blog posts. Any way I will be subscribing in your feeds or even I fulfillment you get right of entry to consistently rapidly.

  16. November 24, 2011
    dekoracje said...

    Hello to every body, it’s my first go to see of this weblog; this webpage includes awesome and genuinely excellent data in favor of visitors.

Leave a Reply