diff --git a/how-to/.eleventy.js b/how-to/.eleventy.js index f3141cf..4b3d27d 100644 --- a/how-to/.eleventy.js +++ b/how-to/.eleventy.js @@ -1,15 +1,39 @@ const { EleventyHtmlBasePlugin } = require("@11ty/eleventy"); -const listOutcomes = require('./build/list-outcomes'); +const { access } = require("fs/promises"); +const { dirname } = require("path"); +const listOutcomes = require("./build/list-outcomes"); -module.exports = function(eleventyConfig) { +const fileExists = async (path) => access(path).then(() => true, () => false); + +function formatSlug(str) { + if (!str) return; + const parts = str.split("-"); + return parts.map((part) => part[0].toUpperCase() + part.slice(1)).join(" "); +} + +module.exports = function (eleventyConfig) { // Ignore a couple things - eleventyConfig.ignores.add('**/readme.md'); - eleventyConfig.ignores.add('_build/**'); - eleventyConfig.ignores.add('**/_template/**'); + eleventyConfig.ignores.add("**/readme.md"); + eleventyConfig.ignores.add("_build/**"); + eleventyConfig.ignores.add("**/_template/**"); // Global data eleventyConfig.addGlobalData("layout", "layout.html"); eleventyConfig.addGlobalData("outcomes", listOutcomes().outcomes); + + // Computed global data + eleventyConfig.addGlobalData("eleventyComputed", { + outcome: async ({ outcome, page }) => { + if (!outcome) return undefined; + const basePath = dirname(page.inputPath).split("/").slice(1, 3).join("/"); + return { + ...outcome, + hasMethods: await fileExists(basePath + "/methods.md"), + hasResearch: await fileExists(basePath + "/research.md"), + hasUserNeeds: await fileExists(basePath + "/user-needs.md"), + }; + } + }) // Make it easy to deploy to gh-pages eleventyConfig.addPlugin(EleventyHtmlBasePlugin); @@ -17,10 +41,40 @@ module.exports = function(eleventyConfig) { // Copy `assets/` to `_site/assets` eleventyConfig.addPassthroughCopy("assets"); + // Custom breadcrumb filter based entirely on paths + page titles + eleventyConfig.addFilter("breadcrumbs", function (collection) { + function findParent(page) { + const resolvedInputBase = dirname( + page.inputPath.replace(/\/index\.md$/, "") + ); + const possibleInputPaths = [ + `${resolvedInputBase}/index.md`, + `${resolvedInputBase}.md`, + ]; + return collection.find(({ data }) => + possibleInputPaths.includes(data.page.inputPath) + )?.data; + } + + const crumbs = []; + let current = collection.find( + ({ data }) => data.page.inputPath === this.page.inputPath + ).data; + while (current) { + crumbs.push( + `
{{ content }}
diff --git a/how-to/_includes/layout.html b/how-to/_includes/layout.html index b7c9a8d..a3bc4d3 100644 --- a/how-to/_includes/layout.html +++ b/how-to/_includes/layout.html @@ -3,26 +3,20 @@ {%- include "layout/page-title.html" %} - + + - - {% include "layout/top-header.html" %} - {%- if outcome.slug %} - {%- include "layout/sub-header.html" %} - {%- endif %} -This is an unpublished draft preview that might include content that is not yet approved. The published website is at w3.org/WAI/. +
+{{ method.description }}
+ {{ content }} +{{ outcome.description }}
+ +None defined at this time.
+ +### Assertions + +There will probably be a generic assertion based on style guides that applies to this guideline.
+ + +{{ outcome.description }}
+{{ outcome.description }}
+ +We would like to conduct research once we have an initial pass/fail set of examples to see if we are making decisions that support various disabilities. Please get in touch if you could facilitate this research.
+ + +## What to do + +Ensure focusable elements include focus indicators that are visible for people using an input device that relies on the keyboard focus to navigate. + +An outline, or indicator which surrounds the focusable element is generally the most easily visible. + +All indicators for keyboard-focusable elements must be: + +* **Present**: There is a visible indicator of keyboard focus. +* **Not obscured**: The focus indicator is not obscured or partially obscured (more than 50%, TBC) +* **Persistent**: The focus indicator persists while the element has focus, but does not persist after the element loses focus. +* **Distinctive**: The keyboard focus indicator uses a style that is distinct from the style of other non-focused controls, so that the item in focus can be distinguished without reference to the non-focused state. +* **Sufficiently visible**: According to the specific method (below), the indicator must be visually discernible whilst navigating. diff --git a/how-to/outcomes/focus-appearance/methods.md b/how-to/outcomes/focus-appearance/methods.md new file mode 100644 index 0000000..50730c7 --- /dev/null +++ b/how-to/outcomes/focus-appearance/methods.md @@ -0,0 +1,19 @@ +--- +title: Methods +layout: layout/methods.md +--- + +## Foundational Requirements + +We will use a metric of 2px of the perimeter -20% as a starting point. This metric needs usability testing, please get in touch if you could help facilitate this.
+ *Text within a control is not considered part of the size metric.
+ +* **Change of contrast:** The contrast change of the pixels that indicate the keyboard focus is [sufficient] in a) standard mode, b) dark mode, and c) high contrast mode. + *The contrast metric is to be determined, but assumed to be similar to a large-text level.
+* **Adjacent Contrast:** The focus indicator has sufficient contrast with the adjacent colors in a) standard mode, b) dark mode, and c) high contrast mode + *There is a relationship between the area of the focus indicator and contrast that will need to be clarified. E.g. a higher contrast area may not need to be as large.
+ *If the focus indicator is adjacent to the focusable element and does not contrast with the element, it can use the Size change method.
+* **Distinct Style:** The keyboard focus indicator uses a style that is distinct from the style of other controls, so that the item in focus can be distinguished without reference to the non-focused state. +* Multiple controls: There must be at least 3 visible controls of the same style in the view/page. + *In order for a change of color to be used, there needs to be a basis for comparison, otherwise another method is needed.
+* **Adjacent:** The indicator is closer to the focused element than any other focusable element. (The center of the focused element to the center of the indicator.) + + + + +## Change of color + + +The authored focus indicator uses a change of color within the control. + +* **Sufficient Size:** The thickness/length of the focus indicator change is [a sufficient size to be noticeable]. + *We will use a metric of 2px of the perimeter -20% as a starting point. This metric needs usability testing, please get in touch if you could help facilitate this.
+ *Text within a control is not considered part of the size metric.
+* **Change of contrast:** The contrast change of the pixels that indicate the keyboard focus is [sufficient] in a) standard mode, b) dark mode, and c) high contrast mode. + *The contrast metric is to be determined, but assumed to be similar to a large-text level.
+* **Distinct Style:** The keyboard focus indicator uses a style that is distinct from the style of other controls, so that the item in focus can be distinguished without reference to the non-focused state. +* Multiple controls: There must be at least 3 visible controls of the same style in the view/page. + *In order for a change of color to be used, there needs to be a basis for comparison, otherwise another method is needed.
+ + + +## Icon/shape + + +The authored focus indicator uses the addition/removal of an icon or shape. + +* **Sufficient Size:** The thickness/length of the focus indicator change is [a sufficient size to be noticeable]. + *We will use a metric of 2px of the perimeter -20% as a starting point. This metric needs usability testing, please get in touch if you could help facilitate this.
+ *Text within a control is not considered part of the size metric.
+* **Change of contrast:** The contrast change of the pixels that indicate the keyboard focus is [sufficient] in a) standard mode, b) dark mode, and c) high contrast mode. + *The contrast metric is to be determined, but assumed to be similar to a large-text level.
+* **Adjacent Contrast:** The focus indicator has sufficient contrast with the adjacent colors in a) standard mode, b) dark mode, and c) high contrast mode + *There is a relationship between the area of the focus indicator and contrast that will need to be clarified. E.g. a higher contrast area may not need to be as large.
+ *If the focus indicator is adjacent to the focusable element and does not contrast with the element, it can use the Size change method.
+ + + +## Tooltip/additional content + + +Display a tooltip to indicate the user interface component with focus. + +* **Sufficient Size:** The thickness/length of the focus indicator change is [a sufficient size to be noticeable]. + *We will use a metric of 2px of the perimeter -20% as a starting point. This metric needs usability testing, please get in touch if you could help facilitate this.
+ *Text within a control is not considered part of the size metric.
+* **Change of contrast:** The contrast change of the pixels that indicate the keyboard focus is [sufficient] in a) standard mode, b) dark mode, and c) high contrast mode. + *The contrast metric is to be determined, but assumed to be similar to a large-text level.
+* **Adjacent Contrast:** The focus indicator has sufficient contrast with the adjacent colors in a) standard mode, b) dark mode, and c) high contrast mode + *There is a relationship between the area of the focus indicator and contrast that will need to be clarified. E.g. a higher contrast area may not need to be as large.
+ *If the focus indicator is adjacent to the focusable element and does not contrast with the element, it can use the Size change method.
+ + + +## Size change + + +A change of size of the focusable element to show focus. + +* **Sufficient Size:** The discernable area of the focus indicator change is [sufficient to be noticeable] + *We will use a metric of 10% as a starting point. This metric needs usability testing, please get in touch if you could help facilitate this.
+ *“discernable area” means the focused element has a discernible border or background, it cannot just be text.
+ *Text within a control is not considered part of the size metric.
+* **Contrast:** The contrast change of the pixels that indicate the keyboard focus is sufficient in a) standard mode, b) dark mode, and c) high contrast mode + + + +## Combination indicators + + +If an indicator uses a combination of techniques, one of those techniques must meet the test. + + + +## Other indicators + + +Using a custom indicator that does not fit into any other method. + +* **Sufficient Size:** The thickness/length of the focus indicator change is sufficient to be noticeable (metric TBC, use 2px perimeter of the (visually apparent) control as the default, should be relative to the visual size of the control.) + *Add the complexity of the adjacent contrast vs size of indicator.
+* Change of contrast: The contrast change of the pixels that indicate the keyboard focus is sufficient in a) standard mode, b) dark mode, and c) high contrast mode. +* **Adjacent Contrast:** The focus indicator has sufficient contrast with the adjacent colors in a) standard mode, b) dark mode, and c) high contrast mode + *There is a relationship between the area of the focus indicator and contrast that will need to be clarified.
+ *If the focus indicator is adjacent to the focusable element and does not contrast with the element, it may pass via “size change” below.
+* **Distinct Style:** The keyboard focus indicator uses a style that is distinct from the style of other controls, so that the item in focus can be distinguished without reference to the non-focused state. +* **Adjacent:** The indicator is closer to the focused element than any other focusable element. (The center of the focused element to the centre of the indicator.) + +### How it solves user need + +Coming soon \ No newline at end of file diff --git a/how-to/outcomes/focus-appearance/methods/custom-focus-indicator/test.md b/how-to/outcomes/focus-appearance/methods/custom-focus-indicator/test.md new file mode 100644 index 0000000..08fd19a --- /dev/null +++ b/how-to/outcomes/focus-appearance/methods/custom-focus-indicator/test.md @@ -0,0 +1,13 @@ +--- +subtitle: Test +--- + +Coming soon + +### Applicability + +Coming soon + +### Expectation + +Coming soon diff --git a/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/default-focus-indicator-check-contrast.json b/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/default-focus-indicator-check-contrast.json new file mode 100644 index 0000000..7572ada --- /dev/null +++ b/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/default-focus-indicator-check-contrast.json @@ -0,0 +1,8 @@ +{ + "method": { + "index": 1, + "title": "Using the default focus indicator and checking contrast", + "slug": "default-focus-indicator-check-contrast", + "description": "The platform’s default indicator is used, and where the backgrounds are changed, the indicator contrast is checked." + } +} diff --git a/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/index.md b/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/index.md new file mode 100644 index 0000000..58aeec3 --- /dev/null +++ b/how-to/outcomes/focus-appearance/methods/default-focus-indicator-check-contrast/index.md @@ -0,0 +1,15 @@ +--- +layout: method.html +subtitle: Introduction +--- + +{{ outcome.description }}
+ +