Opera 9.5 - the next generation of web standards
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
Another exciting time dawns upon us for the advancement of web standards, with the release of the final version of Opera 9.5—download Opera 9.5 here. If you’ve been checking out the beta releases, you’ll already have a taste of some of the great new features our new browser brings to the table, such as Opera Quick Find and Opera Link integration, and the final release builds on this. Sure, it’s a great user experience, but what does Opera 9.5 mean for developers? The answer is that Opera is rallying around the web standards flag more than ever before:
- The browser features better standards support than Opera has ever shipped in previous releases—not only does it have very thorough support for current standards like (X)HTML, XML, XSLT, CSS 2.1, SVG 1.1 and JavaScript, but it also includes support for many aspects of nascent standards such as HTML 5 and CSS 3. Testament to this is Opera passing the Acid 1 and 2 tests, and scoring 83% on the Acid 3 test—check the Acid tests out for yourself here.
- As well as providing you with killer standards support, Opera has also created a great new set of developer tools to help you debug your HTML, CSS, and JavaScript—the debugging application is called Opera Dragonfly, and there is also a brand new developer menu available. Check out our Opera Dragonfly page for more information on these.
- Last but not least, Opera will soon be releasing the first part of an education program to help propagate best practices and increase web standards usage on the web. The Opera Web Standards Curriculum will provide a thorough grounding in all the skills you need to be a proficient front end developer, including web background theory, in-depth HTML and CSS, design principles and introductory DOM/JavaScript. Watch this space!
In this article I will look at all of these in more detail, but with a bias towards the standards support in Opera 9.5—for much more on the Opera developer tools and the Opera Web Standards Curriculum, follow the links above. The structure of the article is as follows:
Thanks a lot to everyone who wrote the examples featured below.
Opera 9.5 web standards support
In this section, I will review Opera 9.5’s standards support, going through some of the highlights, and taking you through some examples to show you how the Web of tomorrow is shaping up! It’s going to be a brighter day when tomorrow eventually comes.
For a reference list of the web standards support in Opera 9.5, have a look at our specs support page. The article you are currently reading focuses more on specific practical examples.
(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 nascent ones, which we’ll discuss later. Suffice to say, Opera 9.5 supports the majority of the HTML 4.01 and XHTML 1.1 specifications; Opera 9.5 also supports nearly the whole CSS 2.1 Specification; finally, Opera 9.5 has very thorough support for both ECMAScript/JavaScript and the DOM. We support a decent amount of DOM 3, and the majority of DOM 2.
CSS 3
CSS3 is currently still a nascent technology, with the different parts of its specification at various different stages. Opera 9.5 supports many of the more complete parts of the spec, as explored below.
Media queries
Media queries are a CSS 3 construct, which work in a similar manner to conditional comments, except that these are web standards, rather than proprietary constructs—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 screen size less than 480 pixels"? 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 2 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 media query example in action here. David Storey has another nice media query example located here.
Text shadows
Using drop shadows with text used to mean serving the text as an image, and messing about 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 the drop shadow example out, 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 9.5 (and Konqueror and iCab, but no other browsers), 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 way 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. (Opera is still using 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.)
the rule added to the div is -o-background-size: 100% auto;
—the first value is the x value—ie, "always make the image expand to 100% of the container width—and the second value is the y value. 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.
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.
HSL
CSS 3 allows you to specify colours as HSL (or Hue, Saturation, Lightness) values—this is good, HSL colours overcome some of the limitations of RGB colours (such as being affected by hardware, and being much easier to predict). 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—.
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
: After the point where the child content reaches the edge of the containing parent, it disappears, as if it were being viewed through a window, and disappeared behind the wall at the edge of the window.scroll
: This creates the same effect ashidden
, with the addition of scroll bars to allow you to scroll to see the rest of the content.auto
: Similar toscroll
, 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 ifdisplay: none
were specified.no-content
: If the child content flows over the edge of the containing parent, the whole lot is hidden, as ifvisibility: 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.
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 ::first-letter
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:first-of-type::first-letter { }
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:nth-child(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:nth-child(2)
would specify the second row only, tr:nth-child(3n)
would select every third row, while tr:nth-child(3n+1)
would select every third row offset by one.
Form pseudo-classes
You can now use pseudo-classes to select specific form elements in different states, such as :disabled
, :enabled
etc. Check out 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 9.5 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 attribute. Read more about Opera 9.5’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.x, 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 9.5 is currently the leader in supporting nascent 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 disabled controls, checked checkboxes, the default submit button, read-only controls, like this:
input:disabled{ background:gray; } input:checked+ label { text-decoration:bold; } input[type=button]:default { border-width:1px; } input:readonly { border-width:2px; border-color:ff0000; }
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 you to choose the options in a drop down box as well as entering your own value if wished—check the Web Forms 2.0 example out here.
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 in various different guises over the years , mostly put 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.
More about our Server-sent events implementation plus a cool example is available on Arve Bersvendsen's site. 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 here.
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), which 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 here, and some nice examples of canvas colour manipulation here.
Cross document messaging
Cross document messaging is an HTML feature that allows you to easily send messages between web pages that are sitting 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 commend 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.)
Opera 9.5 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 (such as 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.
See here for some more information on Opera’s SVG support. 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 9.5 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! and of course, because SVG is fully scriptable and can support animations, you could 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. his makes use of SVG animate motion, and the FakeSMILe (partial javascript implementation of SMIL) library. 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.
I can however include Erik’s example showing how to create an advanced SVG menu using opacity, matrices, and other cool effects:
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.
You can find more SVG tutorials on the SVG tutorial page at dev.opera.com. Carto.net is also worth checking out, for SVG maps.
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 9.5 supports the current ARIA implementation.
Wikipedia says, "It allows web pages (or portions of pages) to declare themselves as applications rather than as static documents, by adding role, property, and state information to dynamic web applications. ARIA is intended for use by developers of web applications, browsers (or user agents), assistive technologies (or ATs), and accessibility evaluation tools." (More about WAI-ARIA from Steve Faulkner of Paciello Group)
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 recent move from static web pages to web applications of web applications has greatly increased the complexity of web development: mark-up, CSS and script all interact with each other in ever-more elaborate ways. As Opera is committed to becoming a vital tool in every developer’s armoury, we are releasing a new breed of developer tools to help you testing your web standards work, and debug any problems you may encounter.
Opera Dragonfly
Opera Dragonfly is the centrepiece of Opera’s new developer tools—it is a complete debugging application that features a JavaScript debugger, command line for entering JavaScript commands, DOM and CSS inspector, call stack inspector, error console, optional integration inside the browser window, and much more. You can access Opera Dragonfly in Opera 9.5 by simply selecting the Tools > Advanced > Developer Tools option in the Opera menu bar.
To find out more information about Opera Dragonfly, read the following:
Let us know what you think of Opera Dragonfly at the Opera Dragonfly feedback page.
The Opera Debug Menu
To complement Opera Dragonfly, we’ve also got our own Developer Menu in the works. The goal of this is to bring developer-specific functionality already present in the browser into one place, and further enhance them with some extra features and reference materials. This is currently in alpha stage, but you can try the developer menu out by clicking on this link.
Again, we want you to give us as much feedback as possible on this, as we want to make it as useful for designers and developers as possible.
The Opera Widget Emulator
The Opera Widget Emulator is another useful new tool that Opera has recently created—it allows you to run your Opera Widgets inside a sandbox, emulating them running on a variety of different sizes and with other altered parameters. Basically, it makes it simple to see how your widgets will perform in different environments, such as on small monitors, TVs, or mobile devices.
The application is an Opera widget itself, so is used in just the same way as any other; all you need to do to run your widgets in it is put your widget package inside the widget directory of the emulator, insert a special line of JavaScript into your index.html file, and then save it all and drag the emulator’s config.xml file into the browser to load the emulator. For more information on how to get hold of the Opera Widget Emulator and how to use it, check out this article.
The Opera Mini Simulator
As more and more people check the Web on their phones, it’s a vital part of the QA process to ensure that the Opera Mini phone browser renders your site correctly, so we’ve developed the Opera Mini simulator. This is available on a standard web site located at http://www.opera.com/developer/tools/mini/, and you just use it like you would the real thing.
Summary
So that’s a wrap—the end of my summary of Opera 9.5’s standards support, and Opera’s overall commitment to the web standards movement. Let us know what you think of the new browser, our new wave of developer tools and our educational material.
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.