This document decribes a proposal for a CSS mechanism and DOM APIs to aid in increasing the level of separation between visual and non-visual structures with runtime reuse. It is useful for Custom Elements, introduces potentially new explanations for how existing elements in the platform work.
When editing a document, an author attempts to mark it up semantically and control
a separation of visual aspects through CSS. This allows various the user-agent
and tools to use the same semantic data to provide any number of affordances
for accessibility, navigation, styling and interaction. HTML elements are generally
carefully constructed to define what they do that makes them unique,
rather than very specifically how they look. This separation leaves room for
certain experimentation and variance that is healthy for the long term adaptability
of the platform. For example, because a
<select>
element doesn't strictly define all aspects of the
visual properties, it was possible for mobile phones to provide a better user
experience where visual real estate is very limited and click areas are shrunk.
Similarly, an author may use various types on the <input>
element,
which, if undefined still defaults to type="text"
and allows UAs like mobile
devices provide native controls. In this aspect, the type
attribute in
some ways acts more like a hint than a requirement. This is, of course, not entirely
true (input type is kind of a debacle actually, APIs actually vary making it improbable to
use the intended 'text only' fallback without much pain) but it is a laudbile
aim and provides a conceptual background for some of the rationale for this proposal.
These examples which already exist in the platform are good, but they are also potentially limited and somewhat magical. They can have impacts on more than visualization as well, to the end effect that they make it difficult for authors to deal with or innovate within.
Preferential Display is a more generalized and more capable extension of the type
idea,
allowing an author to specify preference hints of the type "when the media is screen and max-width is 767px, I would
like to display elements #foo, #bar and #bat as tabsets if possible". At some low level it simply allows the user to manage
a special attribute based on a media query from outside the markup and it desugars into existing platform code
in JavaScript something like this:
/* This is basically a possible approach today */ matchMedia("screen and (max-width: 767px)").addListener(function(evt) {
var element = Array.prototype.slice.call(document.querySelectorAll("#foo, #bar, #bat"));
elements.forEach(function (el) {
if (evt.matches) {
el.setAttribute("preferrential-display", "tabset");
} else {
el.removeAttribute("preferrential-display");
}
});
})
However, this would be a bit more than you'd like to manage in terms of boilerplate, and order should probably follow selector specificity if they have a generic means to add these, and so we can introduce a new API to manage it - something like this:
CSS.associateDisplayPrefernce({
mediaQuery: "screen and (max-width: 767px)",
selector: "#foo, #bar, #bat",
preference: "tabset"
});
This is considerably more conveneint, but ideally you'd be able to express this in CSS itself in a way that is familliar ala something like:
@media screen and (max-width: 767px) {
#foo, #bar, #bat { preferred-display: tabset; }
};
For example,
it might be possible to offer a Preferrential Display for <select-timezone>
elements
which provides a map-like interface similar to those used for choosing timezones in a desktop interface,
but ultimately provides a common <select>
view on the same DOM, or a <common-panel-set>
which can be displayed as any number of visualizations (tabset, accordion, deck or carousel, for example)
but has identical structures and accessibility concerns. It is useful then for an author to be able to
state "under these media conditions I prefer a tabset view if you have it".
The design of this proposal is intended to be such that it introduces minimal new concepts, but offers new capabilities which answer some existing questions, highlight the importance of this separation, and provide new opportunities for experiementation.
An element's Preferential Display is determined by whether or not a Media Query has activated it.
If the preferential display has not been activated by a Media Query, setting it has no effect. Thus:
/* this has no effect as the rule's preferrential-display is not activated by a MediaQuery */
.foo {
preferred-display: map;
}
/* this rule defines a preferrential-display which can be activated by a MediaQuery */
@media screen and (min-width: 767px) {
#foo {
preferred-display: tabset;
}
}
type
, but once set is read-only except via the CSS provided interface. This design
allows that only a media query can cause CSS to change the DOM and simply prevents cycles which would normally prevent this sort of thing. Its presence in the DOM allows it to be
easily used in normal CSS and JavaScript to do simple adaptations. MediaQueryList and listners can be used to explain how this works
fairly well today.