The sub-menu of Your details and Your career names the section you are in #677

Closed
opened 2026-10-03 01:58:54 +00:00 by tiagoagueda · 0 comments
Owner

On Your details and on Your career the sidebar is headed “On this page” however far down you have read. The maintainer's list asks for the title of the section instead, when that title is no longer on the screen: "Sub-menu should display section title instead of “On this page”, when title is not on screen" (the same line is under Your details and under Your career).

What exists today

  • Both pages draw the same sidebar: <p> with the fixed text “On this page”, then {% sidebar section_nav … %} (src/postulo/templates/accounts/profile.html:30-35, src/postulo/templates/resume/overview.html:31-36). The aside is lg:sticky lg:top-[calc(var(--header-height,3.5rem)+1rem)], so from lg up it stays in view while the sections scroll; below lg it is a horizontal strip above the sections and scrolls away with them.
  • The list is partials/sidebar.html: a <nav aria-label="…"> of anchors, each with data-section-link="<section id>". The nav's accessible name is “Parts of your details” or “Career sections”; the visible “On this page” is a separate paragraph, not a heading and not part of that name.
  • app.js already answers “which section is being read”: the observer at src/postulo/static/js/app.js:2730-2794 picks the last section whose top has passed a line two-fifths down the part of the window not under the header, treats the last section as current at the bottom of the page, and sets aria-current="location" and the nav-link-active class on its link. It never touches the label. With scripts off the list still navigates and says nothing about where you are.
  • Each section has a title, but not one element type: the career page uses <h2> in <section id="section-<slug>"> (overview.html:39-41); Your details uses <c-section-title> (an <h2>, templates/cotton/section_title.html) for Your picture, Your name and Contact block, and a <legend class="label"> in a <fieldset> for Telephone numbers, Postal addresses, Identifiers and each link block (partials/phone_numbers.html:23-24, partials/postal_addresses.html:27-28, partials/web_links.html:15-16, profile.html:186-187). The entry's text in the sidebar is the same string as that title.
  • The sections can be long: a list has no ceiling (overview.html), so with twenty experiences the title of Experience is several screens above the part being read, and the label still says “On this page”.
  • The two other sidebars (Settings, Server settings) are headed with the area's name, a fixed string, and list pages, not sections (settings/base.html:16-18, server/base.html:11-13); they are not part of this issue (see #699 for Server settings).
  • Reduced motion is already a global rule (assets/css/app.css:1826-1834); this change has no motion to reduce as long as it stays a text swap. A narrow screen has a precedent for reacting to the breakpoint from script (app.js:1428, matchMedia("(min-width: 64rem)")).

Checked against main at f09b6010b.

Proposal

  1. A hook on the label. The <p> above the list gets data-section-label in both templates. “On this page” stays in the template as the text scripts-off visitors see, and is what script restores; the script holds no English (the rule the live regions in base.html already follow).
  2. Extend the existing observer, not a second one. In the pass that already finds the current section: if its own title element (the first h2 or legend inside it) has scrolled up past the bottom of the masthead, the label's text becomes that title's text; otherwise it is the original text again. Only from lg up, where the aside sticks; below that the label is left alone, and the media query is listened to so a resize back restores it.
  3. No announcement. The label is not a live region and does not become one, or a screen reader would speak on every scroll. The change of section is already carried by aria-current="location", which stays as it is. The nav keeps its own accessible name.
  4. No script, no change. With scripts off the label stays “On this page” and the anchors work as they do.
  5. Long titles wrap. The label is not truncated: ellipsis would hide text under the text-spacing override (SC 1.4.12), the reason base.html gives for not truncating the address in the account menu. A title that takes two lines moves the list by a line at the moment the label changes; see the decision below.

Decisions

  • Which title. The list's wording, "section title … when title is not on screen", can be read two ways. (a) The title of the section being read, as above. (b) The page's own title, “Your details” or “Your career”, shown once the <h1> has scrolled away, as Settings and Server settings already head their sidebar with the name of the area. Recommended: (a), the only reading that follows the reader down a long page; the page's name is in the tab title already. It repeats, above the list, the entry the list highlights below it, which is what the list asks for. If (b) was meant it is a smaller change (one more condition on the same observer) and the Decision becomes only which string.
  • When the section's own title is on screen. Keep “On this page”, or show the title anyway. Recommended: keep “On this page”, because the title is then in view beside it; this is what the list says ("when title is not on screen").
  • The label under a short window. Where the section is taller than the window and its title never returns, the label keeps its title until the next section takes over. Recommended: that, nothing cleverer.
  • Reserved height. Reserve two lines so the list never shifts, or let the list move when a long title wraps. Recommended: let it move; a reserved gap would be an empty line on every page for the sake of a few long titles in a few languages, and the aside's own width (14rem) is the only thing that decides. The text-spacing and reflow e2e cases check it still reads.
  • The strip on a phone. Below lg the label scrolls away with the aside, so there is nothing to keep in view. Recommended: leave it as it is.

Builds on

#175 (the sections as anchors and the observer), #180 (Your details in parts), #195 (the floating header and --header-height). Related: #676 puts Your career in the account menu and touches the same two templates; the two are independent.

Done when

  • On /career/ and /accounts/profile/ at 1280 pixels wide, scrolling until a section's title is behind the masthead makes the label that title, and scrolling back up restores “On this page”; at 390 pixels wide the label does not change. New cases in tests/e2e/test_career_sections.py (the career page, which already has the fixture and the viewport helpers) and a counterpart for Your details.
  • With scripts off the label is “On this page” and the anchors still navigate (the same file, with browser.new_context(java_script_enabled=False) as the e2e suite does elsewhere); with prefers-reduced-motion: reduce nothing animates (there is nothing to animate).
  • aria-current="location" still follows the section, and there is no aria-live on the label. tests/test_career_sections.py and tests/test_profile_sections.py are extended to pin the data-section-label hook on both pages and that the static text is still in the HTML.
  • Text-spacing and 400% zoom still show the whole title (tests/e2e/test_text_spacing.py, tests/e2e/test_reflow.py), and the axe run over both pages (tests/e2e/test_accessibility.py, lines 487 and 491) is clean in both themes.
  • No new string: the label's text is whatever the page already holds, so the catalogues and Weblate (#349) need nothing.

From the list of improvements of 2026-10-02.

On Your details and on Your career the sidebar is headed “On this page” however far down you have read. The maintainer's list asks for the title of the section instead, when that title is no longer on the screen: "Sub-menu should display section title instead of “On this page”, when title is not on screen" (the same line is under Your details and under Your career). ## What exists today - Both pages draw the same sidebar: `<p>` with the fixed text “On this page”, then `{% sidebar section_nav … %}` (`src/postulo/templates/accounts/profile.html:30-35`, `src/postulo/templates/resume/overview.html:31-36`). The aside is `lg:sticky lg:top-[calc(var(--header-height,3.5rem)+1rem)]`, so from `lg` up it stays in view while the sections scroll; below `lg` it is a horizontal strip above the sections and scrolls away with them. - The list is `partials/sidebar.html`: a `<nav aria-label="…">` of anchors, each with `data-section-link="<section id>"`. The nav's accessible name is “Parts of your details” or “Career sections”; the visible “On this page” is a separate paragraph, not a heading and not part of that name. - `app.js` already answers “which section is being read”: the observer at `src/postulo/static/js/app.js:2730-2794` picks the last section whose top has passed a line two-fifths down the part of the window not under the header, treats the last section as current at the bottom of the page, and sets `aria-current="location"` and the `nav-link-active` class on its link. It never touches the label. With scripts off the list still navigates and says nothing about where you are. - Each section has a title, but not one element type: the career page uses `<h2>` in `<section id="section-<slug>">` (`overview.html:39-41`); Your details uses `<c-section-title>` (an `<h2>`, `templates/cotton/section_title.html`) for Your picture, Your name and Contact block, and a `<legend class="label">` in a `<fieldset>` for Telephone numbers, Postal addresses, Identifiers and each link block (`partials/phone_numbers.html:23-24`, `partials/postal_addresses.html:27-28`, `partials/web_links.html:15-16`, `profile.html:186-187`). The entry's text in the sidebar is the same string as that title. - The sections can be long: a list has no ceiling (`overview.html`), so with twenty experiences the title of Experience is several screens above the part being read, and the label still says “On this page”. - The two other sidebars (Settings, Server settings) are headed with the area's name, a fixed string, and list pages, not sections (`settings/base.html:16-18`, `server/base.html:11-13`); they are not part of this issue (see #699 for Server settings). - Reduced motion is already a global rule (`assets/css/app.css:1826-1834`); this change has no motion to reduce as long as it stays a text swap. A narrow screen has a precedent for reacting to the breakpoint from script (`app.js:1428`, `matchMedia("(min-width: 64rem)")`). Checked against `main` at `f09b6010b`. ## Proposal 1. **A hook on the label.** The `<p>` above the list gets `data-section-label` in both templates. “On this page” stays in the template as the text scripts-off visitors see, and is what script restores; the script holds no English (the rule the live regions in `base.html` already follow). 2. **Extend the existing observer, not a second one.** In the pass that already finds the current section: if its own title element (the first `h2` or `legend` inside it) has scrolled up past the bottom of the masthead, the label's text becomes that title's text; otherwise it is the original text again. Only from `lg` up, where the aside sticks; below that the label is left alone, and the media query is listened to so a resize back restores it. 3. **No announcement.** The label is not a live region and does not become one, or a screen reader would speak on every scroll. The change of section is already carried by `aria-current="location"`, which stays as it is. The nav keeps its own accessible name. 4. **No script, no change.** With scripts off the label stays “On this page” and the anchors work as they do. 5. **Long titles wrap.** The label is not truncated: ellipsis would hide text under the text-spacing override (SC 1.4.12), the reason `base.html` gives for not truncating the address in the account menu. A title that takes two lines moves the list by a line at the moment the label changes; see the decision below. ## Decisions - **Which title.** The list's wording, "section title … when title is not on screen", can be read two ways. (a) The title of the section being read, as above. (b) The page's own title, “Your details” or “Your career”, shown once the `<h1>` has scrolled away, as Settings and Server settings already head their sidebar with the name of the area. **Recommended:** (a), the only reading that follows the reader down a long page; the page's name is in the tab title already. It repeats, above the list, the entry the list highlights below it, which is what the list asks for. If (b) was meant it is a smaller change (one more condition on the same observer) and the Decision becomes only which string. - **When the section's own title is on screen.** Keep “On this page”, or show the title anyway. **Recommended:** keep “On this page”, because the title is then in view beside it; this is what the list says ("when title is not on screen"). - **The label under a short window.** Where the section is taller than the window and its title never returns, the label keeps its title until the next section takes over. **Recommended:** that, nothing cleverer. - **Reserved height.** Reserve two lines so the list never shifts, or let the list move when a long title wraps. **Recommended:** let it move; a reserved gap would be an empty line on every page for the sake of a few long titles in a few languages, and the aside's own width (14rem) is the only thing that decides. The text-spacing and reflow e2e cases check it still reads. - **The strip on a phone.** Below `lg` the label scrolls away with the aside, so there is nothing to keep in view. **Recommended:** leave it as it is. ## Builds on #175 (the sections as anchors and the observer), #180 (Your details in parts), #195 (the floating header and `--header-height`). Related: #676 puts Your career in the account menu and touches the same two templates; the two are independent. ## Done when - On `/career/` and `/accounts/profile/` at 1280 pixels wide, scrolling until a section's title is behind the masthead makes the label that title, and scrolling back up restores “On this page”; at 390 pixels wide the label does not change. New cases in `tests/e2e/test_career_sections.py` (the career page, which already has the fixture and the viewport helpers) and a counterpart for Your details. - With scripts off the label is “On this page” and the anchors still navigate (the same file, with `browser.new_context(java_script_enabled=False)` as the e2e suite does elsewhere); with `prefers-reduced-motion: reduce` nothing animates (there is nothing to animate). - `aria-current="location"` still follows the section, and there is no `aria-live` on the label. `tests/test_career_sections.py` and `tests/test_profile_sections.py` are extended to pin the `data-section-label` hook on both pages and that the static text is still in the HTML. - Text-spacing and 400% zoom still show the whole title (`tests/e2e/test_text_spacing.py`, `tests/e2e/test_reflow.py`), and the axe run over both pages (`tests/e2e/test_accessibility.py`, lines 487 and 491) is clean in both themes. - No new string: the label's text is whatever the page already holds, so the catalogues and Weblate (#349) need nothing. From the list of improvements of 2026-10-02.
tiagoagueda added this to the 0.5.0 milestone 2026-10-03 01:58:54 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#677
No description provided.