Skip to content

Conversation

@uzmannazari
Copy link
Contributor

Summary

This PR refactors the BreadCrumb skin object to render semantic, list-based markup using <nav>, <ol>, and <li> elements instead of inline spans and separators.

The updated output improves accessibility and aligns breadcrumb rendering with common WCAG and ARIA breadcrumb patterns, while preserving existing behavior and customization options.

Fixes #6609

Details

  • Updated the BreadCrumb ASCX to wrap the generated breadcrumb items inside a semantic navigation container (<nav aria-label="Breadcrumb">) and an ordered list (<ol itemscope itemtype="https://schema.org/BreadcrumbList">).
  • Replaced the Label with a Literal to avoid injecting wrapper markup inside the list container (ensuring valid list structure).
  • Refactored backend rendering to output one <li> per breadcrumb item with Schema.org BreadcrumbList / ListItem microdata and position meta.
  • Applied aria-current="page" to the <li> representing the current page (instead of the <a>), matching common ARIA breadcrumb patterns.
  • Rendered separators inside each breadcrumb <li> (only when another crumb follows) and marked them decorative via aria-hidden="true", avoiding extra list items while preserving the existing Separator customization and path resolution.
  • Added default styling in type.scss for nav.dnnBreadcrumb ol to prevent list items stacking vertically after switching to list markup, and to ensure the ordered list does not display numeric markers while keeping the visual breadcrumb layout consistent:
    • list-style: none; (prevents numbering/markers)
    • display: flex; align-items: center; gap: 0.5rem; (keeps crumbs inline and spaced)
    • nav.dnnBreadcrumb ol li span { margin-inline-start: 0.5rem; display: inline-block; } (consistent spacing for the separator/content)
image

Impact

  • Improves accessibility and semantic correctness of breadcrumb markup.
  • Preserves existing breadcrumb features and configuration (RootLevel, UseTitle, HideWithNoBreadCrumb, DisableLink, Profile/Group URL parameters, Separator customization).
  • Visual output remains consistent with previous behavior via the added default styling.

Testing

  • Verified breadcrumb output for multi-level navigation paths renders inline (not stacked) and without ordered-list numbering.
  • Tested root breadcrumb rendering and HideWithNoBreadCrumb behavior.
  • Tested pages with disabled breadcrumb links.
  • Confirmed structured data output remains valid for BreadcrumbList.
image

@uzmannazari uzmannazari changed the title Patch 6 BreadCrumb skin object to render semantic, accessible breadcrumb markup Jan 8, 2026
Copy link
Contributor

@mitchelsellers mitchelsellers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note/request included on a change to localization.

Additionally however I do believe this would be a substantially breaking change to introduce, so the planning of how this would be released is something we have to take into consideration. @dnnsoftware/approvers anyone else with thoughts on this?

Copy link
Contributor

@bdukes bdukes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like adding this markup as an option, however I don't think we can change the markup by default, I think it needs to be opt-in (e.g. add a new property for display mode or DisplayAsList or something).

Removed nav and ol tags from breadcrumb control.
Updated the BreadCrumb class to enhance functionality and maintain compatibility with legacy systems. Introduced new properties for cleaner markup and list-based semantic rendering.
@uzmannazari
Copy link
Contributor Author

uzmannazari commented Jan 8, 2026

One note/request included on a change to localization.

Additionally however I do believe this would be a substantially breaking change to introduce, so the planning of how this would be released is something we have to take into consideration. @dnnsoftware/approvers anyone else with thoughts on this?

Totally agree on the breaking-change risk. I’ve updated the implementation so the new semantic/list markup is opt-in via a new property (UseListMarkup, default false).
When UseListMarkup="false" the output stays in the legacy format (to preserve existing skins/CSS), and only when true it renders the <nav>/<ol>/<li> semantic structure.

@uzmannazari
Copy link
Contributor Author

I like adding this markup as an option, however I don't think we can change the markup by default, I think it needs to be opt-in (e.g. add a new property for display mode or DisplayAsList or something).

Agreed — I changed this to opt-in. Added UseListMarkup (default false) so legacy markup remains the default behavior. Setting UseListMarkup="true" enables the semantic list-based breadcrumb output.

@uzmannazari
Copy link
Contributor Author

uzmannazari commented Jan 8, 2026

@bdukes and @mitchelsellers Thanks for the feedback!

I’ve updated the PR to minimize breaking changes and address review notes:

Added UseListMarkup (default false) so legacy output remains the default, and semantic markup is opt-in.

Kept legacy wrapper <span itemprop="breadcrumb" ...> when UseListMarkup=false to preserve existing skin/CSS behavior.

Switched the control output to Literal to avoid invalid nesting; list-mode now starts with<nav>directly.

Localized the aria-label via resx with fallback.

Restored StringComparison.Ordinal, kept doc comments, and ensured tab names are HTML-encoded with AppendFormat usage.

Copy link
Contributor

@mitchelsellers mitchelsellers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry upon further review one small changes suggested.

Avoid intermediate string allocation when initializing breadcrumb StringBuilder
@bdukes bdukes added this to the 10.2.2 milestone Jan 26, 2026
@bdukes bdukes requested a review from valadas January 26, 2026 20:12
Copy link
Contributor Author

@uzmannazari uzmannazari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for commit @bdukes

Copy link
Contributor

@valadas valadas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it!

@valadas
Copy link
Contributor

valadas commented Jan 26, 2026

@mitchelsellers are you good with this?

@mitchelsellers mitchelsellers merged commit 7d85ff4 into dnnsoftware:develop Jan 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Breadcrumb WCAG compliant

4 participants