Name­spaces for Media Features

This is a proposal to extend CSS and HTML to allow applications to define their own media features. Browsers would then provide an API to their extensions and add-ons, allowing them to control the values of those features on a per-tab basis.

This document presents five solutions to a problem faced by this project. Three are considered inadequate, but have been tried with varying degrees of success. One is an improved solution that may be objected to on non-technical grounds. Finally, an ideal solution is presented that would exploit the proposed extension to media features.

Goal

We wanted webmasters to be able to retain in-band navig­ation alongside their sitemaps, for visitors that don’t have browsers capable of viewing the sitemaps. However, visitors that do see the sitemaps don’t want to see the duplicate in-band navig­ation, so we needed a way to switch off the in-band navig­ation while the sitemap is presented.

Furthermore, we wanted to support a scale of display levels, whereby a sitemap isn’t simply displayed or hidden. Instead, there are degrees of availability of the sitemap, and the author may choose to reveal more page content to compensate for gradual unavailability.

Inadequate solutions

Several solutions have been devised and tried with varying success. All have their drawbacks.

Injecting a user stylesheet

Under this solution, the Firefox extension uses part of Firefox’s extension API to control user stylesheets. Again, the user specifies the additional sheet’s URI in the sitemap.

The user agent's burden

The extension must fetch the linked stylesheet, sanitize the content and protect it so that it will only apply to pages on the site, and then use the Stylesheet Service to inject it into the cascade.

The author's burden

The author must write additional styles in a separate file, e.g.:

/* sitemap-styles.css */
#in-band-nav {
  display: none !important;
}

…and link to it in the sitemap:

<sitemap ...>
  <style href="sitemap-styles.css" />
  ...
</sitemap>

Assessment

The main advantage here is that, when navigating within a site (i.e., between two pages declaring the same sitemap), the additional sheet is already in place as you move to the second page. Therefore, there can be no flicker.

However, it has some major flaws:

  • As part of a user stylesheet, the rules appear very early in the cascading order, and so are overridden by later rules, such as the author’s main page styles. The author is forced to work around this by adding !important to the sitemap rules.

  • User stylesheets apply to the whole browser, not just a single tab. Other tabs are therefore polluted with the same styles, even though they are meant to apply to only some tabs. Tabs showing unrelated pages have to be protected by wrapping the author’s styles in @-moz-document url-prefix declarations, which does not necessarily match the author’s definition of what pages belong to a site. Even tabs showing pages in the same site are all forced to show the additional styles, or all to show none, even though some of those tabs may be showing the sidebar while others are not.

  • As with injecting <link rel="stylesheet">, it also requires the author to provide an extra stylesheet, rather than including sitemap styles in existing sheets.

Class injection

This technique allows the author to employ class-based styling, whereby the sitemap add-on makes dynamic changes to the HTML to trigger the author’s CSS to hide the in-band navig­ation.

Under this solution, the author specifies rules in the sitemap directing the add-on to alter the HTML, specifically the classes that apply to a given element. The HTML document does not change structurally, but rather the value of a single attribute is modified, in an author-defined manner.

The user agent's burden

The extension must extract parameters from the <class-change> element in the sitemap, use the XPath expression within it to locate the specified element within the page (usually <body>), parse the space-separated class list in its class attribute, and replace that list with class names of the forms sitemap-over-N and sitemap-under-M.

The author's burden

The author must write additional styles in any sheet that the page uses, with a selector that depends on injected classes, e.g.:

/* sitemap.css */
body.sitemap-over-49 #in-band-nav { display: none; }

/* other styles not related to sitemaps */
...
<html>
  <head>
    ...
    <link rel="stylesheet" href="sitemap.css">
  </head>
  <body>
    ...
  </body>
</html>

…and specify in the sitemap the way to modify each page:

<sitemap ...>
  <class-change
     xmlns:html="http://www.w3.org/1999/xhtml"
     elem="/html:html/html:body"
     attr="class" prefix="sitemap" />
  ...
</sitemap>

Assessment

The main advantage here is that the sitemap styles can be embedded in the author’s existing stylesheets, so he has control over cascading order, and does not need to provide an extra file. The changes also apply to the content of only the relevant tabs. Also, this mechanism was designed from the outset to support multiple display levels.

The main disadvantage is that changes can only be applied some time after loading, with the risk of flicker. In its defence, perhaps because there are no structural changes to the HTML, this occurs fast enough to avoid flicker. However, it may still depend too much on local factors, such as browser efficiency and computer speed.

Improved solutions

Ad-hoc standard­ized media feature

A base set of media features is defined for some media types, and it is observed in many modern browsers that these are effectively variable characteristics of a browser tab that can change dynamically and effect an immediate change in the styles that get applied. For example, an author could have his page use a multi-column layout only if enough horizontal space (say, 60em) is available for it, defaulting to a simpler layout if not:

/* ... single-column layout... */

/* Access the 'width' media feature... */
@media (min-width: 60em) {
  /* ... multi-column layout ... */
}

This technique can also be used in fail-safe manner, as the example shows. That is, if encountered by a browser that does not understand the media feature, all the styles guarded by it are disabled.

We could use this technique to avoid all problems encountered by the other solutions described above, if only we could define a new media feature, say sitemap-presence, whose value is one of the display levels.

The user agent's burden

As a sitemap becomes available or unavailable, or as it is displayed or hidden, the extension must update the current display level for the tab, and report it to the browser with a call such as:

tab.setFeature('sitemap-presence', 67);

The author's burden

The author must write additional styles in any sheet that the page uses, with a selector that depends on the new media feature, e.g.:


@media (min-sitemap-presence: 50) {
  #in-band-nav {
    display: none;
  }
}

Assessment

The two problems here are one of standard­ization, and one of its acceptance by browser implementors. We must persuade standards bodies that sitemap-presence is a generally useful feature, which depends on browser implementors being prepared to agree on it and implement it. Furthermore, the browser implementors must provide a way for the sitemap add-ons to control this new media feature as a variable. (This doesn’t have to be the same across all browsers, as it’s part of the browser/add-on API, which is already browser-specific.) This isn’t going to happen without some prior momentum behind the navig­ational sitemap concept, which isn’t going to exist without at least one working implementation already supporting it; a chicken-and-egg problem.

Ideal solution

Name­spaced media feature

The ideal solution would require a standard­ized extension to HTML and CSS, i.e., support of name­spaces in media-query features.

What if media features were not set in stone, and various, unrelated applications and bodies could devise their own arbitrary media features without further standard­ization and implementation? The usual way to permit this, as seen in XML and CSS, is to allow users to define new name­spaces, identified by URI, and then let the user owning that name­space populate it as he sees fit.

CSS already supports the definition of mappings between local prefixes and global name­space URIs, and these prefixes can then be used on element and attribute names within an XML (or XML-like) document. By allowing such prefixes to be used on media features too, we immediately deal with the standard­ization issue, and have a way to express sitemap styles concisely, and entirely in CSS.

The user agent's burden

As a sitemap becomes available or unavailable, or as it is displayed or hidden, the extension must update the current display level for the tab, and report it to the browser with a call such as:

tab.setFeature('http://standard-sitemap.org/2007/ns', 'presence', 67);

The author's burden

The author must write additional styles in any sheet that the page uses, enclosed in a media query that depends on the current display level, e.g.:

@name­space ssp url(http://standard-sitemap.org/2007/ns);

@media (ssp|min-presence: 50) {
  #in-band-nav {
    display: none;
  }
}

Assessment

As soon as setFeature is called, dependent styles applied to the content of the tab are immediately affected. If the user navigates to another page in the site, the value of the variable persists, and the styles continue to apply to the subsequent page, so there should be no flicker on internal navig­ation.

If the user navigates from one page with a sitemap to a page that has no sitemap, that page will not need any sitemap-dependent styles, so the fact that the present value persists for a short moment before being corrected by the add-on will not cause any flicker. If the user navigates to a page using a different sitemap, there will only be flicker if the site warrants a different display level.

Help

Do you carry any weight in the community of Web standard­ization? Can you promote this? Can you devise more (and more compelling) use cases that would help to convince others of the general utility of such a feature? Can you propose anything better?

Summary

All five solutions are summarized below in terms of six desirable properties.

Class injection is the best solution that can be achieved without standard­ization. Even its one fault, the risk of flicker, appears not to manifest on sufficiently capable devices, perhaps aided by its minimalistic approach to alteration of the DOM.

Devising a new media feature for a specific application solves the flicker problem, but depends on standard­ization. This is mitigated by standard­izing on a generic, extensible mechanism for devising new features, based on URI name­spaces. Devising a sitemap feature then becomes a mere application of this mechanism, which is suitable for other applications.

Solution Properties
Combination of sitemap and non-sitemap styles in same sheet Tab isolation Elimination of flicker risk on internal navig­ation Author-defined cascade Avoidance of standard­ization Avoidance of ad-hoc standard­ization
<link> injection no yes no no (forced at end) yes yes
user-stylesheet injection no no yes no (forced at start) yes yes
class injection yes yes no yes yes yes
ad-hoc standard­ized media feature yes yes yes yes no no
name­spaced media feature yes yes yes yes no (requires standard­ization of a more generic mechanism) yes