Answer to the Core Question
Placing <VSkipLink> as the first focusable element in the DOM guarantees that it will receive focus before any VAppBar, drawer or dialog content when those components are rendered in their default slots. The guarantee holds as long as overlay content is not teleported to a different part of the DOM that precedes the skip link.
When the skip link is rendered inside <VAppBar>, its position in the tab order is determined by the relative order of the <VAppBar> in the template and any focusable nodes that appear before it. If a drawer or dialog is opened and its content is teleported to <body> (the default for Vuetify 3), that content will appear after the skip link in the DOM, so the skip link still comes first. However, if the overlay content is conditionally rendered before the <VAppBar> or if a custom portal target places it before the skip link, the tab order can shift.
Why the Difference Matters
- First‑DOM placement aligns with WCAG bypass blocks guidance by ensuring the skip link is the very first focusable element.
- Inside VAppBar keeps the skip link visually consistent with the app chrome and allows it to inherit Vuetify theme styling, but it can be out of sync with the tab order if overlay content is inserted before the
<VAppBar> in the DOM or if teleportation changes the actual rendering order.
Practical Verification Steps
- Build a minimal test page. Include
<VApp>, <VAppBar>, <VNavigationDrawer>, <VDialog>, and a <VSkipLink> as the first element in the template.
<template>
<VApp>
<VSkipLink>Skip to main content</VSkipLink>
<VAppBar>…</VAppBar>
<VNavigationDrawer>…</VNavigationDrawer>
<VDialog>…</VDialog>
</VApp>
</template>
- Open the page in a browser. Press Tab repeatedly and observe which element receives focus first. The skip link should be the first focusable element.
- Move the
<VSkipLink> inside the <VAppBar>.
<VAppBar>
<VSkipLink>Skip to main content</VSkipLink>
…
</VAppBar>
- Open the navigation drawer and a dialog. Verify whether any focusable elements from those overlays appear before the skip link in the tab order. If they do, the skip link is no longer the first focusable element.
- Inspect the final DOM. Use dev‑tools to confirm that the skip link’s position is unchanged and that no teleport or portal has moved overlay content before it.
Recommendation
For the most reliable keyboard‑only navigation, place <VSkipLink> as the first focusable element in the DOM. If visual consistency with the app chrome is a higher priority, keep the skip link inside <VAppBar> but add a duplicate, visually hidden skip link at the top of the template to guarantee reachability.
Missing Diagnostic Detail
To fine‑tune the recommendation for your specific project, could you confirm whether your <VNavigationDrawer> or <VDialog> components use a custom portal-target that renders their content before the <VSkipLink> in the DOM?