From 455d378d7e40b0922827e7e6f7dab39059669b24 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Sun, 13 Nov 2022 17:19:24 -0800 Subject: [PATCH] Split "contrast is complex" into two sub-sections Split into "use the APCA" and "What contrast algorithms don't cover: over-saturation" Add a footnote to a podcast that covers over-saturation. --- content/posts/website-best-practices.gmi | 8 ++- content/posts/website-best-practices.md | 70 +++++++++++++----------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/content/posts/website-best-practices.gmi b/content/posts/website-best-practices.gmi index d1ee111..fcd45d9 100644 --- a/content/posts/website-best-practices.gmi +++ b/content/posts/website-best-practices.gmi @@ -775,7 +775,7 @@ I personally like a foreground and background of "#E9E9E9" and "#191919", respec If you use JavaScript: avoid setting colors, especially dark-mode colors, using JavaScript. Using JavaScript to set a styles risks introducing a "Flash of Unstyled Content" (FOUC). In the case of a dark theme, this FoUC manifests as a "White Flash of Death" (WFoD). A WFoD is incredibly irritating for dark-mode users; at worst, it could put photosensitive epileptic users at risk. CSS is a render-blocking resource for a reason. -### Contrast is complex +### Use the Advanced Perceptual Contrast Algorithm When setting colors, especially for a dark background, I recommend checking your page's contrast using Accessible Perceptual Contrast Algorithm (APCA) values. You can do so in an online APCA checker or Chromium's developer tools (you might have to enable them in a menu for experimental preferences. I recommend using the web app. @@ -793,6 +793,8 @@ Note that the APCA isn't fully mature as of early 2022. Until version 3.0 of the => https://yatil.net/blog/wcag-3-is-not-ready-yet WCAG 3 is not ready yet +### What contrast algorithms don't cover: over-saturation + Even if the APCA is much better than the WCAG's current naive contrast algorithms, it still doesn't account for all aspects of the relationship between perceptual contrast and color. This discussion on the SAPC-APCA repository covers some shortcomings; for instance, the current APCA doesn't account for the Helmholtz–Kohlrausch effect: => https://github.com/Myndex/SAPC-APCA/discussions/74 Dark Mode Color Palettes and APCA @@ -800,12 +802,12 @@ Even if the APCA is much better than the WCAG's current naive contrast algorithm The Helmholtz–Kohlrausch effect describes how highly-saturated colors appear "brighter" than de-saturated colors with the same brightness. Excessive perceptual brightness against dark backgrounds can trigger halation, eye-strain, and overstimulation. -Yellow may have great contrast on dark backgrounds, but yellow and red can cause problems among people who deal with overstimulation; this includes many on the autism spectrum. +Yellow may have great contrast on dark backgrounds, but yellow and red can cause problems among people who deal with overstimulation; this includes many on the autism spectrum. This issue is a bit personal, since I do deal with overstimulation quite a bit. => https://www.tpgi.com/beyond-wcag-losing-spoons-online/ Beyond WCAG: Losing Spoons Online => https://www.experia.co.uk/blog/ultimate-guide-to-autism-friendly-colours/ The Ultimate Guide to Autism Friendly Colours -If you want to use yellow and red, de-saturate them so that their color feels muted. This site's dark theme uses pale, washed-out yellow and pink for maximum contrast with minimal harshness. +If you want to use significant amounts of "emergency colors" like yellow and red, de-saturate them so their color feels muted. This site's dark theme uses very pale, washed-out yellow and violet for maximum contrast with minimal harshness. Accounting for halation, overstimulation, and high-contrast needs is hard to do if you prioritize minute aesthetics before inclusivity. diff --git a/content/posts/website-best-practices.md b/content/posts/website-best-practices.md index 53bc6e0..2fe5348 100644 --- a/content/posts/website-best-practices.md +++ b/content/posts/website-best-practices.md @@ -825,7 +825,7 @@ If you can't bear the thought of parting with your solid-black background, worry I personally like a foreground and background of `#E9E9E9` and `#191919`, respectively. These shades seem to be as far apart as possible without causing accessibility issues: `#191919` is barely bright enough to create a soft "glow" capable of minimizing halos among slightly astigmatic users, but won't ruin contrast on cheap displays. I also support a `prefers-contrast: less` media query which lightens the background to `#333`.[^24] -### Contrast is complex +### Use the Advanced Perceptual Contrast Algorithm Color is a nuanced topic that deserves more attention than current guidelines give. @@ -841,9 +841,13 @@ The APCA takes several factors into account: Note that [the APCA isn't fully mature](https://yatil.net/blog/wcag-3-is-not-ready-yet) as of early 2022. Until version 3.0 of the WCAG is ready, pages that are required to comply with the WCAG should also conform to the contrast ratios described in the WCAG 2.2's success criteria 1.4.3 (Contrast: Minimum, level AA) or 1.4.6 (Contrast: Enhanced, level AAA). This site's dark-mode stylesheet is an example of a palette that conforms to both the WCAG 2.2 AAA contrast requirements and APCA recommendations. +### What contrast algorithms don't cover: over-saturation + Even if the APCA is much better than the WCAG's current naive contrast algorithms, it still doesn't account for all aspects of the relationship between perceptual contrast and color. [Discussion no. 74 on the SAPC-APCA repository](https://github.com/Myndex/SAPC-APCA/discussions/74) covers some shortcomings. For instance, the current APCA version does not account for [the Helmholtz–Kohlrausch effect](https://en.wikipedia.org/wiki/Helmholtz%E2%80%93Kohlrausch_effect): highly-saturated colors appear "brighter" than de-saturated colors with the same brightness. Excessive perceptual brightness against dark backgrounds can trigger halation, eye-strain, and overstimulation. -Yellow may have great contrast on dark backgrounds, but vivid yellow and red can cause problems among [people who deal with overstimulation](https://www.tpgi.com/beyond-wcag-losing-spoons-online/); this includes [many on the autism spectrum](https://www.experia.co.uk/blog/ultimate-guide-to-autism-friendly-colours/). If you want to use yellow and red, de-saturate them so that their color feels muted. This site's dark theme uses pale, washed-out yellow and pink for maximum contrast with minimal harshness. +Yellow may have great contrast on dark backgrounds, but vivid yellow and red can cause problems among people who deal with overstimulation; this includes [many on the autism spectrum](https://www.experia.co.uk/blog/ultimate-guide-to-autism-friendly-colours/). {{}}{{}}.[^25] + +If you want to use significant amounts of "emergency colors" like yellow and red, de-saturate them so their color feels muted. This site's dark theme uses very pale, washed-out yellow and violet for maximum contrast with minimal harshness. Accounting for halation, overstimulation, and high-contrast needs is hard to do if you prioritize minute aesthetics before inclusivity. @@ -851,7 +855,7 @@ Accounting for halation, overstimulation, and high-contrast needs is hard to do Color palettes need to be effective for different types of vision deficiencies (e.g. color blindnesses) and screens. Color blindness is a far more nuanced topic than "the inability to see some colors". {{}}{{}}. Color blindness manifests in complex ways. Testing in grayscale is a great start, but it doesn't account for all kinds of color vision deficiencies. -Different screens and display-calibrations render color differently; what may look like a light-gray on a cheap monitor could look nearly black on a high-end OLED screen. Try to test on both high- and low-end displays, especially when designing a dark color scheme.[^25] +Different screens and display-calibrations render color differently; what may look like a light-gray on a cheap monitor could look nearly black on a high-end OLED screen. Try to test on both high- and low-end displays, especially when designing a dark color scheme.[^26] Color schemes should also look good to users who apply gamma adjustments. Most operating systems and desktop environments bundle a feature to reduce the screen color temperature at night, while some individuals may select a higher one in the morning. @@ -873,7 +877,7 @@ A basic WCAG Level A requirement is for information to not be conveyed solely th ### In defense of link underlines -Some typographers insist that [underlined on-screen text is obsolete](https://practicaltypography.com/underlining.html),[^26] and that hyperlinks are no exception. I disagree. +Some typographers insist that [underlined on-screen text is obsolete](https://practicaltypography.com/underlining.html),[^27] and that hyperlinks are no exception. I disagree. Readers already expect underlined text to signify a hyperlink. Don't break fundamental affordances for aesthetics. Underlines are also necessary to distinguish the beginnings and ends of multiple consecutive links, especially among color-blind users. @@ -958,9 +962,9 @@ Someone using the GitHub issues interface for the first time will struggle to id ### Against focusable containers -Screen readers like iOS VoiceOver[^27] fail to follow in-page links whose targets are not focusable. Designers often work around this by annotating link targets with the `tabindex="-1"` HTML attribute. This is a good idea when a link target is a heading or piece of [phrasing content](https://html.spec.whatwg.org/dev/dom.html#phrasing-content). Unfortunately, making large containers focusable ruins keyboard-navigability. +Screen readers like iOS VoiceOver[^28] fail to follow in-page links whose targets are not focusable. Designers often work around this by annotating link targets with the `tabindex="-1"` HTML attribute. This is a good idea when a link target is a heading or piece of [phrasing content](https://html.spec.whatwg.org/dev/dom.html#phrasing-content). Unfortunately, making large containers focusable ruins keyboard-navigability. -Normally, if you select some text in a page and press Tab, the tab-focusable element _after_ the selected text will receive focus. However, if the selectable text is inside a focusable container---even a container with a negative `tabindex`---pressing Tab will move focus to the _start_ of the container. If you're reading this on a desktop browser, you can experience this first-hand: select some text in this paragraph and press Tab. Then, do the same in [this snapshot of an excellent _Smashing Magazine_ article](https://web.archive.org/web/20220808163715/https://www.smashingmagazine.com/2022/06/voice-control-usability-considerations-partially-visually-hidden-link-names/).[^28] +Normally, if you select some text in a page and press Tab, the tab-focusable element _after_ the selected text will receive focus. However, if the selectable text is inside a focusable container---even a container with a negative `tabindex`---pressing Tab will move focus to the _start_ of the container. If you're reading this on a desktop browser, you can experience this first-hand: select some text in this paragraph and press Tab. Then, do the same in [this snapshot of an excellent _Smashing Magazine_ article](https://web.archive.org/web/20220808163715/https://www.smashingmagazine.com/2022/06/voice-control-usability-considerations-partially-visually-hidden-link-names/).[^29] {{}} {{}} @@ -992,7 +996,7 @@ Some image optimization tools I use: : The reference WebP encoder; has dedicated lossless and lossy modes. Lossy WebP compression isn't always better than JPEG, but lossless WebP consistently beats PNG. `avifenc` -: The reference AVIF encoder, included in [libavif](https://github.com/AOMediaCodec/libavif).[^29] AVIF lossless compression is typically useless, but its lossy compression is pretty unique in that it leans towards detail removal rather than introducing compression artifacts. Note that AVIF is not supported by Safari or most WebKit-based browsers. It also seems unsupported in Microsoft Edge.[^30] +: The reference AVIF encoder, included in [libavif](https://github.com/AOMediaCodec/libavif).[^30] AVIF lossless compression is typically useless, but its lossy compression is pretty unique in that it leans towards detail removal rather than introducing compression artifacts. Note that AVIF is not supported by Safari or most WebKit-based browsers. It also seems unsupported in Microsoft Edge.[^31] I put together [a quick script](https://git.sr.ht/~seirdy/dotfiles/tree/3b722a843f3945a1bdf98672e09786f0213ec6f6/Executables/shell-scripts/bin/optimize-image) to losslessly optimize images using these programs. For lossy compression, I typically use [GNU Parallel](https://www.gnu.org/software/parallel/) to mass-generate images using different options before selecting the smallest image at the minimum acceptable quality. Users who'd rather avoid the command line while performing lossy compression can instead check out [Squoosh](https://squoosh.app/), a JavaScript app that bundles Web­Assembly-compiled encoders; I've heard good things about it. @@ -1116,7 +1120,7 @@ The first or second heading in the DOM, and the highest heading level, should be Remember that not all landmarks are announced by screen readers; for instance, many screen readers don't announce the ending of a `
` element in an article. An `
` element is a good way to force the ending of a landmark to be visible: it introduces a thematic break between sections that is visible to assistive technologies and user-agents that don't support CSS. -Consider adding a "skip link" if some pages require many Tab keystrokes to reach the main content.[^31] Visually-impaired users generally prefer navigating by headings or landmarks, but screen reader beginners and motor-impaired users still benefit from a skip link. Skip links are especially helpful when pure heading- and landmark-based navigation isn't optimal. +Consider adding a "skip link" if some pages require many Tab keystrokes to reach the main content.[^32] Visually-impaired users generally prefer navigating by headings or landmarks, but screen reader beginners and motor-impaired users still benefit from a skip link. Skip links are especially helpful when pure heading- and landmark-based navigation isn't optimal. If your skip link toggles visibility states when focused, ensure that it doesn't move any existing content; see [the "Layout shifts" section](#layout-shifts) for more details. If it appears over existing content, it needs to have a solid background; if you set the background color, set a foreground color too as described in [the "About custom colors" section](#about-custom-colors). @@ -1126,7 +1130,7 @@ Users of ATs such as screen readers Try using a tool to view a list of all your link names. Just about every screen reader and some browser extensions should offer this functionality. Minimize links with ambiguous names, and ensure that identical link names have identical destinations. -Think twice before placing important content immediately after skippable content such as nested landmarks, long code snippets, figures, and large lists. AT users who wish to skip content may jump directly to the next heading, glossing over anything between the skippable content and subsequent heading; this is especially common on mobile devices.[^32] When it makes sense to do so, place skippable content in its own sections and/or at the end of its parent section. +Think twice before placing important content immediately after skippable content such as nested landmarks, long code snippets, figures, and large lists. AT users who wish to skip content may jump directly to the next heading, glossing over anything between the skippable content and subsequent heading; this is especially common on mobile devices.[^33] When it makes sense to do so, place skippable content in its own sections and/or at the end of its parent section. ### Single-column layout @@ -1215,7 +1219,7 @@ Users employing machine translation will not benefit from your soft hyphens, so Where long inline `` elements can trigger horizontal scrolling, consider a scrollable `
` element instead. Making a single element horizontally scrollable is far better than making the entire page scrollable in two dimensions. Hard-wrap code blocks so that they won't horizontally scroll in most widescreen desktop browsers.
 
-Be sure to test your hyphens with NVDA or Windows Narrator: these screen readers' pronunciation of words can be disrupted by poorly-placed hyphens. Balancing the need to adapt to narrow screens against the need to sound correctly to a screen reader is a complex matter.[^33] The best place to insert a hyphen is between compound words. For example, splitting "Firefighter" into "Fire-fighter" is quite safe. Beyond that, try listening to hyphenated words in NVDA to ensure they remain clear.
+Be sure to test your hyphens with NVDA or Windows Narrator: these screen readers' pronunciation of words can be disrupted by poorly-placed hyphens. Balancing the need to adapt to narrow screens against the need to sound correctly to a screen reader is a complex matter.[^34] The best place to insert a hyphen is between compound words. For example, splitting "Firefighter" into "Fire-fighter" is quite safe. Beyond that, try listening to hyphenated words in NVDA to ensure they remain clear.
 
 ### Keeping text together
 
@@ -1237,7 +1241,7 @@ I already covered the first option in the prior subsection. If you expect viewer
 
 The best compromise is to ensure that the image isn't too wide, and can support large text on a narrow viewport. Lines of text in images should contain as few characters as possible. For a good example, see the "[In defense of link underlines](#in-defense-of-link-underlines)" section.
 
-If the text needs to be readable, [check its APCA levels](#contrast-is-complex). At large sizes, the contrast shouldn't be too high; at small sizes, it shouldn't be too low.
+If the text needs to be readable, [check its APCA levels](#use-the-advanced-perceptual-contrast-algorithm). At large sizes, the contrast shouldn't be too high; at small sizes, it shouldn't be too low.
 
 ### Indented elements
 
@@ -1475,7 +1479,7 @@ On one hand, users who need enhanced focus visibility may override the default f
 
 The WCAG [Success Criterion 2.4.12](https://w3c.github.io/wcag/guidelines/22/#focus-appearance-enhanced) recommends making focus indicators 2 px thick. While this success criterion is only AAA-level, it's easy enough to meet and beneficial enough to others that we should all meet it.
 
-You can use `:focus` and `:focus-visible` to highlight selected and keyboard-focused elements, respectively. Take care to only alter styling, not behavior: only keyboard-focusable elements should receive outlines. Modern browser stylesheets use `:focus-visible` instead of `:focus`; old browsers only support `:focus` and re-style a subset of focusable elements. Your stylesheets should do the same, to match browser behavior.[^34]
+You can use `:focus` and `:focus-visible` to highlight selected and keyboard-focused elements, respectively. Take care to only alter styling, not behavior: only keyboard-focusable elements should receive outlines. Modern browser stylesheets use `:focus-visible` instead of `:focus`; old browsers only support `:focus` and re-style a subset of focusable elements. Your stylesheets should do the same, to match browser behavior.[^35]
 
 {{}}
 
@@ -1555,7 +1559,7 @@ Screen readers on touch screen devices are also quite different from their deskt
 
 Screen reader implementations often skip punctuation marks like the exclamation point (!). Ensure that meaning doesn't rely too heavily on such punctuation.
 
-Screen readers have varying levels of verbosity. The default verbosity level doesn't always convey inline emphasis, such as ``, ``, or ``. Ensure that your meaning carries through without these semantics.[^35]
+Screen readers have varying levels of verbosity. The default verbosity level doesn't always convey inline emphasis, such as ``, ``, or ``. Ensure that your meaning carries through without these semantics.[^36]
 
 Default verbosity does, however, convey symbols and emoji. Use symbols and emoji judiciously, since they can get pretty noisy if you aren't careful. Use `aria-labelledby` on symbols when appropriate; I used labels to mark my footnote backlinks, which would otherwise be read as right arrow curving left. If you have to use a symbol or emoji, first test how assistive technologies announce it; the emoji name may not communicate what you expect.
 
@@ -1613,7 +1617,7 @@ No matter how simple a page is, I don't think simplicity eliminates the need for
 
 Automated tests---especially accessibility tests---are a supplement to manual tests, not a replacement for them. Think of them as time-savers that bring up issues for further research, containing both false positives and false negatives.
 
-These are the tools I use regularly. I've deliberately excluded tools that would be redundant.[^36]
+These are the tools I use regularly. I've deliberately excluded tools that would be redundant.[^37]
 
 
 [Nu HTML checker](https://validator.nu/)
@@ -1626,7 +1630,7 @@ These are the tools I use regularly. I've deliberately excluded tools that would
 : An auditing tool by Google that uses the DevTools protocol in any Chromium-based browser. Skip the "Access­ibility" category, since it just runs a subset of axe-core's audits. The most useful audit is the tap target size check in its "SEO" category. It's also convenient for measuring performance with CPU throttling, to simulate low-end mobile devices. Note that your `sandbox` CSP directive will need to include `allow-scripts` for it to function.
 
 [Webhint](https://webhint.io/)
-: Similar to Lighthouse. Again, you can ignore the accessibility audits if you already use axe-core. I personally disagree with some of its hints: the "unneeded HTTP headers" hint ignores the fact that the CSP can have an effect on non-hypertext assets, the "HTTP cache" hint has an unreasonable bias against caching HTML, and the "Correct `Content-Type` header" recommends charset attributes a bit too agg­ressively.[^37]
+: Similar to Lighthouse. Again, you can ignore the accessibility audits if you already use axe-core. I personally disagree with some of its hints: the "unneeded HTTP headers" hint ignores the fact that the CSP can have an effect on non-hypertext assets, the "HTTP cache" hint has an unreasonable bias against caching HTML, and the "Correct `Content-Type` header" recommends charset attributes a bit too agg­ressively.[^38]
 
 [IBM Equal Access Accessibility Checker](https://www.ibm.com/able/toolkit/verify/automated/)
 : Has a scope similar to axe-core. Its "Sensory Characteristics" audit seems unique.
@@ -1662,7 +1666,7 @@ These tests begin reasonably, but gradually grow absurd. Once again, use your ju
 
 1. Test in all three major browser engines: Blink, Gecko, and WebKit.
 
-2. Evaluate the heaviness and complexity of your scripts (if any) by testing with your browser's JIT compilation disabled.[^38]
+2. Evaluate the heaviness and complexity of your scripts (if any) by testing with your browser's JIT compilation disabled.[^39]
 
 3. Test using the Tor Browser's safest security level enabled (disables JS and other features).
 
@@ -1690,7 +1694,7 @@ These tests begin reasonably, but gradually grow absurd. Once again, use your ju
 
 15. Try printing out your page in black-and-white from an unorthodox graphical browser.
 
-16. Download your webpage and test how multiple word processors render and generate PDFs from it.[^39]
+16. Download your webpage and test how multiple word processors render and generate PDFs from it.[^40]
 
 17. Combine conversion tools. Combine an HTML-to-EPUB converter and an EPUB-to-PDF converter, or stack multiple article-extraction utilities. Be creative and enjoy breaking your site. When something breaks, examine the breakage and see if it's caused by an issue in your markup, or a CSS feature with an equivalent alternative.
 
@@ -1904,39 +1908,41 @@ A special thanks goes out to GothAlice for the questions she answered in #
 
 [^24]: An earlier version of this article recommended a background of `#111`, but two helpful readers sensitive to overstimulation and halation found `#191919` preferable.
 
-[^25]: When making an earlier version of this site's dark-mode color palette, I made the mistake of exclusively testing in cheap or poorly-calibrated displays with bright black points. I mistakenly thought that my `#0b0b0b` background was bright enough to [prevent halation](#halation). Only after testing on a better screen did I realize that it would look almost completely black; I subsequently lightened the background to `#111` to strike a good balance.
+[^25]: Lē also [shared their experience in A11y Rules](https://a11yrules.com/podcast/le-silveus-mcnamara-talks-about-neurodivergence-color-choices-and-overstimulation/), one of my favorite podcasts
 
-[^26]: {{}}{{}}{{}} only renders invisible text without JavaScript. You can use a textual browser, screen reader, copy-paste the page contents elsewhere, use a reader-mode implementation, or "view source" to read it without enabling scripts. All of these options will ironically override the carefully-crafted typography of this website about typography.
+[^26]: When making an earlier version of this site's dark-mode color palette, I made the mistake of exclusively testing in cheap or poorly-calibrated displays with bright black points. I mistakenly thought that my `#0b0b0b` background was bright enough to [prevent halation](#halation). Only after testing on a better screen did I realize that it would look almost completely black; I subsequently lightened the background to `#111` to strike a good balance.
+
+[^27]: {{}}{{}}{{}} only renders invisible text without JavaScript. You can use a textual browser, screen reader, copy-paste the page contents elsewhere, use a reader-mode implementation, or "view source" to read it without enabling scripts. All of these options will ironically override the carefully-crafted typography of this website about typography.
 
     I find Practical Typography quite useful for printed works, and incorporated a more moderate version of its advice on soft-hyphens into this page. With a few such exceptions, I generally find it to be poor advice for Web content.
 
-[^27]: I can't confirm if this is also an issue on VoiceOver for macOS, because I haven't borrowed the hardware required to test it.
+[^28]: I can't confirm if this is also an issue on VoiceOver for macOS, because I haven't borrowed the hardware required to test it.
 
-[^28]: I linked to a snapshot from the Wayback Machine in hopes that the live version of the Smashing Magazine site will get fixed.
+[^29]: I linked to a snapshot from the Wayback Machine in hopes that the live version of the Smashing Magazine site will get fixed.
 
-[^29]: libavif links against libaom, librav1e, and/or libsvtav1 to perform AVIF encoding and decoding. libaom is best for this use-case, particularly since libaom can link against libjxl to use its Butteraugli distortion metric. This lets libaom optimize the perceptual quality of lossy encodes much more accurately.
+[^30]: libavif links against libaom, librav1e, and/or libsvtav1 to perform AVIF encoding and decoding. libaom is best for this use-case, particularly since libaom can link against libjxl to use its Butteraugli distortion metric. This lets libaom optimize the perceptual quality of lossy encodes much more accurately.
 
-[^30]: I find it quite odd that Microsoft Edge doesn't support AVIF. Chromium has supported AVIF for a long time, and Edge is based on Chromium. AVIF is a royalty-free format; I don't know why Microsoft would remove support for it, especially since Microsoft allows adding AVIF support to Windows. I think Edge also removed Chromium's experimental, off-by-default support for JPEG-XL.
+[^31]: I find it quite odd that Microsoft Edge doesn't support AVIF. Chromium has supported AVIF for a long time, and Edge is based on Chromium. AVIF is a royalty-free format; I don't know why Microsoft would remove support for it, especially since Microsoft allows adding AVIF support to Windows. I think Edge also removed Chromium's experimental, off-by-default support for JPEG-XL.
 
-[^31]: I say that a skip link is useful to reduce the amount of Tab keystrokes required, but I don't know a good "threshold number" to signify "too many keystrokes". If it takes ten keystrokes to reach the main content, it's probably time to add a skip-link.
+[^32]: I say that a skip link is useful to reduce the amount of Tab keystrokes required, but I don't know a good "threshold number" to signify "too many keystrokes". If it takes ten keystrokes to reach the main content, it's probably time to add a skip-link.
 
-[^32]: ATs typically let users navigate by headings, landmarks, paragraphs, and links. Most users prefer skipping article content with heading-based navigation. Keyboard users can bind different keys to different modes of navigation, but mobile users can only access one navigation mode at a time.
+[^33]: ATs typically let users navigate by headings, landmarks, paragraphs, and links. Most users prefer skipping article content with heading-based navigation. Keyboard users can bind different keys to different modes of navigation, but mobile users can only access one navigation mode at a time.
 
     Mobile users wishing to temporarily switch modes have to stop, change their navigation mode, perform a navigation gesture, and switch back. Mobile users trying to skim an article don't always find this worth the effort and sometimes stick to heading-based navigation even when a different mode would be optimal.
 
-[^33]: At least, it will be until [NVDA bug 9343](https://github.com/nvaccess/nvda/issues/9343) gets resolved.
+[^34]: At least, it will be until [NVDA bug 9343](https://github.com/nvaccess/nvda/issues/9343) gets resolved.
 
-[^34]: If you'd like to learn more, {{}}{{< cited-work name="A guide to designing accessible, WCAG-compliant focus indicators" url="https://www.sarasoueidan.com/blog/focus-indicators/" extraName="headline" >}} by {{< indieweb-person url="https://www.sarasoueidan.com/" first-name="Sara" last-name="Soueidan" url="https://www.sarasoueidan.com/" itemprop="author">}}{{}} has far more details on making accessible focus indicators.
+[^35]: If you'd like to learn more, {{}}{{< cited-work name="A guide to designing accessible, WCAG-compliant focus indicators" url="https://www.sarasoueidan.com/blog/focus-indicators/" extraName="headline" >}} by {{< indieweb-person url="https://www.sarasoueidan.com/" first-name="Sara" last-name="Soueidan" url="https://www.sarasoueidan.com/" itemprop="author">}}{{}} has far more details on making accessible focus indicators.
 
-[^35]: Screen readers aren't alone here. Several programs strip inline formatting: certain feed readers, search result snippets, and textual browsers invoked with the `-dump` flag are some examples I use every day.
+[^36]: Screen readers aren't alone here. Several programs strip inline formatting: certain feed readers, search result snippets, and textual browsers invoked with the `-dump` flag are some examples I use every day.
 
-[^36]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded [Hardenize](https://hardenize.com/) and [CryptCheck](https://cryptcheck.fr/), since their scope is covered by Internet.nl.
+[^37]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded [Hardenize](https://hardenize.com/) and [CryptCheck](https://cryptcheck.fr/), since their scope is covered by Internet.nl.
 
     I excluded Security Headers, since its approach seems to be recommending headers regardless of whether or not they are necessary. It penalizes forgoing the Permissions-Policy header even if the CSP blocks script loading and execution; see [Security Headers issue #103](https://github.com/securityheaders/securityheaders-bugs/issues/103). I personally find the Permissions-Policy header quite problematic, as I noted in August 2021 on [webappsec-permissions-policy issue #189](https://github.com/w3c/webappsec-permissions-policy/issues/189#issuecomment-904783021). Finally, Security Headers doesn't have in-depth checks of the _values_ of headers; Internet.nl does a much better job of that. Security should be a thoughtful process, not a checklist.
 
-[^37]: My site caches HTML and RSS feed for a few hours. I disagree with webhint's recommendations against this: cache durations should be based on request rates and how often a resource is updated. I also disagree with some of its `content-type` recommendations: you don't need to declare UTF-8 charsets for SVG content-type headers if the SVG is ASCII-only and called from a UTF-8 HTML document. You gain nothing but header bloat by doing so.
+[^38]: My site caches HTML and RSS feed for a few hours. I disagree with webhint's recommendations against this: cache durations should be based on request rates and how often a resource is updated. I also disagree with some of its `content-type` recommendations: you don't need to declare UTF-8 charsets for SVG content-type headers if the SVG is ASCII-only and called from a UTF-8 HTML document. You gain nothing but header bloat by doing so.
 
-[^38]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnerabilities. In Firefox, navigate to about:config and toggle some flags under javascript.options.
+[^39]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnerabilities. In Firefox, navigate to about:config and toggle some flags under javascript.options.
 
     
@@ -1952,6 +1958,6 @@ A special thanks goes out to GothAlice for the questions she answered in # In Chromium and derivatives, run the browser with `--js-flags='--jitless'`; in the Tor Browser, set the security level to "Safer". -[^39]: LibreOffice can also render HTML but has extremely limited support for CSS. OnlyOffice seems to work best, but doesn't load images. If your page is CSS-optional, it should look fine in both. +[^40]: LibreOffice can also render HTML but has extremely limited support for CSS. OnlyOffice seems to work best, but doesn't load images. If your page is CSS-optional, it should look fine in both.