IndieUI: User Context defines a set of preferences that users can choose to expose to web applications, and an API for user agents to access the preferences and listen for changes. Users can set preferences for features such as screen and font size, color, and typographical preferences. Users with disabilities can provide information about assistive technologies in use, indicate that the display is in an accessibility mode, and indicate whether and what kind of subtitles and audio descriptions they need. Web applications can use this information to optimize the presentation without a requirement to target a specific device, operating system, or locale. While customizations based on these properties benefit users, the information could also be used to make assumptions about users or compromise anonymity. Therefore, the specification includes user agent requirements to allow users to opt out and choose not to expose information on a category basis to preserve privacy.
See the introduction for background and usage examples. Also see the IndieUI Overview.
The primary goal of IndieUI User Context is to provide authorized web applications access to information about a user's relevant settings and preferences, to provide the best possible experience to all users. Some complex web applications can provide a much better experience if given access to information such as a user's preferred color, font, screen, and even *restricted* assistive technology settings such as a preference to render captions, or whether a screen reader is active. General web pages developed using best practices may never need access to restricted user settings, but complex web applications can utilize this information to enhance the performance and user interface.
There are privacy implications to providing any user-specific information to a third-party such as a web site, so a critical part of this specification defines how user agents and web browsers must prevent unauthorized access to user information, including methods to prevent access from parties interested in abusive uses such as "fingerprinting" by marketers. The IndieUI Working Group members believe we've provided a reasonable level of privacy with an API that prevents web sites from being able to detect a difference between a default setting and non-default setting that is not shared with the requesting site.
This section defines feature keys for user settings for use with the UserSetting interface. Some keys can also be accessed as Media Features using syntax defined in the CSS Media Queries specification. User Agents SHOULD implement an access control mechanism that allows users to restrict access to senesitive information requested via the userSetting()
and matchMedia()
method of the Window interface, or from the @media selector in CSS.
The specification below defines feature keys for user settings that can be requested through a new "userSetting" extension to the Window interface. Some keys can also be accessed as new "Media Features" to detect user settings, using existing syntax defined in the CSS Media Queries specification. Because this approach relies so heavily on features that overlap with work maintained by the CSS Working Group and Web Applications Working Group, it is possible that portions or all of this specification may move under the purview these other groups. At a minimum, the IndieUI Working Group requests guidance and a collaborative working relationship with CSS and WebApps.
Todo: Move these to the refs section and link them here:
http://www.w3.org/TR/css3-mediaqueries/
Need to note why we could not use the standard addEventListener
here. It would have either required a new event for every key (onUserFontSizeChanged, etc) or it would have not allowed authors to scope the preferences they were interested in (onUserSettingChange), and therefore prompted excessive callbacks, user prompts, etc.
Description TBD (esp re: privacy and fingerprinting, and prompt access for certain parameters on a per-domain basis, similar to location sharing).
The UserSetting interface extends the Window object rather than the Navigator object because return values can be unique to each window. For example, a user might share a particular setting with only a few trusted domains.
// example of settings keys defined within the IndieUI User Context specification. window.userSetting('user-font-size'); // returns computed value in CSS pixels, e.g. '16px' window.userSetting('subtitles'); // e.g. returns 'display' if the user wants to see subtitles/captions; otherwise returns 'none' // example of taxonomy- or vendor-prefixed settings proposals, intended for standardization. window.userSetting('-webkit-foo'); window.userSetting('-moz-foo');
Standard vendor prefixes (ie
, moz
, o
, webkit
) are reserved. Any additional implementation, host language, or external taxonomy identifiers may be defined in a supplemental working group document.
Todo: Further explain how the privacy model works: when user prompted, window.userSetting() or window.matchMedia() return the default value or null immediately, and only provide the updated match ansynchronously through handleUserSettingChanged() and matchMedia().addEventListener, or on subsequent requests to matchMedia().matches (e.g. on page reload) so there is never any detectable difference between "No" and "You don't need to know." A restricted @media block never prompts unless both the @media block and an included selector matches.
Todo: Document the way justification string may be defined by a meta element in the document head, such as:<meta name="userMediaSettings" content="Used to enable captions and display them in your preferred font size and color.">
In the following example, the web author attempts to query two restricted user settings using two different techniques. For the sake of the example, assume the user's setting do match the specified queries.
// Query matches if screen reader is enabled and user's privacy settings allow the match. var mediaQueryList = window.matchMedia('screen and (screenreader)'); var mediaMatch = mediaQueryList.matches; // The following is equivalent to the previous MQ approach, but uses the window.userSetting(). // window.userSetting will likely be the preferred interface for accessibing these settings // through JavaScript, but the matchMedia syntax can be more terse for complex queries. var setting = window.userSetting('screenreader'); var settingMatch = (setting === 'active') ? true : false; // Note: in conforming implementations, these boolean values will either both be true, or both be false. if (mediaMatch || settingMatch) { console.log('A screen reader is active and the user prefers audio descriptions.'); } else { console.log('The settings do not match, or the user has chosen to not share that information.'); }
Depending on the user's privacy settings and implementation details of the user agent, there are a number of outcomes, according to the following, normative requirements.
To avoid privacy concerns, User Agents MUST immediately return the default value for any restricted features that will result in a user prompt. If and when the user chooses to share settings from the relevant category with the requesting page, the web page author can handle a user setting change callback, or make a subsequent request to the userSetting()
method of the Window object.
In the following example dialog mockup, the web author has requested subtitles
and/or subtitle-languages
settings. The author has also provided a justification string for the userMediaSettings
category using the following markup.
<meta name="userMediaSettings" content="Example Site uses your media settings to automatically enable captions or subtitles in your preferred language.">
A user agent may render the prompt a number of ways, such as a non-blocking notification or a modal dialog.
window.userSetting()
The following example illustrates the code path that is executed when a user with a preference for audio descriptions visits a web page that uses window.userSetting() to automatically enable the secondary audio track at load time.
// Author defines a function to handle changes of the audioDescription setting. function handleAudioDescriptionChanged(key, value) { if (key === 'audio-description' && value !=== 'none') { // User has shared that audio descriptions should be presented. // Enable the "descriptive audio" track in the video. } else { // Set to default. Audio descriptions are off, // or the user has chosen to not share this setting. // Authors should still provide a way to enable the // audio description track in the video player interface. } } /* When the author first attempts to check the setting, the user agent will determine that this is a restricted setting, and immediately return the default value or null, so the first call to this method on the initial page load will never result in audio descriptions being enabled. Note: The immediate return is critical to prevent blocking threads, as well as eliminating potential abuse by fingerprinting scripts attempting to determine uniqueness using execution time of the synchronous call to window.userSetting(). */ // get the setting value var audioDescriptionSetting = window.userSetting('audio-description'); // and explicitly call the handler the first time, because there is no callback yet handleAudioDescriptionChanged('audio-description', audioDescriptionSetting); /* Even though the setting returns the default value immediately, the user will be prompted to decide whether or not to share their media alternative settings with the requesting web site. The web author can register for a change listener on this setting, and the handler will be called asynchronously once the user agrees to share their media settings. */ window.addSettingListener('audio-description', handleAudioDescriptionChanged); // Note: Subsequent page loads should not cause the user to be prompted again.
To avoid privacy concerns, User Agents MUST immediately match the default value of the media query for any restricted features that will result in a user prompt. If and when the user chooses to share settings from the relevant category with the requesting page, the web page author can receive a mediaQueryListChanged event, and make a subsequent request of the matches
property of the MediaQueryList.
window.matchMedia()
Todo: Add code example.
@media
block in CSSTodo: Add code example.
This section defines feature keys for user settings for use with the UserSetting interface. Some keys can also be accessed as Media Features using syntax defined in the CSS Media Queries specification. User Agents SHOULD implement an access control mechanism that allows users to restrict access to senesitive information requested via the userSetting()
method and matchMedia()
method of the Window interface, or from the @media selector in CSS. Todo: link these the the relevant portions of the access control extension.
The features are grouped by restriction categories (e.g. type settings, media settings, etc.) that define related media features and recommended default restriction levels.
Need a setting for whether full keyboard access is enabled (e.g. related to Safari "focus all controls" setting, or any touch screen device without a keyboard or Tab-like capability)
Color settings are not be restricted by default from the requesting page, primarily because a site can figure out most of this information using some creative CSS and JavaScript. These keys are therefore primarily intended as convenience accessors so that web authors can more easily provide adaptive interfaces that work well for all users. The display inversion feature is not currently detectable, but does not represent a major concern for privacy or fingerprinting since it is unlikely that most individuals will have this setting enabled all the time.
user-color
user-color
See user-background-color
and user-subtitle-background-color
for examples of how the color media queries might be used with HSLA suffixes.
user-background-color
user-background-color
In this example, the user-defined color and background color are defined through a user style sheet or other means, so override the site theme to respect the user's colors.
@media (user-color) and (user-background-color) { main { /* Syntax for the user-setting variables to be specified in one of the CSS 4 modules. */ color: user-setting(color); background-color: user-setting(background-color); } }
In this example, the user-defined background color is dark (luminosity less than 40%), so the author adjusts the site logo element to use an image that looks better on darker background colors.
/* Use default logo that looks good on lighter background colors. */ .logo { background-image: url(./img/logo_light.png);} /* Note: this example uses the greater-than/less-than syntax likely to be adopted by CSS4. */ @media (user-background-color-luminosity < 40) { /* User background color is dark; use logo variant that looks better on dark colors. */ .logo { background-image: url(./img/logo_dark.png); } }
In this example, the user-defined background color matches a warm palette (hue is not between 100 and 280; a.k.a. not green, blue, or blue-violet), so the author could adjust the rest of the site theme to be complementary.
/* Note: this example uses the greater-than/less-than syntax likely to be adopted by CSS4. */ @media (user-background-color-hue < 100) or (user-background-color-hue > 280) { /* User background color palette is red-violet, red, orange, or yellow. */ /* This is example is admittedly contrived, and exists mainly to show possibilities. */ }
inverted-colors
Web authors SHOULD NOT re-invert foreground and background colors based on this setting, but MAY choose to double-invert some content, such as photographs.
inverted-colors
The inverted-colors
media feature has being defined in CSS Media Queries Level 4. Once that spec has reached W3C Recommendation status, the remainder of this section will be removed in favor of referencing the CSS specification directly.
inverted
| [none
]In this example, the hardware display rendering is inverted, so the web app could double-invert foreground image and video content, which usually looks strange while inverted. This would leave text foreground color, all background colors, and background styles inverted to adhere to user setting.
@media (inverted-colors) { img, video { filter: invert(100%); } }
In this example, the hardware display rendering is inverted, so the web app could hide elements styles that resemble "shadows" of physical light, which by default look like white glows while inverted. This media query allows authors to disable settings that don't make sense when the physical display pixels are inverted.
@media (inverted-colors) { .page { box-shadow: none; } .pagecurl { background-image: none; } }
Note: Privacy and fingerprinting concerns related to this media feature are minimal, since it is unlikely that most individuals will have this setting enabled all the time. For example, due to personal preference or situational context, some individuals use this as a manual quick toggle to temporarily view text content in a light-on-dark color scheme as opposed to a dark-on-light default.
user-contrast
user-contrast
This example illustrates how Microsoft's implementation-specific -ms-high-contrast
proposal can be replaced by three media features that are not implementation-specific.
Currently Microsoft does not impose any restrictions on the -ms-high-contrast
media feature, but it's possible the user-contrast
setting may end up in a restricted category if it's determined to expose the user to privacy or fingerprinting implications.
/* adjusting to cover both the Microsoft proposal as well as other platforms that have a slider value for color variants */ /* -ms-high-contrast: active; would be equivalent to: */ @media (user-contrast: 1) {} /* a variant query of the same media feature would match both Microsoft's */ /* binary setting and other platform's variable contrast settings */ /* Note: this example uses the greater-than/less-than syntax likely to be adopted by CSS4. */ @media (user-contrast > 0) {} /* -ms-high-contrast: black-on-white; would be equivalent to: */ @media (user-contrast: 1) and (user-color: black) and (user-background-color: white) {} /* -ms-high-contrast: white-on-black; would be equivalent to: */ @media (user-contrast: 1) and (user-color: white) and (user-background-color: black) {} /* -ms-high-contrast: white-on-black; could also be written to use the HSLA color suffixes: */ @media (user-contrast: 1) and (user-color-luminosity: 100) and (user-background-color-luminosity: 0) {} /* -ms-high-contrast: none; would be equivalent to the default value: */ /* No media query is required here b/c it's already the default value. */ /* @media (user-contrast: 0) {} */
Microsoft's current implementation of "high contrast" would only ever return 0.0
or 1.0
, but other platforms support variable contrast increases that would result in a intermediary value like 0.42
, or 0.7
, which could be matched using the CSS3 min/max prefixes, or the CSS4 greater-than/less-than syntax.
monochrome
monochrome
The monochrome
media feature is defined in CSS3.
Type settings are not restricted by default from the requesting page, because a site can figure out all of this information by creatively using CSS and JavaScript. These keys are therefore primarily intended as convenience accessors so that web authors can more easily provide adaptive interfaces that work well for all users.
user-font-size
user-font-size
/* Default layout uses 2 columns */ main { columns: 2; } /* But if the user's default font size (from browser text zoom setting or... */ /* user style sheet...) is larger than 32px, drop the columns. */ /* Note: the CSS3 syntax is (min-user-font-size: 32) */ /* Note: this example uses the greater-than/less-than syntax likely to be adopted by CSS4. */ @media (user-font-size > 32) { main { columns: auto; } }
user-minimum-font-size
user-minimum-font-size
user-line-height
user-letter-spacing
user-word-spacing
In addition to font-size, which is commonly adjusted by mainstream users, line-height, letter-spacing, and word-spacing can be especially important for users with cognitive impairments such as dyslexia and ASD, so it's important to respect a user's default settings.
subtitles
Web authors using a native video player SHOULD allow subtitles to be displayed natively. Web authors using a custom subtitle view SHOULD display the custom-rendered subtitles based on this setting.
subtitle-languages
For example, a native Mexican Spanish speaker living in the United States may have a language preference of "es-mx es en-us en" indicating a preference order for Mexican Spanish, any Spanish, US English, and finally any English dialect.
subtitle-type
sdh
, cc
, or standard
Necessary to match preference for subtitles for the deaf and hard of hearing (SDH) over default dialogue-only subtitles, but the preference for closed captions (CC) versus SDH may not be necessary. SDH appears to be generally preferred over CC when available, and a preference for SDH could indicate an implicit preference for CC over dialogue-only subtitles when CC is available but SDH is not.
user-subtitle-color
user-subtitle-color
none
]See user-background-color
and user-subtitle-background-color
for examples of how the color media queries might be used with HSLA suffixes.
user-subtitle-background-color
user-subtitle-background-color
none
]In this example, the user-defined subtitle background color is not sufficiently opaque to to prevent the video noise from making the captions difficult to read, so add a text shadow.
/* Note: this example uses the greater-than/less-than syntax likely to be adopted by CSS4. */ @media (user-subtitle-background-color-alpha < 20) and (user-subtitle-color-luminosity > 50) { .customRenderedCaptions { text-shadow: 1px 1px 2px black; } }
See user-background-color
and user-subtitle-background-color
for examples of how the color media queries might be used with HSLA suffixes.
audio-description
display
| [none
]Returns a user's preference to be presented with an alternate or supplemental audio track describing the information presented visually.
Audio descriptions are also sometimes referred to as "descriptive audio" tracks.
Need a more appropriate true value than "display"; possibly "prefer", "selected", etc.
User Agents MUST NOT implement high security features like screenreader
settings until the user privacy model is implemented. User Agents MUST allow users to control sharing of prompted settings on a per-domain basis.
Web authors SHOULD NOT request any keys in this category unless the knowledge is essential to the operation of the web application, and web authors MUST provide a justification for the request as defined in @@ section.
Due to community feedback related to privacy, this feature may be marked as at-risk or removed. The working group acknowledges its usefulness in complex web applications such as enterprise document-editing suites, but also acknowledges the fact that its utility may be easily misunderstood or potentially misused.
For example, the typing echo or other verbosity settings would be useful today, for sites such as Google Docs and iWork for iCloud. These applications use custom display views that are not able to be made accessible through conventional means, so speech output is controlled via live region announcements. The web application does not otherwise have access to user settings such as typing echo, so without access to this feature, the web application could not mimic the user's preferred output.
One potential misuse is for user metrics or tracking. Even with the best of intentions, this is a potentially harmful misuse of the API. There are currently very strict user privacy model requirements to implement this feature in a reasonably safe and secure way, but if the working group is not comfortable in the implementation's ability to sufficiently prevent this type of misuse, we will remove the feature.
screenreader
Returns whether a screen reader is currently active or not (none).
active
), or none
otherwise.screenreader
active
| [none
]screenreader-typing-echo
Returns a value indicating whether typing in text fields causes a screen reader echos whole words, characters, both, or none.
words
| characters
| both
| [none
]Todo: Probably need additional categories for screen magnifiers (active/none, scale factor), switch control software (active/none), and the more general "api-compatible" key which could be used for automation scripts in addition to real assistive technology.