Skip to content

comply with WCAG 2.0 for footnote backlinks #313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 16, 2018
Merged

Conversation

sunnywalker
Copy link
Contributor

WCAG 2.0 2.4.4 (and 2.4.9) says link texts to different URLs cannot be the same. Using aria-label which matches the title attribute is probably redundant and doesn't solve the issue. This implementation allows for user-overridable aria-labels with reference and footnote number reference options to comply with 2.4.4 and 2.4.9.

This PR also includes an .editorconfig file to help maintain source formatting options across multiple editors/contributors.

WCAG 2.0 2.4.4 says link texts to different urls cannot be the same.
aria-label matching the title attribute is probably redundant and
doesn't solve the issue, so this implementation allows for
user-overridable aria-labels with reference and footnote number
reference options to comply with 2.4.4
@sunnywalker
Copy link
Contributor Author

Changes to the default behavior are: the aria-label is no longer included on the footnote backlinks when the $fn_backlink_title is specified. This is not effectively breaking anything because the aria-label was being set to the same value as the title which is redundant.

@michelf
Copy link
Owner

michelf commented Oct 12, 2018

I believe the problem you're trying to solve is the repeated aria-label text when you have more than one reference to the same footnote. Is that right? That sounds like a legitimate problem.

Is there a good reason why the label should be different from the title? Adding a configuration variable allowing the text to be different makes things more complicated to configure, and adds more logic to test and maintain. I'd rather avoid it if possible. We could fix title generation instead.

It might look fine to say "Go back to reference 1 of footnote 1" when there is more than one footnote reference. But most of the time there is only one footnote per reference, and in such a situation this text is far from ideal. I think it should say ""Go back to reference of footnote 1", skipping the reference index since there's only one. So I think we need a different string for cases where there more than one reference.

About the implementation

The note id is just an identifier for generating the id attribute. It can be anything. For instance, if someone writes its footnote references as [^blah], the note id will be blah even though the user will still be shown a number, not the identifier. I don't think it makes sense to put the note id in user-facing text for aria-label, title, or anything really.

What you probably want is the footnote number. You'll need a counter in the while loop to get it.

@sunnywalker
Copy link
Contributor Author

Yes, the problem is that to pass WCAG 2.0 checks (which is required by law for US Government and Public sector, e.g., education), you cannot have multiple links with the same link text which lead to different URLs. See WCAG 2.0, 2.4.4 (level A) and 2.4.9 (level AAA). If you have more than one footnote (or multiple footnote references to the same footnote), that creates multiple return arrow links (which is therefore the same link text leading to different URLs and the hash portion counts as part of the URL in this case). You can get around the same link text issue by providing a unique aria-label (or title) which keeps the visual aspect but positively affects the accessibility DOM.

screen shot 2018-10-12 at 8 17 31 am

The footnote markers themselves (sup 1, 2, 3) are fine because they all lead to their respective same URLs.

I fully agree that it adds complexity to the implementation but I didn't want to hard-code any sort of aria-label because that limits the text to English and to a specific phrase format. Using those {ref} and {fn} placeholders in an optional user-definable label allows for localization of the aria-label for the back reference.

I generally use numeric references so I didn't test with a named reference. I'll fix that and create a new PR with your suggested internal variable. I will also fix a bug I noticed which allows for spaces in named footnote references which creates an invalid id value.

I understand your reticence to adding complexity to the code for an admittedly rarely used issue, but you already have some accessibility built-in with the aria roles and the aria-label so I feel going the extra step for a11y compliance is worth it. Plus, for those of us that have a critical/lawful need, it will save a considerable amount of headache if we want to keep using your fantastic tool.

I hope you will consider it.
Thank you,
Sunny

@sunnywalker
Copy link
Contributor Author

As to the aria-label versus title, I stuck with aria-label instead of title because most browsers will show the title as a mouse hover tooltip which may or may not be a desired effect. Also, you already have $fn_backlink_title which allows for (universal) customization of the title whereas the aria-label is a more specific function/problem of accessibility and for which meeting the standard is an unsolved issue.

whitespace creates invalid HTML ids
refer to the internal footnote number instead of the named reference id
@sunnywalker
Copy link
Contributor Author

I've pushed updates (which I guess should have been separate PRs--sorry) to address the footnote reference number and the issue with named footnotes with spaces in them.

@sunnywalker
Copy link
Contributor Author

Just to cite a reference, the WHATWG docs on the id attribute state that the id must not contain any whitespace.

invalidating spaces in footnote names, while technically correct from
HTML standards point of view is an unnecessarily burdensome breaking
change at this time
@sunnywalker
Copy link
Contributor Author

sunnywalker commented Oct 13, 2018

Indeed, there are other characters that php-markdown accepts as valid footnote names which make them invalid from an HTML standards perspective that, were such a change to be made, it should be a more comprehensive implementation and transparent to the user without the need for additional documentation unless absolutely warranted.

I hope that you will still give serious consideration the aria-label WCAG 2 compliance issue/fix.
Thank you.

@michelf
Copy link
Owner

michelf commented Oct 13, 2018

Ok. I agree we should fix this. Here's two guidelines I'd like to be followed:

  • The text formatting mechanics should be consistent between the title and the aria-label. If we add a way to parametrize the string in the label, the title should be parametrizable in the same way.
  • Ideally, the backlink html (shown inside the link) should accept the same formatting too.
  • There should be a way to have a different string for the very common case where there is only one reference, because when there's only one reference it makes little sense to have a numbered reference.

Here's what I had in mind for the configuration variables:

public $fn_backlink_title = "";
public $fn_backlink_title_with_multiple_references = ""; // uses fn_backlink_title if empty
public $fn_backlink_html = '↩︎';
public $fn_backlink_html_with_multiple_references = ""; // uses fn_backlink_html if empty
public $fn_backlink_label = "";
public $fn_backlink_label_with_multiple_references = ""; // uses fn_backlink_label if empty

Which someone would configure this way:

$parser->fn_backlink_title = "Back to reference";
$parser->fn_backlink_title_with_multiple_references = "Back to reference ##";
$parser->fn_backlink_label = "Back to reference of footnote %%";
$parser->fn_backlink_label_with_multiple_references = "Back to reference ## of footnote %%";

Does that make sense? Hopefully I'm not pilling up too much work on you by suggesting this. Feel free to skip some parts if you want.

And I used ## and %% as formatting parameters here because %% is already used to format table cell class names. I don't think that's better than using words in braces (like {ref}), but it'd be a bit more consistent.

@sunnywalker
Copy link
Contributor Author

While I prefer named replacement parameters because they're self-documenting, I also appreciate consistency.

What if I implement both ##/%% and {ref}/{fn}? I don't think that would create too much of a cognitive load or technical debt and shouldn't be a significant hit to performance.

But, because these are programmer-side, I don't think it's too onerous to keep them simple and consistent but opaque in use/meaning.

As for all the extra variables, it sort of rubs me the wrong way but I'm trying to think of a more elegant solution that isn't troublesome.

$parser->fn_backlink_title = "Return to [[reference ## of]] footnote %%";

Using special characters to denote optional regions could start to get messy because of the need to escape control characters. That can get ugly quick.

I'm talking it out before coding, in case you have any particular feedback or ideas.

@sunnywalker
Copy link
Contributor Author

sunnywalker commented Oct 13, 2018

I kind of prefer ^^ as the footnote number marker instead of ## because it is related to the [^1] of the original footnote definition.

$parser->fn_backlink_label_multi_reference = "Return to reference %% of footnote ^^";

This may make it easier to remember that ^^ is the footnote number and %% is the reference number.

@michelf
Copy link
Owner

michelf commented Oct 13, 2018

I do like ^^, so please go with that.

From a localization perspective, two separate strings will generally work better than a string pattern of some kind because adaptation might be needed to suite the grammatical rules.

@michelf
Copy link
Owner

michelf commented Oct 13, 2018

And I'm not brining localization issues as a way to discourage exploration into other solutions than having two variables, just as something to keep in mind.

@sunnywalker
Copy link
Contributor Author

You're right. There are too many variations in language grammars that a single variable with a parsed syntax could be problematic. I'll stick with multiple variables and the simpler str_replace().

@sunnywalker
Copy link
Contributor Author

sunnywalker commented Oct 13, 2018

Considering the duality of the double variable with fallback solution, I'm thinking what happens when one or either or both vars are blanks.

I will refer to the single variable as, for example, $fn_backlink_title, and the multi variable as, for example, $fn_backlink_title_with_multiple_references.

  1. For the title and (aria-)label:
    • If the single is not blank
      • and there is one reference
        • add single param accordingly.
      • and there are multiple references
        • and multi is blank, add single param to each backlink.
        • and multi is not blank, add multi param to each backlink (including first one)
    • If the single is blank
      • and there is one reference, no param is added
      • and there are multiple references
        • and multi is blank, no param is added
        • and multi is not blank, add multi param to each backlink (including the first one)
  2. For the backlink html:
    • If the single is not blank
      • and there is one reference
        • use the single html
      • and there are multiple references
        • and multi is blank, use the single html for all
        • and multi is not blank, use the multi html for all (including first one)
    • If the single is blank
      • currently an empty <a> tag is created which is bad for a11y.
      • and there is one reference
        • no backlink tag should be generated (is this a breaking change?)
      • and there are multiple references
        • and multi is blank, no tag should be generated
        • and multi is not blank, use the multi html for all (including first one)

@michelf
Copy link
Owner

michelf commented Oct 13, 2018

That logic looks fine.

Omitting the link altogether when the HTML is empty would make sense. I don't know if anyone depends on that behavior currently, but I'd find that surprising. On the other hand, I wonder if this is only adding flexibility for the sake of adding flexibility as I expect no one will use the feature. I don't have a definitive answer, so I'll let you decide.

@sunnywalker
Copy link
Contributor Author

I think the footnote backlinks parsing feature is going to be rarely used, even if it is critical to those of us who need it. A simpler implementation should be fine for now.

@michelf michelf merged commit 4db3e9a into michelf:lib Oct 16, 2018
michelf added a commit that referenced this pull request Oct 16, 2018
jkrrv pushed a commit to jkrrv/php-markdown that referenced this pull request Aug 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants