Wednesday, February 13, 2013

Opera: Presto! It's now WebKit

Opera is replacing its Presto rendering engine with WebKit (Chromium, really, when you factor in the V8 JavaScript rendering engine). Big news as of this morning.

If you've been paying attention, it's not really that big or news. About a month ago a video was leaked showing Opera using WebKit (the video has since been pulled from YouTube). Within the last three weeks two of the Opera folks I follow on Twitter are suddenly no longer Opera folks (Tiffany Brown, Patrick Lauke). Heck, even Opera's founder sold off some shares yesterday. If you paid attention, you knew something was up.

All of that aside, what does this really mean?

For Developers

I feel most web developers already ignored Opera. For those developers they can continue to be lazy and ignore Opera.

For Users

The short term impact on users will be minimal. Users will upgrade, users will surf, users may notice some sites work or look a little better.

For users trapped on old Android devices with the Android stock browser (that never seems to upgrade), this could result in a better experience — assuming these users know about and download the Chromium-powered Opera.

For Standards

Opera has an impressive place in the mobile world, being at the top of the pile globally. Opera's participation in the standards process has been valuable, partly because its rendering engine has been used to help move the process forward thanks to early implementations, differences in implementations, and arguments over implementations.

While the standards evangelists at Opera may do a great job of contributing back to Chromium, Google may be the block from those changes being committed. Even when changes get to Chromium, there is no guarantee that they'll make it back into WebKit, which might involve getting past Apple. Only if those changes get into WebKit do they stand a chance of making it Apple's Safari.

From the co-chairman of the W3C CSS Working Group, Daniel Glazman:

For the CSS Working Group, that's an earthquake. One less testing environment, one less opportunity to discover bugs and issues. Let me summarize the new situation of the main contributors to the CSS Working Group:

  • Microsoft: Trident
  • Apple: WebKit
  • Google: WebKit
  • Opera: WebKit
  • Adobe: WebKit and their own Adobe Digital Editions rendering engine found in many ebook readers
  • Mozilla: Gecko
  • Disruptive Innovations: Gecko
  • HP: has delivered WebKit-based products in the past but is pretty browser-agnostic IMO
  • Rakuten: ADE and probably WebKit
  • Kozea: WeasyPrint
  • Qihoo 360 Technology Co: both Trident and WebKit
  • other Members of the Group: I don't know

Suddenly I feel like the US political term lead from behind is apt.

Some other reactions from the Twitters:

Related

...to the news about Presto

...to older bits

...And evidence that lazy developers can keep on keeping-on (from almost a year ago):

Update, February 14, 2013

Since I posted this, some folks have asked just what Opera did that was so useful? This quote from David Storey's post outlines some of it pretty well:

Moving from HTML to CSS based layouts? Opera was perhaps the first to have a useable CSS engine. HÃ¥kon (father of CSS, and Opera CTO) often says it was the reason he started to believe a browser could be made in Norway, not just the USA, and joined Opera. AJAX? Opera reverse engineered this from MS’ ActiveX based approach and were the spec editors through Anne van Kesteren. HTML5? Started at Opera with Ian Hickson and others. Responsive web design? Media Queries came from Opera, and were implemented for years before showing up in other browsers. What about native video on the Web? Opera again.

Tuesday, February 12, 2013

ARIA Tabs

Photo of whiteboard and ARIA tabs sketch.

Last week I spent my Friday afternoon trying to get my head around how to apply ARIA properly to a tabbed interface. I even got so far as to map it out on my whiteboard and snap a photo so I could mull it over during the weekend.

And then the very next day Marco Zehe, responsible for accessibility quality assurance at Firefox, posted Advanced ARIA tip #1: Tabs in web apps and suddenly my weekend of snow shoveling turned into fiddling.

Marco's post included sample HTML for tabs and an outline of how the script to control it should function, but did not include the necessary styles or script to make it behave as tabs. Since I was marking up a tab list anyway to incorporate ARIA, I'm sharing my code here for others to try, enhance, and so on. It's also on CodePen, so you can fork it and fiddle there.

The HTML

My code has minor differences from the example. For instance, I add a return false; at the end of the event handler. I also call the function that activates the first tab at the bottom of the page, so all tabs start as un-selected and no tab panels are visible until that function fires. You can just as easily put the logic into your HTML and CSS to have one pre-selected and skip that function call altogether.

<ul class="tabList" id="tabs" role="tablist">
  <li role="presentation"><a id="tab1" href="#panel1" onclick="showTab(1);return false;" role="tab" aria-controls="panel1" aria-selected="false">Tab 1</a></li>
  <li role="presentation"><a id="tab2" href="#panel2" onclick="showTab(2);return false;" role="tab" aria-controls="panel2" aria-selected="false">Tab 2</a></li>
  <li role="presentation"><a id="tab3" href="#panel3" onclick="showTab(3);return false;" role="tab" aria-controls="panel3" aria-selected="false">Tab 3</a></li>
</ul>

<div class="tabPanels">
  <div id="panel1" role="tabpanel" aria-labelledby="tab1">
  <p>
    Nulla tincidunt pharetra tortor. In dapibus ultricies arcu. Suspendisse at purus eu est tincidunt feugiat. Praesent et sapien. Vivamus fermentum, diam vel ornare vestibulum, nibh massa imperdiet lectus, eget tincidunt urna urna nec erat. Curabitur interdum. Nam lorem nunc, posuere quis, suscipit eu, hendrerit vitae, nisi. Etiam hendrerit tincidunt felis.
  </p>
  </div>

  <div id="panel2" role="tabpanel" aria-labelledby="tab2">
  <p>
    Vestibulum id eros eu lorem tincidunt sollicitudin. Suspendisse ligula. Sed nisi magna, elementum at, ultricies in, tincidunt imperdiet, quam. Nulla semper. Suspendisse potenti. Sed sollicitudin dolor aliquet purus. Aliquam dui. Proin arcu metus, porttitor eget, pulvinar nec, molestie dapibus, ligula.
  </p>
  </div>

  <div id="panel3" role="tabpanel" aria-labelledby="tab3">
    <p>
      Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam vel erat. Vestibulum egestas purus ut felis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
    </p>
  </div>
</div>

<script>
  showTab(1);
</script>

The CSS

This CSS presumes you've already set your typefaces, your page background, and everything works as you want. I have put the minimum styles to make it visually look like tabs. You may notice that I use two different selectors for both a selected tab and for a hidden tab panel. One is by a class name, the other is by the value of the appropriate aria- attribute. Use the first for broader (older) browser support and the latter if you don't care. If you do target just current browsers, then you may adjust the script below to skip writing classes.

.tabList {
  list-style-type: none;
  padding: 0;
  margin: 0 auto;
}

.tabList a {
  display: block;
  float: left;
  border: .1em solid #000;
  padding: .25em 2em;
  margin: 0 0 -1px .25em;
  border-radius: .5em .5em 0 0;
  background-color: #aaa;
}

.tabList a:link, .tabList a:visited, .tabList a:hover, .tabList a:focus, .tabList a:active {
  text-decoration: none;
  color: #000;
}

.tabList a:hover, .tabList a:focus {
  background-color: #ccc;
}

.tabList a.selected {
  background-color: #fff;
  border-bottom: 1px solid #fff;
}

.tabPanels div {
  clear: left;
  margin: 0 auto;
  padding: 1em 2em;
  border: 1px solid #000;
  border-radius: .25em;
  background-color: #fff;
  display: none;
}

.tabPanels div.selected, div[aria-hidden=false] {
  display: block;
}

.hide, div[aria-hidden=true] {
  display: none;
}

The Script

The following script toggles classes for the tabs and the tab panels, as well as adjusting the aria-selected and aria-hidden attributes. There is no keyboard functionality in it at all, but I am always willing to take some from a kind donor. As I noted above, if you use solely the aria- attribute as a CSS selector, you can drop the part that changes the class for each element.

var OpenTab;

function showTab(num) {
  try{
      if(OpenTab!=undefined){
        var OldTabID = document.getElementById('tab'+OpenTab);
        var OldPanelID = document.getElementById('panel'+OpenTab);
        OldTabID.className = '';
        OldPanelID.className = 'hide';
        OldTabID.setAttribute('aria-selected', false);
        OldPanelID.setAttribute('aria-hidden', true);
      }
      var TabID = document.getElementById('tab'+num);
      var PanelID = document.getElementById('panel'+num);
      TabID.className = 'selected';
      PanelID.className = 'selected';
      TabID.setAttribute('aria-selected', true);
      PanelID.setAttribute('aria-hidden', false);
      OpenTab = num;
  }catch(e){}
}

An Example

The following is an embedded version of the tabs on CodePen. Because of how CodePen works, you'll see a few minor differences in styles, but this is at least a functional example which you can fork and tweak.

For example, on CodePen, the function to enable the first tab must be called in the block of script itself, but I prefer to call it at the bottom of the page.

For reasons I cannot figure out, the tabs on the embedded version of this Pen do not work. Visit the tabs directly on CodePen to see them in action.

Check out this Pen!

Wrap-up

That's it, pretty simple. If you have suggestions, corrections, or are a regular AT user and can offer further insight, please feel free to share in the comments or tweet me on the Twitters.

Update, August 6, 2013

Marco Zehe, the guy who wrote the article Advanced ARIA tip #1: Tabs in web apps (which I link above) offered some adjustments to make to my sample code. In essence, dump the aria-hidden from the HTML and use the CSS style visibility: hidden; in its place. His explanation:

Update, December 4, 2013

Heydon Pickering has an example of ARIA tabs as well, with slightly different approach (aria-controls instead of aria-labelledby). He also offers a tip for maximizing compatibility: