Web Platform Team Blog

Adobe

decor

Making the web awesome

Welcoming Sylvain, Alexis & Julee to our team!

Recently we have had 3 new additions to our team! Please welcome Sylvain, Alexis & Julee to our team!

Sylvain Galineau

Sylvain is not just new to our team but also to Adobe! Sylvain previously worked at Microsoft, & is a connoisseur of fine wine & food. He is French after all.

Alexis Deveria

Alexis has been working at Adobe for more than a year, but will now pick up his pixel hacker hat again which means he will be one of the leading consumers of his own website: caniuse.com

Julee Burdekin

Julee has been shepherding the content creation over at Web Platform Docs, which she will continue doing, except only now you will see more blog posts from her on this blog :)

Please do send in your warm welcome to our new team members!

Penetrating Polygons Explained

Hans Muller has another great blog post focusing on his work implementing the shape-inside feature from the CSS Exclusions and Shapes specification. In this installment, Hans explains how he calculates the shape-inside that corresponds to a polygon penetrating an HTML element’s content box.

penetrating_polygon

Read all about how the algorithm works and play with Hans’s interactive demo to help visualize the functionality. Don’t miss the short video of Hans’s cat-on-a-ladder-turning-on-a-light demo at the bottom of the post.

Building a Better Web Through Crowd Sourcing

In case you hadn’t heard, the SFHTML5 Meetup group will be hosting a meetup on April 25th 2013 focused on making the Web better via crowd sourcing testing.

Rebecca Hauck will talk to us about Test the Web Forward a community-based grass roots movement with the goal of improving the quality of the Web by fostering knowledge to write high quality tests for W3C specifications.

John Hammink will be teaching us about the crowd sourcing testing that is happening around Firefox OS and the related challenges.

Sign up on the SFHTML5 Meetup page and see you on April 25th!

Hope to see you there!

Freeing the Floats of the Future From the Tyranny of the Rectangle

With modern web layout you can have your content laid out in whatever shape you want as long as it’s a rectangle. Designers in other media have long been able to have text and other content lay out inside and around arbitrarily complex shapes. The CSS Exclusions and Shapes specification aims to bring this capability to the web.

While these features aren’t widely available yet, implementation is progressing and it’s already possible to try out some of the features yourself. Internet Explorer 10 has an implementation of the exclusions processing model, so you can try out exclusions in IE 10 today.

At Adobe we have been focusing on implementing the shapes portion of the specification. We began with an implementation of shape-inside and now have a working implementation of the shape-outside property on floats. We have been building our implementation in WebKit, so the easiest way to try it out yourself is to download a copy of Chrome Canary. Once you have Canary, enable Experimental WebKit Features and go wild!

What is shape-outside?

“Now hold up there,” you may be thinking, “I don’t even know what a shape-outside is and you want me to read this crazy incomprehensible specification thing to know what it is!?!”

Well you’ll be happy to know that it really isn’t that complex, especially in the case of floats. When an element is floated, inline content avoids the floated element. Content flows around the margin box of the element as defined by the CSS box model. The shape-outside CSS property allows you to tell the browser to use a specified shape instead of the margin box when wrapping content around the floating element.

CSS Exclusions

The current implementation allows for rectangles, rounded rectangles, circles, ellipses, and polygons. While this gives a lot of flexibility, eventually you will be able to use a SVG path or the alpha channel of an image to make it easier to create complex shapes.

How do I use it?

First, you need to get a copy of Chrome Canary and then enable Experimental WebKit features. Once you have that, load up this post in Chrome Canary so that you can click on the images below to see a live example of the code. Even better, the examples are on Codepen, so you can and should play with them yourself and see what interesting things you can come up with.

Note that in this post and the examples I use the unprefixed shape-outside property.
If you want to test these examples outside of my Codepen then you will need to use the prefixed -webkit-shape-outside property or use (which is a built in option in Codepen).

We’ll start with a HTML document with some content and a float. Currently shape-outside only works on floating elements, so those are the ones to concentrate on. For example: (click on the image to see the code)

HTML without shape-outside

You can now add the shape-outside property to the style for your floats.

.float {
  shape-outside: circle(50%, 50%, 50%);
}

A circle is much more interesting than a standard rectangle, don’t you think? This circle is centered in the middle of the float and has a radius that is half the width of the float. The effect on the layout is something like this:

shape-outside circle

While percentages were used for this circle, you can use any CSS unit you like to specify the shape. All of the relative units are relative to the dimensions of element where the shape-outside is specified.

Supported shapes

Circles are cool and all, but I promised you other shapes, and I will deliver. There are four types of shapes that are supported by the current shape-outside implementation: rectangle, circle, ellipse, and polygon.

rectangle

You have the ability to specify a shape-outside that is a fairly standard rectangle:

shape-outside: rectangle(x, y, width, height);

The x and y parameters specify the coordinates of the top-left corner of the rectangle. This coordinate is in relation to the top-left corner of the floating element’s content box. Because of the way this interacts with the rules of float positioning, setting these to anything other than 0 causes an effect that is similar to relatively positioning the float’s content. (Explaining this is beyond the scope of this post.)

The width and height parameters should be self-explanatory: they are the width and height of the resulting rectangle.

Where things get interesting is with the six-argument form of rectangle:

shape-outside: rectangle(x, y, width, height, rx, ry);

The first four arguments are the same as explained above, but the last two specify corner radii in the horizontal (rx) and vertical (ry) directions. This not only allows the creation of rounded rectangles, you can create circles and ellipses as well. (Just like with [border-radius][border-radius].)

Here’s an example of a rectangle, a rounded rectangle, a circle, and an ellipse using just rectangle syntax:

shape-outside rectangle

If you’re reading this in Chrome Canary with exclusions turned on, play around with this demo and see what other things you can do with the rectangles.

circle

I already showed you a simple circle demo and you’ll be happy to know that’s pretty much all there is to know about circles:

shape-outside: circle(cx, cy, radius);

The cx and cy parameters specify the coordinates of the center of the circle. In most situations you’ll want to put them at the center of your box. Just like with rectangles moving this around can be useful, but it behaves similarly to relatively positioning the float’s content with respect to the shape.

The radius parameter is the radius of the resulting circle.

In case you’d like to see it again, here’s what a circle looks like:

shape-outside circle

While it is possible to create circles with rounded rectangles as described above, having a dedicated circle shape is much more convenient.

ellipse

Sometimes, you need to squish your circles and that’s where the ellipse comes in handy.

shape-outside: ellipse(cx, cy, rx, ry);

Just like a circle, an ellipse has cx and cy to specify the coordinates of its center and you will likely want to have them at the center of your float. And just like all the previous shapes, changing these around will cause the float’s content to position relative to your shape.

The rx and ry parameters will look familiar from the rounded rectangle case and they are exactly what you would expect: the horizontal and vertical radii of the ellipse.

Ellipses can be used to create circles (rx = ry) and rounded rectangles can be used to create ellipses, but it’s best to use the shape that directly suits your purpose. It’s much easier to read and maintain that way.

Here’s an example of using an ellipse shape:

shape-outside ellipse

polygon

Now here’s where things get really interesting. The polygon `shape-outside` allows you to specify an arbitrary polygonal shape for your float:

shape-outside: polygon(x1 y1, x2 y2, ... , xn yn);

The parameters of the polygon are the x and y coordinates of each vertex of the shape. You can have as many vertices as you would like.

Here’s an example of a simple polygon:

shape-outside triangle

Feel free to play with this and see what happens if you create more interesting shapes!

Putting content in the float

The previous examples all had divs without any content just to make it easier to read and understand the code, but a big motivation for shape-outside is to wrap around other content. Interesting layouts often involve wrapping text around images as this final example shows:

shape-outside with images

As usual, you should take a look and play with the code for this example of text wrapping around floated images. This is just the beginning of the possibilities, as you can put a shape outside on any floating element with any content you want inside.

Next steps

We are still hard at work on fixing bugs in the current implementation and implementing the rest of the features in the CSS Exclusions and Shapes specification. We welcome your feedback on what is already implemented and also on the spec itself. If you are interested in becoming part of the process, you can raise issues with the current WebKit implementation by filing bugs in the WebKit bugzilla. If you have issues with the spec, those are best raised on the www-style mailing list. And of course, you can leave your feedback as comments on this post.

I hope that you enjoy experimenting with shape-outside and the other features we are currently working on.

Test the Web Forward Seattle!

Test the Web Forward Seattle!

Come Join Us!

Test the Web Forward is throwing an event in Seattle on April 12–13. The focus of this event is on learning, hacking, and writing tests for W3C specifications. During the event, experts will teach you about W3C specs & W3C testing and will guide you as you help make the Web a better, more interoperable place.

The Experts and Speakers will be posted shortly on the Test the Web Forward website.

Also, follow us on @testthewebfwd for updates and be sure to sign up for the W3C Test the Web Forward mail list.

To learn more about the past events, check out our posts on Test the Web Forward ParisBeijing and San Francisco.

Get Registered

Registration is now open on Eventbrite, so get signed up! Help make the Web a better place!

Can’t make it?

Hey, if you are busy or can’t make it for any reason, it is a bummer, but be sure to sign up for the W3C Test the Web Forward mail list so that you learn about future happenings!

Regions feature support matrix revisited – keeping it clean

Welcome to the Real World™

A while ago, I wrote a blog post on how we used Browserscope to create a feature support matrix for tracking the level of support for CSS Regions in different browsers. The initial plan was to have both the feature detection tests and the submission mechanism available to the public so that anyone could run the tests and submit their results.

Fast-forward a couple of months and the initial plan didn’t seem to hold very well to the rigors of the real life Internet: submissions for irrelevant browsers (like the one running on Nokia 72), false negatives on supported browsers (as the feature is under a runtime flag), or plain empty results as people used our test key for personal experimentation. In this context it became apparent we needed to revise both the process and the data we were exposing.

Fixing the process

Revising the process was fairly easy. We just moved the code responsible for the results submission on an internal server, while leaving all the other bits for running the tests and viewing the aggregated results in place.

The tricky part was cleaning up the existing data without re-running the tests on the whole list of browsers – some of which already unavailable due to the fast-paced release cycle of modern browsers.

Fixing the data

The reasons we initially chose Browserscope for the feature support matrix was that it did almost all the heavy lifting for us: user-agent parsing, results storage and aggregation, all through a very simple API. The downside however, was that one has almost no control over the data once it got inside Browserscope. The only exposed operations are reordering or removing test categories (basically, columns from the results table).

Browserscope’s way of keeping the results relevant – in spite of the unavoidable mis-reports – resides in the large number of results submitted, as the suites are usually public. For abuse protection they’re capping the number of results pushed from any given IP address and protection against outliers is provided by the statistical processing of the results submitted.

In our case, given that WebKit nightly is by no means a mainstream browser and Chrome has the regions implementation under a run-time flag meant that we were more likely to get inaccurate results as more people run the tests. So besides “hiding” the submit code from the general public, we also had to clean-up the results ourselves.

The main challenge was removing irrelevant browsers from the results list (basically, rows from the results table) – there’s simply no nice way to trick the system. You could hack your way around it by manually listing the user agent strings you want to see/aggregate over. But that involves updating the list every time you land some results with a new user agent. Ugh!

Delete as selective copy

Instead of actually deleting results, we resorted to creating a new results table – one that would contain only the relevant results/browsers. Once the copy would be complete, we would start using that table further on.

However, what started as an “I know, I’ll use Python” moment, turned to bitter reconsideration once I realised that:

  1. currently there’s no way to retrieve all the test results in a machine-friendly format, like CSV;
  2. Browserscope relies solely on the User-agent HTTP header to aggregate results, so I had to use some API that would allow me to fiddle with that header, too;
  3. and last, but not least: the “API” for submitting the results relies on executing some JavaScript code from the Browserscope server that has, among other things, some CSRF protection magic. So I actually had to execute that code in a real JavaScript environment – which actually limited my options quite a bit.

Most of the things above were things that I knew in a corner of my mind, but only became apparent at a closer inspection of the problem.
What I needed was basically an environment where I could

  1. retrieve some HTML, scraping it for useful data
  2. filter said data and then
  3. execute some JavaScript in a browser-like environment whose user-agent string I could change at will.

After a short initial panic moment :) I realized a platform that would allow me to do all those things actually exists, and I’m actually familiar with it, being an Adobe-built technology. This technology is Adobe AIR. One of the cool things about AIR is that it embeds a WebKit port, allowing developers to write desktop apps using just HTML/CSS and JavaScript.

HTMLLoader to the rescue

Browserscope submitter

Armed with this new-found hope, I created a helper app (pictured above) that does just a little more than the three steps I previously listed as requirements for the solution. More specifically:

  • it takes as input: the key of the source results table, the maximum number of results to fetch, the key of the destination results table and the sandbox ID for the destination table
    • the sandbox ID is required to bypass the per-IP cap on results submissions, since most probably we’re gonna submit a lot of results in a short period of time from the same IP
  • based on the key of the source table it fetches its raw (not aggregated) contents, nicely formatted as HTML (something like this). This is done via an AJAX call and the response is parsed using jQuery, extracting the list of tests and the individual test results
  • based on the list of tests and the individual results previously extracted, an interactive table is displayed that allows excluding irrelevant results
  • the non-excluded results are submitted to Browserscope using the AIR-specific air.HTMLLoader object
    • for each result, the userAgent property of an HTMLLoader object is set to the user-agent string reported by the browser that submitted the result and then, using the loadString() method, a small piece of JavaScript is injected and executed that does the actual result submission
    • results are submitted one-by-one, asynchronously, using a pool of HTMLLoader instances

Wrapping it up

Now that the cleanup is completed, you can see what CSS Regions features are supported in which browsers and run the tests yourself, over on our gitHub page, just as before.

If there’s one important thing this clean-up/refactor taught me, is that when you know you’re (ab)using a technology, you’d better be prepared for the moment you’ll hit the hard wall of limitations you knew existed from the very beginning. And also, as long as it gets the job done, no technology should be discarded just because it doesn’t seem appropriate. Oh, and most of the times, the path you already know is usually the shortest.

W3Conf 2013: A Summary

The Adobe Web Platform team helped in organizing the W3Conf at the beautiful Regency Center in San Francisco on 21-22nd Feb 2013. Here are some notes from my perch behind the curtains (I was introducing the speakers!).

By all standards, the conference was a great success. Here are some metrics:

  1. We had about 20,000 viewers watching the conference live in total (there were on an average about 300 viewers watching every second of it).
  2. About 1,500 people tweeted about the conference. Notably, Faruk Ateş and Kevin Marks were live-tweeting the event.
  3. 300 people attended the event (including Tim Berners-Lee) in total. Chris Coyier live-blogged day 2 of the event.

What was talked about?

Speakers such as Joshua Davis, Eric Meyer, Lea Verou, Brad Hill, Vicki Murley, Leoni Watson (and more!), gave excellent talks on various aspects of Open Web technologies, including CSS, SVG, Accessibility, Security, and Performance. All the talks are archived on the W3Conf Youtube Channel.

We also had Alexis, Alex, and CJ from our team speaking about various aspects of the web:

Opportunities to Contribute

Larry McLister & Rebecca Hauck from our team were at the event speaking to the participants about Test the Web Forward and Webplatform.org efforts. We had about 100 people registering their interest in participating in Test the Web Forward events (you can too, just subscribe to this mailing list)

Thanks

It would be insane not to thank the valiant and super human efforts of Susan Parini, Marie Nedich, and Liz Arroyove-Federick who took care of all the logistics and the W3C for letting us be the host of this year’s event.

Wait, there is more!

We also had 2 other events that occurred just after the W3Conf: A workshop by Joshua Davis on using SVG with Processing for creative coding, and a Docsprint to add more exhaustive references to webplatform.org.

You can work through the files from Joshua Davis’s workshop.

Join us

We are participating in many more events, and we would love to have you join us at more events.

“The Making of CSSFilterLab” at W3Conf 2013

Link to the CSS FilterLab Presentation - W3Conf 2013

I had the honor to speak at the W3Conf 2013 last week. My talk was about a fork of CSS FilterLab that I’ve been working on recently. The project is written entirely in JavaScript, CSS and HTML and targets mobile devices with touch based interfaces. In order to work with all the touch API, I had to implement a framework that I’ve later reused to create the slides. Yes, the slides are also using HTML5 and the presentation was given on a tablet device. I’ve also covered the performance problems I had while porting to mobile and the workarounds I used in CSS FilterLab.

The talk was recorded and is embedded below. The source code for the slides are available on my GitHub account and you can also browse the slides online. Make sure you use left/right on your keyboard to navigate or swipe to advance to the next slide.

“Do Androids Read Electric Books?” at W3Conf 2013

Screen-Shot-2013-03-05-at-1.27.58-PM

I was fortunate to have the opportunity to speak at W3Conf in San Francisco this year. My talk was about reading experiences on the web, ways we can improve them and where we see this going in the future. In the talk I show off how we can use Regions for visually stunning magazine layout and responsive pagination. There are also some examples of Exclusions being used in creative designs for web based children’s books/games or responsive comic books. You can view the video of my talk below and find the slides on github along with the source. Be sure to check out all the other amazing speakers from the conference as well.

“The top web features from caniuse.com you can use today”

First slide of W3Conf slideshowAt the 2013 W3Conf I gave a talk about the browser compatibility site Caniuse.com. The talk consisted of two parts, starting with an explanation of how caniuse.com started, how it’s useful to developers, and what’s to come on the site. The next and larger part discusses top web features now supported by enough browsers that you can safely start using them without worry or guilt. Features include CSS Tables, Pseudo-element & generated content, CSS counters, CSS outline, sessionStorage & localStorage, hashChange event, text-overflow, and Data URIs. Lesser supported but related features are also addressed.

The talk was recorded (together with all other W3Conf talks) and can be viewed here: