1
0
Fork 0
mirror of https://git.sr.ht/~seirdy/seirdy.one synced 2024-09-19 20:02:10 +00:00

Add more justifications for advice

- Mention lockdown mode and the Tor Browser disabling 3p fonts
- Mention usvg for simplifying SVGs
- Cite WAI's draft Low Vision Requirements document to justify stance
  against sidebars.
- Trivial rephrasing
- Link to my "two types of privacy" article
- Update references to site colors to reflect changes
- Link to additional reference on buttons versus links.
This commit is contained in:
Rohan Kumar 2022-08-07 17:42:12 -07:00
parent 2c133b1870
commit 0f0f7d4724
No known key found for this signature in database
GPG key ID: 1E892DB2A5F84479
2 changed files with 61 additions and 33 deletions

View file

@ -442,6 +442,8 @@ A personal example: I set my preferred browser font to "sans-serif", and map it
The "users don't know better and need us to make decisions for them" mindset isn't without merits; however, in my opinion, it's overused. Using system fonts doesn't make your website harder to use, but it does make it smaller and stick out less to the subset of users who care enough about fonts to change them. This argument isn't about making software easier for non-technical users; it's about branding by asserting a personal preference.
Moreover, third-party fonts may not always work. The Tor Browser's "Safer" and "Safest" modes and iOS 16's "Lockdown Mode" disable them. Content-blockers like Firefox Focus and uBlock Origin prominently expose remote-font toggles. If you ship remote fonts, you'll need to test your site with remote *and* system fonts.
### Can't users globally override stylesheets instead?
It's not a good idea to require users to automatically override website stylesheets to see their preferred fonts. Doing so would break websites that use fonts such as Font Awesome to display vector icons. We shouldn't have these users constantly battle with websites the same way that many adblocking/script-blocking users (myself included) already do when there's a better option.
@ -698,7 +700,7 @@ If you can't bear the thought of parting with your solid-black background, worry
=> https://drafts.csswg.org/mediaqueries-5/#prefers-contrast Media Queries Level 5, section 11.3: prefers-contrast
=> https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast prefers-contrast on MDN
I personally like a foreground and background of "#E9E9E9" and "#111", respectively. These shades seem to be as far apart as possible without causing accessibility issues: "#111" 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 "#222".
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". An earlier version of this article recommended a background of "#111", but two helpful readers sensitive to overstimulation and halation found "#191919" preferable.
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.
@ -797,6 +799,9 @@ One key difference between buttons and links is the cursor appearance. Buttons s
Personally, I think its best to respect the convention of the browser and OS rather than break it.
Read more about the differences between buttons and links:
=> https://yatil.net/blog/buttons-vs-links Buttons vs. Links by Eric Eggbert.
### Visible non-interactive semantics
In addition to offering ample non-interactive space (see the prior "non-interactive space" section), ensure that non-interactive and interactive regions are visually distinct. Avoid making interactive elements with many children.
@ -917,10 +922,11 @@ I only recommend using SVG in images; not embeds, objects, or directly in the bo
Ignore the elements specifically required for SVG Tiny PS; your image can be a standard SVG that only utilizes a tiny subset of the full SVG spec.
This advice might seem daunting, but its usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5's SVG implementation, librsvg (used by Wikipedia and GNOME), and most operating systems' icon renderers.
This advice might seem daunting, but its usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5's SVG implementation, librsvg (used by Wikipedia and GNOME), and most operating systems' icon renderers. Moreover, tools like usvg can simplify complex SVGs to a tiny subset of the SVG spec.
=> https://github.com/RazrFalcon/resvg/tree/master/usvg usvg
=> https://github.com/RazrFalcon/resvg/blob/master/docs/usvg_spec.adoc usvg specification
Two tools that can optimize the size of an SVG file are SVGO and the now-discontinued svgcleaner:
=> https://github.com/svg/svgo SVGO
=> https://github.com/RazrFalcon/svgcleaner svgcleaner
@ -1003,6 +1009,11 @@ Sidebars are probably unnecessary, and can be quite annoying to readers who re-s
Neither situation looks great.
Here's a work-in-progress document from the WAI, describing issues caused by significant responsive changes:
=> https://w3c.github.io/low-vision-a11y-tf/requirements#maintain-point-of-regard Low Vision User Accessibility Requirements
It encourages designers to “maintain point of regard” during responsive changes (the “point of regard” is the place a reader is looking at). Unfortunately, its not always possible to “guess” whether the point of regard is the main content or a sidebar.
### Sidebar alternatives
Common items in sidebars include tag clouds, an author bio, and an index of entries; these aren't useful while reading an article. Consider putting them in the article footer or--even better--dedicated pages. This does mean that readers will have to navigate to a different page to see that content, but they probably prefer things that way; almost nobody who clicked on "An opinionated list of best practices for textual websites" did so because they wanted to read my bio.
@ -1516,6 +1527,9 @@ This article is, and will probably always be, an ongoing work-in-progress. Some
* Keyboard-driven browsers and extensions. Qutebrowser, Luakit, visurf, Tridactyl, etc.
* Ways to support non-mainstream and older browsers by supporting subsets of specifications and using progressive enhancement.
* Avoiding "_blank" targets in URLs unless absolutely necessary.
* Spatial navigation
* Why in-page links should generally point to phrasing content rather than sections (pointing to sections messes with tab order).
* The principle of redundant coding
* Ways to improve comprehension by readers who struggle to understand non-literal language (certain manifestations of cognitive disabilities, non-native speakers unfamiliar with idioms, etc.). I might wait until this WAI- draft specification matures and its vocabularies gain adoption before going in depth:
=> https://www.w3.org/TR/adapt-help/ WAI-Adapt: Help and Support Module
@ -1546,7 +1560,7 @@ There are tons of ways to read a page; authors typically cater only to the mains
* Stylesheet alteration, injection, or replacement
* Non-default color palettes
* Forced color palettes
* Adblockers, with a variety of filter-lists
* Adblockers, with various filter-lists
* Blocking third-parties, frames, images, and cookies
* User-selected custom fonts
* Machine translators

View file

@ -127,7 +127,7 @@ Finally, consider using your CSP to restrict script loading. If you must use inl
### Third-party content
Third-party content will complicate the CSP, allow more actors to track users, possibly slow page loading, and create more points of failure. Some privacy-conscious users actually block third-party content: while doing so is fingerprintable, it can reduce the amount of data collected about an already-identified user. Avoid third-party content, if at all possible.
Third-party content will complicate the CSP, allow more actors to track users, possibly slow page loading, and create more points of failure. Some privacy-conscious users actually block third-party content: while doing so is fingerprintable, it can [reduce the amount of data collected about an already-identified user]({{<relref "two-types-of-privacy.md">}}). Avoid third-party content, if at all possible.
Some web developers deliver resources using a third-party content delivery network (<abbr title="content delivery network">CDN</abbr>), such as jsDelivr or Unpkg. Traditional wisdom held that doing so would allow different websites to re-use cached resources; however, [mainstream browsers partition their caches](https://privacycg.github.io/storage-partitioning/) to prevent this behavior.
@ -492,6 +492,8 @@ A personal example: I set my preferred browser font to `sans-serif`, and map it
The "users don't know better and need us to make decisions for them" mindset isn't without merits; however, in my opinion, it's overused. Using system fonts doesn't make your website harder to use, but it does make it smaller and stick out less to the subset of users who care enough about fonts to change them. This argument isn't about making software easier for non-technical users; it's about branding by asserting a personal preference.
Moreover, third-party fonts may not always work. The Tor Browser's "Safer" and "Safest" modes and iOS 16's "Lockdown Mode" disable them. Content-blockers like Firefox Focus and uBlock Origin prominently expose remote-font toggles. If you ship remote fonts, you'll need to test your site with remote _and_ system fonts.
### Style&shy;sheet overrides aren't an excuse {#stylesheet-overrides-arent-an-excuse}
It's not a good idea to require users to automatically override website stylesheets to see their preferred fonts. Doing so would break websites that use fonts such as Font Awesome to display vector icons. We shouldn't have these users constantly battle with websites the same way that many ad- and script-blocking users (myself included) already do when there's a better option.
@ -759,7 +761,7 @@ This image is an approximation of what halation looks like, cropped from <a href
If you can't bear the thought of parting with your solid-black background, worry not: there exists a CSS media feature and client-hint for contrast preferences called `prefers-contrast`. It takes the parameters `no-preference`, `less`, and `more`. You can serve increased-contrast pages to those who request `more`, and vice versa. Check section 11.3 of the W3C {{<mention-work itemtype="TechArticle">}}{{<cited-work url="https://drafts.csswg.org/mediaqueries-5/#prefers-contrast" name="Media Queries Level 5" extraName="headline">}}{{</mention-work>}} specification for more information.
I personally like a foreground and background of `#E9E9E9` and `#111`, respectively. These shades seem to be as far apart as possible without causing accessibility issues: `#111` 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 `#222`.
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`.[^19]
### Contrast is complex
@ -787,7 +789,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". {{<mention-work itemprop="citation" itemtype="BlogPosting">}}{{<indieweb-person itemprop="author" first-name="Rob" last-name="Pike" url="http://herpolhode.com/rob/">}} describes his experience in {{<cited-work name="Color blindness" extraName="headline" url="https://commandcenter.blogspot.com/2020/09/color-blindness-is-inaccurate-term.html">}}{{</mention-work>}}. 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.[^19]
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.[^20]
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.
@ -809,7 +811,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),[^20] and that hyperlinks are no exception. I disagree.
Some typographers insist that [underlined on-screen text is obsolete](https://practicaltypography.com/underlining.html),[^21] 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.
@ -868,6 +870,8 @@ When this is not possible, provide instructions that explain how to use the cont
One key difference between buttons and links is the cursor appearance. Buttons should not turn the cursor into a "hand" or "pointer" icon. The article {{<mention-work itemtype="BlogPosting" itemprop="citation" role="doc-credit">}}{{<cited-work url="https://hidde.blog/some-pointers-on-default-cursors/" name="Some pointers on default cursors" extraName="headline">}} by {{<indieweb-person itemprop="author" name="Hidde de Vries" url="https://hidde.blog/about-me/">}}{{</mention-work>}} covers both sides of the issue. Personally, I think it's best to respect the convention of the browser and OS rather than break it.
Read more about the differences between buttons and links in {{<mention-work itemtype="BlogPosting">}}{{<cited-work url="https://yatil.net/blog/buttons-vs-links" name="Buttons vs. Links" extraName="headline">}} by {{<indieweb-person url="https://yatil.net/" first-name="Eric" last-name="Eggbert">}}{{</mention-work>}}.
### Visible non-interactive semantics
In addition to [offering ample non-interactive space](#non-interactive-space), ensure that non-interactive and interactive regions are visually distinct. Avoid making interactive elements with many children.
@ -902,7 +906,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).[^21] 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.[^22]
: The reference AVIF encoder, included in [libavif](https://github.com/AOMediaCodec/libavif).[^22] 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.[^23]
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&shy;Assembly-compiled encoders; I've heard good things about it.
@ -991,7 +995,7 @@ Light and dark variants of legacy formats (PNG, JPG, GIF), WebP, and AVIF can ca
I only recommend using SVG in images; avoid using them in embeds, objects, or directly in the body. Remember that users may save images, and open them in a non-browser image viewer with reduced SVG compatibility. To maintain maximum compatibility, stick a the subset of the [secure static processing mode](https://www.w3.org/TR/SVG/conform.html#secure-static-mode) of [SVG Static](https://www.w3.org/TR/SVG11/feature#SVG-static). Specifically, the subset that appears in the [SVG Tiny Portable<wbr />/Secure (<abbr title="Portable/Secure">PS</abbr>) spec](https://datatracker.ietf.org/doc/draft-svg-tiny-ps-abrotman/). SVG Tiny PS is a subset of [SVG Tiny&nbsp;1.2](https://www.w3.org/TR/SVGTiny12/intro.html), which is a supported export format in most vector drawing programs. Ignore the elements specifically required for SVG Tiny PS; your image can be a standard SVG that only utilizes a tiny subset of the full SVG spec.
This advice might seem daunting, but its usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5's SVG implementation, librsvg (used by Wikipedia and GNOME), and most operating systems' icon renderers.
This advice might seem daunting, but its usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5's SVG implementation, librsvg (used by Wikipedia and GNOME), and most operating systems' icon renderers. Moreover, tools like [usvg](https://github.com/RazrFalcon/resvg/tree/master/usvg) can simplify complex SVGs to [a tiny subset of the SVG spec](https://github.com/RazrFalcon/resvg/blob/master/docs/usvg_spec.adoc).
Two tools that can optimize the size of an SVG file are [SVGO](https://github.com/svg/svgo) and the now-discontinued [svgcleaner](https://github.com/RazrFalcon/svgcleaner). Too much lossy SVG compression can sometimes _reduce_ the effectiveness of gzip and Brotli compression. Compress in moderation.
@ -1020,7 +1024,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 `<header>` element in an article. An `<hr>` 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 <kbd>Tab</kbd> keystrokes to reach the main content.[^23] 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 <kbd>Tab</kbd> keystrokes to reach the main content.[^24] 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).
@ -1030,7 +1034,7 @@ Users of <abbr title="assistive technology">AT</abbr>s such as screen readers pr
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.[^24] 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.[^25] 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
@ -1056,6 +1060,8 @@ Sidebars are probably unnecessary, and can be quite annoying to readers who re-s
Neither situation looks great.
{{<mention-work itemtype="TechArticle">}}{{<cited-work url="https://w3c.github.io/low-vision-a11y-tf/requirements#maintain-point-of-regard" name="Low Vision User Accessibility Requirements" extraName="headline">}} by the <abbr itemscope="" itemtype="https://schema.org/Organization" itemprop="publisher" title="Web Accessibility Initiative">WAI</abbr>{{</mention-work>}} is a work-in-progress document that describes issues caused by significant responsive changes. It encourages designers to "maintain point of regard" during responsive changes (the "point of regard" is the place a reader is looking at). Unfortunately, it's not always possible to "guess" whether the point of regard is the main content or a sidebar.
### Sidebar alternatives
Common items in sidebars include tag clouds, an author bio, and an index of entries; these aren't useful while reading an article. Consider putting them in the article footer or---even better---dedicated pages. This does mean that readers will have to navigate to a different page to see that content, but they probably prefer things that way; almost nobody who clicked on "An opinionated list of best practices for textual websites" did so because they wanted to read my bio.
@ -1117,7 +1123,7 @@ Users employing machine translation will not benefit from your soft hyphens, so
Where long inline `<code>` elements can trigger horizontal scrolling, consider a scrollable `<pre>` 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.[^25] 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.[^26] 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
@ -1377,7 +1383,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&nbsp;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.[^26]
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.[^27]
{{<codefigure>}}
@ -1455,7 +1461,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 `<em>`, `<code>`, or `<strong>`. Ensure that your meaning carries through without these semantics.[^27]
Screen readers have varying levels of verbosity. The default verbosity level doesn't always convey inline emphasis, such as `<em>`, `<code>`, or `<strong>`. Ensure that your meaning carries through without these semantics.[^28]
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 <samp>right arrow curving left</samp>. 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.
@ -1484,7 +1490,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.[^28]
These are the tools I use regularly. I've deliberately excluded tools that would be redundant.[^29]
[Nu HTML checker](https://validator.nu/)
@ -1497,7 +1503,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&shy;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. 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&shy;ressively.[^29]
: 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&shy;ressively.[^30]
[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.
@ -1527,7 +1533,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 <abbr title="just-in-time">JIT</abbr> compilation disabled.[^30]
2. Evaluate the heaviness and complexity of your scripts (if any) by testing with your browser's <abbr title="just-in-time">JIT</abbr> compilation disabled.[^31]
3. Test using the Tor Browser's safest security level enabled (disables JS and other features).
@ -1555,7 +1561,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.[^31]
16. Download your webpage and test how multiple word processors render and generate PDFs from it.[^32]
17. Combine conversion tools. Combine an HTML-<wbr />to-<wbr />EPUB converter and an EPUB-<wbr />to-<wbr />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.
@ -1605,6 +1611,12 @@ This article is, and will probably always be, an ongoing work-in-progress. Some
* Ways to improve comprehension by readers who struggle to understand non-literal language (certain cognitive disabilities, non-native speakers unfamiliar with idioms, etc.). I might wait until the <cite>[WAI-Adapt: Help and Support Module](https://www.w3.org/TR/adapt-help/)</cite> draft specification matures and its vocabularies gain adoption before going in depth.
* Spatial navigation
* Why in-page links should generally point to phrasing content rather than sections (pointing to sections messes with tab order).
* The [principle of redundant coding](https://w3c.github.io/Mobile-A11y-TF-Note/#provide-clear-indication-that-elements-are-actionable)
* Other accessible writing tips, maybe after I get a copy of <span class="h-cite" itemprop="mentions" itemscope="" itemtype="https://schema.org/Book">{{<cited-work name="Writing Is Designing" url="https://rosenfeldmedia.com/books/writing-is-designing/">}} by {{<indieweb-person first-name="Michael" last-name="Metts" url="https://mjmetts.com/" itemprop="author">}} and {{<indieweb-person first-name="Andy" last-name="Welfe" url="https://www.andy.wtf/" itemprop="author">}}</span>. A relevant excerpt on writing accessibly is [on A List Apart](https://alistapart.com/article/standards-for-writing-accessibly/).<!--Hugo does something weird when I use my mention-work shortcode here.-->
* Rules for descriptive link text, for screen reader navigation and for user-agents that display links as footnotes (e.g. some textual browsers with the `dump` flag).
@ -1638,7 +1650,7 @@ There are so many ways to read a page; authors typically cater only to the mains
* Altering, injecting, or replacing CSS
* Non-default color palettes
* Forced color palettes
* Adblockers, with a variety of filter-lists
* Adblockers, with various filter-lists
* Blocking third-parties
* Disabling frames, images, and cookies
* User-selected custom fonts
@ -1751,33 +1763,35 @@ A special thanks goes out to GothAlice for the questions she answered in <samp>#
[^18]: Since <abbr title="Windows High Contrast Mode">WHCM</abbr> sets colors independently of explicitly-defined ARIA roles, it's a good way to test adherence to [the First Rule of ARIA](#first-rule-of-aria).
[^19]: 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.
[^19]: An earlier version of this article recommended a background of `#111`, but two helpful readers sensitive to overstimulation and halation found `#191919` preferable.
[^20]: {{<mention-work itemtype="Book">}}{{<cited-work name="Practical Typography" url="https://practicaltypography.com/">}}{{</mention-work>}} 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.
[^20]: 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.
[^21]: {{<mention-work itemtype="Book">}}{{<cited-work name="Practical Typography" url="https://practicaltypography.com/">}}{{</mention-work>}} 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 <cite>Practical Typography</cite> 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.
[^21]: 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.
[^22]: 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.
[^22]: 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.
[^23]: 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.
[^23]: I say that a skip link is useful to reduce the amount of <kbd>Tab</kbd> 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.
[^24]: I say that a skip link is useful to reduce the amount of <kbd>Tab</kbd> 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.
[^24]: 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.
[^25]: 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.
[^25]: At least, it will be until [NVDA bug 9343](https://github.com/nvaccess/nvda/issues/9343) gets resolved.
[^26]: At least, it will be until [NVDA bug 9343](https://github.com/nvaccess/nvda/issues/9343) gets resolved.
[^26]: If you'd like to learn more, {{<mention-work itemtype="BlogPosting">}}{{< 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">}}{{</mention-work>}} has far more details on making accessible focus indicators.
[^27]: If you'd like to learn more, {{<mention-work itemtype="BlogPosting">}}{{< 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">}}{{</mention-work>}} has far more details on making accessible focus indicators.
[^27]: 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.
[^28]: 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.
[^28]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded Security Headers, since its approach seems to be recommending headers regardless of whether or not they are necessary. It penalizes forgoing the <code>Permissions-<wbr />Policy</code> 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 <code>Permissions-<wbr />Policy</code> 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).
[^29]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded Security Headers, since its approach seems to be recommending headers regardless of whether or not they are necessary. It penalizes forgoing the <code>Permissions-<wbr />Policy</code> 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 <code>Permissions-<wbr />Policy</code> 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).
[^29]: My site caches HTML documents for ten minutes and caches the RSS feed for several 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.
[^30]: My site caches HTML documents for ten minutes and caches the RSS feed for several 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.
[^30]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnerabilities. In Firefox, navigate to <samp>about:<wbr />config</samp> and toggle some flags under <code>javascript<wbr />.options</code>.
[^31]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnerabilities. In Firefox, navigate to <samp>about:<wbr />config</samp> and toggle some flags under <code>javascript<wbr />.options</code>.
<figure itemprop="hasPart" itemscope="" itemtype="https://schema.org/SoftwareSourceCode">
<figcaption>
@ -1793,6 +1807,6 @@ A special thanks goes out to GothAlice for the questions she answered in <samp>#
In Chromium and derivatives, run the browser with `--js-flags='--jitless'`; in the Tor Browser, set the security level to "Safer".
[^31]: 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.
[^32]: 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.