Opera Presto 2.1 - Web standards supported by Opera’s core

By Bruce Lawson

This article is obsolete

It's retained for historical purposes only. Download the latest version of Opera or see what's coming soon in Opera.Next. See Web specifications support in Opera.

Introduction

There are many Opera browsers, but each uses the same rendering engine, which is called Opera Presto. You can be sure that every device, desktop or mobile running a browser with Opera Presto 2.1 will render the Web site identically, although with a browser user interface appropriate to that device.

Opera Presto 2.1 has very thorough support for current standards like (X)HTML, XML, XSLT, CSS 2.1, SVG 1.1, JavaScript and the DOM, but it also includes support for many aspects of nascent standards such as HTML 5 and CSS 3. Opera passes the Acid 1 and 2 tests, and scores 83% on the Acid 3 test—check the Acid tests out for yourself.

Here’s a rundown in detail.

Thanks a lot to everyone who wrote the examples featured below.

Opera Presto 2.1 Web standards support

(X)HTML, CSS 2.1 and JavaScript

As we all know, (X)HTML, CSS and JavaScript are the three mainstays that we do most of our Web site building in; it also won’t be a surprise to many of you that Opera has a reputation for being one of the most standards-compliant browsers. This reputation starts with current Web standards, and is gradually building forwards to some of the more emergent ones, which we’ll discuss later.

Presto 2.1 supports

CSS 3

CSS3 is currently still an emerging technology, with the different parts of its specification at various different stages. Opera Presto 2.1 supports many of the more complete parts of the spec, including the majority of the CSS Snapshot 2007, as explored below.

Media queries

Media queries are a CSS 3 construct, which work like Microsoft’s conditional comments, except that these are web standards rather than proprietary constructs, and you can ask more advanced queries of the renderer than simply “what version are you?”

For example, you can enclose a block of CSS rules inside a media query, and then have them applied to your markup (or not) depending on a condition, such as “is the browser window less than 480 pixels wide”? Put into code, this would look something like so:

img { 
    margin: 0 0 10px 10px; 
    float: right;
}

@media all and (max-width: 480px) { 
    img { 
        margin: 10px auto;
        float: none; 
        display: block;
        font-size: 80%;
    }
}

I’m sure you can immediately see the benefits here—this kind of dynamic layout optimization is very powerful for cutting down on dynamic code, and making sites behave better on alternative devices, such as mobile phones (although to target rules at mobile browsers such as Opera Mini and Opera Mobile, you need to use max-device-width instead, as max-width uses the width of the virtual viewport).

Here’s a more complicated example containing two media queries—one changes the floats to block display when the width gets down to 480 pixels, and the other removes the image altogether when it gets down to 240 pixels:

body { 
    max-width: 800px; 
    font-family: georgia, serif;
}

img { 
    margin: 0 0 10px 10px; 
    float: right;
}

.info { 
    position: absolute; 
    left: 8000px;
}

@media all and (max-width: 480px) { 
    img { 
        margin: 10px auto;
        float: none; 
        display: block;
    }
}

@media all and (max-width: 240px) { 
    img { display: none; }
    .info { position: static; }
}

See this example of a media query in action —watch what happens to the images as you resize your browser window. David Storey has another media query example that adjusts the width of image for the browser window.

Text shadows

Applying drop shadows to text used to mean serving the text as an image and messing about with the positioning, but that’s no longer the case: the creators of CSS3 have introduced a nice easy property to do it all for you called text-shadow. As you will see below, this makes shadows easy to control. The CSS for the example I’ll display in this section looks like so:

body { 
    max-width: 800px; 
    font-family: georgia, serif;
}

h1 { text-shadow: #555 3px 3px 4px; }

h2 { text-shadow: #f00 0px -5px 10px; }

a { 
    font-size: 120%; 
    text-shadow: #555 2px 2px 0px; 
    border: 1px solid black;
}

p.shadow { 
    color: #ccc; 
    text-decoration: bold; 
    text-shadow: #000 2px 2px 2px;
}

In the text-shadow property, the values from left to right set the colour of the shadow, the left/right and top/bottom offsets of the shadow (negative values move the shadow left/up, and positive values move the shadow right/down), and the amount of blurring for the shadow. Check out the drop shadow example to see what effects the CSS has. The HTML doesn’t contain anything special—just a level 1 and level 2 heading, some text, a preformatted code section, and a link.

In Opera Presto 2.1 you can also make use of multiple text shadows, like so:

text-shadow: 0 0 4px white, 0 -5px 4px #ff3, 2px -10px 6px #fd3, -2px -15px 11px #f80, 2px -25px 18px #f20;

You just chain the different shadows together inside a single CSS property, delimiting them using commas.

This text has the shadow applied! Cool huh?

If you want to know more, visit the CSS3 spec.

Background sizing

There are many different screen resolutions in the world, and it can be hard to create graphics so that they work nicely across all those different resolutions—your lovely designs can be broken if you’re not careful, and don’t give this fact enough forethought. There are ways to bullet-proof things like rounded corner boxes and background repeated images, but they are sometimes tricky.

Check out this single column example. This is a simple single column—a heading and a paragraph inside a div, with a background graphic repeated vertically. The CSS looks like this:

div {
  background-image: url(bkgd_col.png);
  background-repeat: repeat-y;
  border: 1px solid #466900;
}

h1 {
font: Georgia, "Times New Roman", Times, serif;
margin: 0;
background: url(transparency.png);
 padding: 0 50px;
 font-style: italic;
 color: #F1921A;

}

p {
  font-family: Verdana, Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
  padding: 0 50px;
}

p+p {
  margin-top: 1em;
}

the trouble is that the text breaks out of the column after the viewport gets any wider than about 400 pixels. You could fix this by setting the max-width value to 400 pixels, but wouldn’t it be nice if the image just scaled with the paragraph width increase? CSS provides a way to do this—background size. If you add a -o-background-size declaration to the div rule, you’ll end up with this background sizing example.

We've added the rule -o-background-size: 100% auto; . The first value is the x value, and the second is the y value. This example says "always make the image expand to 100% of the container width". If there is only one value specified, it is applied to both the width and height. The background-size property accepts percentage and length values as well as auto, which preserves the aspect ratio.

Opera uses an experimental version of this, hence the -o- prefix. Webkit and KHTML also have experimental implementations (using their -webkit- and -khtml- prefixes) so to ensure maximum compatibility for now, add multiple rules to your page with the different prefixes on them.

Opacity

CSS 3 opacity is very easy to use—all you need to do is add an opacity proprety to your rule, with a single value to specify the opacity of the element(s) you are selecting. For example:

div { opacity: .7; }

Check out this opacity example, which shows a semi-transparent block laid over the rest of the page. The Opera Developer Network article CSS and opacity: methods for creating translucent elements has worked examples of using the opacity property in the real world.

HSL

CSS 3 allows you to specify colours as HSL (or Hue, Saturation, Lightness) values. HSL colours overcome some of the limitations of RGB colours such as being difficult to predict how to change the colour. HSL colours are specified like so:

div { background-color: hsl(240, 100%, 50%); }

It is also easy to convert RGB colours into HSL. Check out the CSS 3 color module for more details on this. By way of an example, I’ve rewritten the opacity example using HSL colour. In this version the absolutely positioned block’s background colour is set using an HSL value, and a lighter paragraph is added, which simply has the lightness values increased to create a ligher shade. To change the colour, you can change the hue value.

overflow-x and overflow-y

these properties allow you to control how children will behave when they flow out of their containing parent box; overflow-x controls overflow out of the right and left, and overflow-y controls overflow out of the top and bottom. The possible values of these properties are as follows:

  • visible: The child content will flow beyond the edge of the containing parent.
  • hidden: Only the child content that can naturally be displayed edge within the confines of the containing parent is visible.
  • scroll: This creates the same effect as hidden, with the addition of scroll bars to allow you to scroll to see the rest of the content.
  • auto: Similar to scroll, but scroll bars are only shown when necessary.
  • no-display: If the child content flows over the edge of the containing parent, the whole lot is removed, as if display: none were specified.
  • no-content: If the child content flows over the edge of the containing parent, the whole lot is hidden, as if visibility: hidden were specified.

Note that you can also set a property called just overflow, which acts as shorthand for overflow-x and overflow-y. See the CSS 3 box model specification for more details and some examples.

nav-index, nav-up, nav-down, nav-left and nav-right

These properties allow you to specify which element will be given focus when the user presses navigation keys on the keyboard, for any element you like (ie, you might want focus to be able to move from a central element only to the four elements that immediately surround it, using the keyboard). The spec doesn’t define what key to use for each, but suggests the direction arrows should be used by user agents, and that they should provide a means to left users set their own custom keys. Opera actually uses this for spatial navigation—it’s used by pressing Shift + the arrow keys on the desktop browser.

These properties are especially useful when absolute positioning is used and the elements may not be displayed in source order. Check out the CSS 3 UI module for more information and an example.

The first-of-type selector

A popular way to add drop caps is to put a span around the first letter, or add a class to the paragraph you want to add the drop cap to and use the ::firstletter pseudo-element to manipulate the drop cap (the class is needed as it isn’t always predictable where the element will be in the code; there could be a image or a list before the first paragraph for example, which could throw things off.) But no more do we have to suffer this hassle—you can now create a drop cap (among many other things) with the first-of-type selector.

Check out the following code:

div.article > p:firstof-type::firstletter { }

This selects the first letter of the first p element that is a direct child of the div element with a class of article. If there are any other elements before the first paragraph of the article, the correct element will still be selected. It ignores any paragraphs that are not a direct descendent, such as those contained in div elements. This can be seen in this drop caps example.

The nth child/nth-of-type selector

Alternating the background colour of the rows in a data table has been a popular usability technique for a few years now—it allows the eye to follow the rows more easily. This traditionally required JavaScript or adding a class name to each row that needed to be styled with the alternative colour, but no more! This can now be done with nth-child (or nth-of-type).

In the following example (nth-child example in action) the striped effect can be created by simply using:

#playlist tr:nthchild(odd) td {  background-color: #edf3fe; }

Alternatively nth-child(even) could have been used. You can have exact control over which element is selected, by specifying the element number, the repeating pattern you want and/or the element offset value. For example, tr:nthchild(2) would specify the second row only, tr:nthchild(3n) would select every third row, while tr:nthchild(3n+1) would select every third row offset by one.

The Opera Developer Network article Zebra striping tables with CSS 3 has more information on this technique.

Form pseudo-classes

You can now use pseudo-classes to select specific form elements in different states, such as :disabled , :enabled, etc., which allows for usability advantages like greying out disabled form fields or highlighting checked boxes.

For example, you can write rules such as

input:disabled  {background:gray } 
input:checked {background-color:yellow;}

Read this article for more on styling form elements with form pseudo-classes.

Other CSS 3 selectors

There are many other CSS 3 selectors available—check out the CSS 3 selectors spec for more about them.

XML and XSLT

Opera Presto 2.1 features a fast, streamlined XML and XSLT processor, which boasts full support for XSLT 1.0, XPath 1.0, XML events, XML namespaces and the xml:id and xml:base attributes. Read more about Opera Presto 2.1’s XML support.

HTML 5

HTML 5 is the next generation of HTML language, currently in working draft form—it aims to improve on the semantics of HTML 4, get rid of some of its ambiguities, and provide a better language for creating modern applications. After all, HTML was never originally intended for creating dynamic web applications—it was originally intended for static documents.

In addition, HTML is under threat of being usurped from its position as "language of the Web" by proprietary technologies. In order for HTML to stay competitive with proprietary technologies and to keep the Web open, it needs new functionality and even better interoperability between the various browser vendors. HTML 5 adds new functionality and provides browser vendors with watertight definitions to follow.

Opera Presto 2.1 supports some proposed HTML 5 features. In this section I will look at some of those features, along with some examples.

Web Forms 2.0

Web Forms 2.0 go a long way towards improving the usability, simplicity and robustness of HTML forms—the semantics are better, they are easier to style, and some stuff that used to require scripting has been handled by some special built-in attributes. Let’s look at some examples.

Validation can now be handled automatically using specialist attributes. Take a look at the following:

<form>
 <p><label>Name: <input name="name" required="required"></label></p>
 <p><label>E-mail: <input name="email" type="email" required="required"></label></p>
 <p><label>URL: <input name="url" type="url"></label></p>
 <p><label>Comment: <textarea name="comment" required="required"></textarea></p>
 <p><input type="submit" value="React!"></p>
</form>

This is very logical, even to a developer who has never seen HTML 5 before—the url, email etc keywords dictate what type of string should be entered for the field to validate, and the required keyword specifies whether the field should be mandatory or not.

Styling form controls is now easier using the new pseudo-classes recognised in HTML 5—for example:

input:required { background:yellow; }

You can do the same type of thing for the default submit button, read-only controls, like this:

input[type=button]:default {border-width:1px; }
input:readonly {border-width:2px; border-color:ff000; }

Combo boxes are now a lot more logical to create. An HTML 5 combo box looks like this:

<input list="drinks" name="drinks">
<datalist id="drinks">
  <option value="Tea"></option>
  <option value="Coffee"></option>
  <option value="Beer"></option>
  <option value="Smoothie"></option>
  <option value="Water"></option>
</datalist>

It will degrade to a commmon text field in browsers that do not support HTML 5, but in ones that do, it will allow the user to choose the options in a drop down box or enter their own value—click into the input field in this Web Forms 2.0 combo box example.

The last thing I’ll cover is giving auto focus to a certain form element. Whereas before this required scripting, in HTML 5 you can just put an autofocus attribute on to the form element you want to give focus to first, eg <input name=search autofocus>.

for more, check out this Web Forms 2.0 tutorial site from Olav Junker Kjaer, and these Web Forms 2.0 examples by Shwetank Dixit.

Server-sent events

Traditional Ajax applications tend to involve the clients putting a lot of strain on the server by continuously polling it. Server-sent events provide a mechanism by which you can continuously push events from server to client via a persistent connection, which reduces the load, and still allows instant feedback to the user. This type of interaction has been done by various different means over the years under the umbrella term "Comet"; Comet methods have traditionally had many issues however, and server-sent events aim to solve some of those issues. For more about Comet, check out the Comet Daily site here, or this very informative Comet presentation by Simon Willison.

Arve Bersvendsen has written more about the Opera Presto 2.1 Server-sent events implementation plus a cool example. Bear in mind that the spec actually changed after we implemented Server-sent events (event-source); we will update our implementation when the specification is finalised.

Canvas

HTML 5 canvas is a drawing API that uses a special HTML element to define a drawing area, and scripting to draw graphics inside that area. Creating a canvas requires you to use the <canvas>—simple as that:

<canvas id="example" width="260" height="200">
There is supposed to be an example drawing here, but it's not important.
</canvas>

The id is used as a hook for the script to identify the canvas and draw something inside it, the width and height simply define the size of the canvas area, and the text inbetween the tags specifies a fallback message to display in case the canvas doesn’t work in the browser viewing the page (you could specify a static image too if you wished). To actually draw something inside the canvas, you need to use script, as shown in the following example:

<html>
  <head>
    <title>HTML 5 Canvas example</title>
    <script>
      function drawPicture(){
        var canvas = document.getElementById('example');
        
        var context = canvas.getContext('2d');
        
        context.fillStyle = "rgb(0,255,0)";
        context.fillRect (25, 25, 100, 100);
        
        context.fillStyle = "rgba(255,0,0, 0.6)";
        context.beginPath();
        context.arc(125,100,50,0,Math.PI*2,true);
        context.fill();
        
        context.fillStyle = "rgba(0,0,255,0.6)";
        context.beginPath();
        context.moveTo(125,100);
        context.lineTo(175,50);
        context.lineTo(225,150);
        context.fill();
        
      }
    </script>
    <style type="text/css">
      canvas { border: 2px solid black; }
    </style>
  </head>
  <body onload="drawPicture();">
    <canvas id="example" width="260" height="200">
    There is supposed to be an example drawing here, but it's not important.
    </canvas>
  </body>
</html>

View the basic canvas example.

The getContext() Canvas DOM method is used to get the context (in this case it’s 2D), and the two lines below it are fairly self explanatory—the fillStyle method specifies what color the shape I’m going to draw will be, using an rgb value (you could also use hex values or colour keywords, and you can also specify rgba values to include opacity too, as I’ve done with the other two shapes.) The fillRect method specifies a filled rectangle to be filled with that colour—the parameters from left to right are x and y coordinates relative to the origin 0,0 (the top left hand corner of the canvas), and the width and height of the rectangle.

The rectangle is the only shape primitive specified by the Canvas API however—other similar shapes have to be drawn using curves and lines, which is what I have done for the circle and the triangle. In each case, I set the fill colour, including opacity this time, specify that I’m beginning to draw a shape using beginPath(), draw the shape I want, then use fill() to close the shape and fill it. The other methods are as follows:

  • arc(): Draws a circle, or part of a circle. The parameters (L-R) are the x and y coordinates or the centre of the arc, the arc’s radius, the start and end angles of the arc, and a boolean value to specify whether the arc should be drawn clockwise (false) or anticlockwise (true).
  • moveTo(): Moves the pen to the specified x and y coordinates.
  • lineTo(): Draws a line from where the pen is currently positioned, to a new position specified by the x and y coordinates.

Canvas also allows manipulation of images, transformations, composition, animation, and all manner of other wonderful things.

You can find a very interesting Canvas example that uses physics simulation and animation, and some nice examples of Canvas colour manipulation.

Cross document messaging

Cross document messaging is an HTML feature that allows you to easily send messages between web pages that are hosted on different domains.

getElementsByClassName

At last, that DOM method we’ve all been waiting for has been introduced in HTML 5. Most JavaScript libraries now implement a shorthand command that does something similar, but it is nice to be able to do it natively.

SVG

SVG (Scalable Vector Graphics) is a web standard for representing vector graphics in markup—it is a fantastic technology, which, in conjunction with other web standards, provides you with mechanisms for creating shapes, animation, text user interaction and more. In fact, it can give Flash a run for its money, and it’s all open. Currently Opera leads the way in terms of SVG support, with Safari/WebKit following, and then Firefox a bit further behind them. We can only hope that other major browsers will follow suit soon (we’re looking at you, Internet Explorer.)

Presto 2.1 supports a pretty complete set of SVG 1.1 features (with a few minor exceptions). In addition, it supports some features of SVG 1.2—such as SVG 1.2 Tiny’s vector effects (eg non-scaling stroke), keyboard navigation, handler, and editable text as seen in the examples below. Check out the SVG Tiny 1.2 spec for more details.

With the pleasantries out of the way, let’s go on to look at some SVG examples.

Decorating your pages using SVG backgrounds

A very nice feature in Opera Presto 2.1 is the ability to use a SVG image as the source of an img element, or even add SVG to a page with CSS using the background-image and list-style-image properties, just like you would regular images. Try this out yourself!

Because SVG is fully scriptable, you can have all kinds of fascinating background animations, without having to resort to Flash or lots of complicated code.

SVG for text

SVG has all the functionality you’d ever need for creating rich internet applications, complete with great looking form fields for entering data. You can easily create simple form fields like so:

This requires the following simple code:

  <rect x="0" y="0" width="100%" height="100%" fill="#87ceeb">
      <title>background rectangle</title>
   </rect>

   <g id="nameInput" transform="scale(4) translate(50, 20)">
      <text x="0" y="20" font-size="18" font-family="Arial, sans-serif" fill="#000080">Name:</text>
      <rect x="0" y="25" width="156" height="26" rx="3" ry="3"
         fill="white" stroke-width="2" stroke="#000080"/>
      <textArea x="3" y="27" width="150" height="20" font-size="18" font-family="Arial, sans-serif"
         editable="simple" focusable="true" pointer-events="boundingBox">John Doe</textArea>
   </g>

Or go a bit crazy, like this (check out the crazy SVG text field example then view source to check out the source code):

SVG Animation and image manipulation

Again, SVG is full equipped for animation/image manipulation. You can include images in an SVG file easily enough, draw complex shapes with SVG, or even include SVG files inside the HTML 5 Canvas, as shown in this Image resizing example from Erik Dahlström. You simply pass an Image object to drawImage that points to an SVG file.

I just had to include this time travel animation example, again from Erik. As Erik explains on his blog, this currently tends to freeze Safari and Firefox, so only an image is included below. This makes use of SVG animation, and the FakeSMILe (partial javascript implementation of SMIL) library for browsers with less advanced SVG supportext1.svgt than Opera Presto 2.1 offers. Check out the source of this example—it is amazing how litle script is needed for this animation, compared to how much it would be to do it in JavaScript alone.

image of Erik Ds time travel SVG example

SVG animate motion

I can however include Erik’s example showing how to create an advanced SVG menu using opacity, matrices, and other cool effects:

fall back image for SVG menu

Also check out the dev.opera.com SVG tutorials showing an SVG Image gallery by Jeff Schiller, and an SVG darts game by Ruud Steltenpool. Carto.net is also worth checking out, for SVG maps.

You can find more SVG tutorials on the SVG tutorial page at dev.opera.com, and a Presto 2.1 SVG support reference.

WAI-ARIA

WAI-ARIA (the Accessible Rich Internet Applications Suite) is a W3C specification that aims to define how to make Rich Internet Application technologies such as Ajax accessible, by filling in the accessibility gaps in the Ajax model. Opera Presto 2.1 experimentally supports an ARIA implementation, but the specification is still changing.

The Opera Developer Network has a comprehensive Introduction to WAI ARIA showing what the technology is and how it is used.

Opera Widgets

Opera Widgets are applications written using Web standards, which are specially packaged and run on the desktop. They have their own security model, can be run across different platforms and devices (including mobile devices) and have some exciting features available such as the Opera Widget API, which allows all manner of useful new widget manipulation.

You can download a large amount of Opera widgets from widgets.opera.com; to find out more about how to develop widgets, visit the wealth of information available at the Opera Widgets SDK.

Opera’s developer tools

The Scope module and Opera Dragonfly

Many implementations of Opera Presto 2.1 come with the Scope API, which can be enabled on a product-by-product basis. This can hook up to a desktop computer running Opera Dragonfly, our tool which allows developers to remotely debug devices (typing test data directly into devices can be horrible) as well as debug CSS and JavaScript in the page.

Summary

So that’s a wrap—the end of my summary of Opera Presto 2.1 ’s standards support and Opera’s overall commitment to the Web standards movement.

This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.