NVDA's elements list doesn't recognize the <nav> in a <header> if it's the first direct child - header

Has anyone experienced this, and if so, do you have an explanation and/or solution? Basically, if you have the following markup, the "Primary" nav won't be recognized in NVDA unless there's a non-nav element preceding it.
<header role="banner">
<nav role="navigation" aria-label="Primary">...</nav>
</header>

It's perfectly valid HTML to nest a <nav> element within a <heading> element, and there are no sematic issues with doing so.
That said, NVDA doesn't appear to display elements in the "Landmarks List" if they are children of other landmark elements.
NVDA will see and announce your <nav> element within the <header>, but only if you manually step through the page content.
This means that if you nest a <nav> within a <header>, only the top-level element (in this case <header> would be visible in the "Landmarks List", and the child-element would not be accessible by cycling through landmarks with keyboard shortcuts.
If it were me, I would probably move the <nav> element outside the <header>, but neither way is technically wrong.

Related

Why are Vue dynamic components destroyed inside loop every re-render?

I run into an issue with Vuejs 2.x version (latest). While rendering a list of item inside a loop, if I make changes to the items then the normal components are not destroyed but the dynamic components will always be destroyed:
I have put a short sample code here:
https://gist.github.com/yellow1912/fc1c053e07c1ca136148484cf7f79d1a
I have also put a codepen here:
https://codepen.io/raineng/pen/zYGOXYY?editors=1111
<nl-test inline-template>
<div>
<div v-on:click="increase"> increase here please </div><br><br>
<div v-on:click="decrease"> decrease here please </div>
<ul>
<li v-for="(value, key) in getItems()" :key="key">
printing
<component :is="getItem()" :key="key"></component>
<nl-test inline-template>
<div>
this is a test here
</div>
</nl-test>
</li>
</ul>
</div>
</nl-test>
To see what I mean, open the console tab on codepen, click the add item and you will see that the dynamic component items are destroyed and re-created everytime.
I found out why, I need to use keep-alive:
https://v2.vuejs.org/v2/guide/components-dynamic-async.html
To quote:
When switching between these components though, you’ll sometimes want
to maintain their state or avoid re-rendering for performance reasons
Recreating dynamic components is normally useful behavior, but in this
case, we’d really like those tab component instances to be cached once
they’re created for the first time. To solve this problem, we can wrap
our dynamic component with a element
Wasted 2 days on this issue and then I found the answer just a moment after posting this on StackOverflow. Hope it helps someone.

VueJS: <template> vs <div> or related for grouping elements for conditional rendering

In Vue.js, if you want to conditionally render multiple elements via a v-if/v-else-if directive you can wrap them inside <template> tags and apply the directive to the <template> tag, as explained here. However, you can also do the same with <div> tags wrapping the multiple elements. Are there any noticeable performance benefits to using <template> over <div> or any other similar native HTML5 tag?
I doubt there is a performance change but a big difference is that the <template> node does not appear in the DOM.
This is an important distinction especially when grouping children that are the only valid node types for their parent such as list items, table rows, etc:
This is valid:
<ul>
<template v-if="something">
<li>Text</li>
<li>Text</li>
</template>
</ul>
This is not:
<ul>
<div v-if="something">
<li>Text</li>
<li>Text</li>
</div>
</ul>
I know that the question is quite old, but I found out one more thing
if you use divs - your div will be in DOM, but empty, if v-if is false and it can make some spaces looks like margins
if you use template - you don't have anything in DOM and it just don't appear

Oddity with templates and root node with vue.js

I think this is possibly a bug I've stumbled across, not sure. I'm getting this Vue.js warning for a component:
vue.js:2611 [Vue warn]: Cannot use <template> as component root element because it may contain multiple nodes:
The problem seems to be this:
<template id="tpl-field">
<template v-if="fieldType==='checkbox-inline'">
<label class="checkbox-inline">[SNIP]</label>
</template>
<template v-else>
[SNIP]
</template>
</template>
So I have two template nodes, which seems to be the multiple nodes it's choking on (certainly each of the template nodes contains just a single node). Yet this is an if-else in Vue - if one of the nodes is present, the other logically cannot be.
Demo of the problem here: https://jsfiddle.net/jonmor51/Ldz3k0jp/1/. If I wrap everything in a div, it works. But without, it fails. (Unfortunately, in the context where I want to use this, namely for inline checkboxes within a Bootstrap grid, wrapping in a div breaks things).
Not sure if this will solve your problem with bootstrap... but you could wrap you inner templates with a <transition> tag and set a key to each one.
Please check this working fiddle
https://jsfiddle.net/AldoRomo88/7c7znu3p/
helpful thing - just use div display: contents as a root of the component and browser will ignore that element and consider child elements (which can be many) as children of upper dom element
<div style="display: contents">
<template v-if="...">
<template v-for="..."> ...
</template>
<template v-if="...">
</template>
</div
works even inside tables!
The inner templates direct children, are they single elements? If so, you can just remove the inner templates and move v-if to the label.
Or, just use span rather than div as your quick fix, which won't break inline elements' style.

twitter bootstrap, container class is not nestable

The documentation of the bootstrap 3 container class states that 'due to padding and more, neither container is nestable".
But then, in the official examples, take this, a demo of a simple navbar, we see something like:
<body>
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
where a container-fluid is clearly nested inside a a container.
My understanding of the "neither container is nestable" sentence is that we should have just one container in a page, or on the other hand we can have multiple if they are not nested one within the other.
Seeing the examples it doesn't seem to be the case, then what does it mean that constraint? I've read also this question and some others but they don't talk about the nesting thing.
This has been brought up as in issue on the Bootstrap repo:
https://github.com/twbs/bootstrap/issues/15512
I'm not sure if the doc will be updated accordingly, but as you'll see in the issue it looks like it's ok to put a container-fluid inside a container.

Multiple aria role "navigation" and "complementary"?

In a document, there are multiple <nav> and <aside> elements. Should I add role="navigation" on all <nav>s and role="complementary" on all <aside>s?
In other words, is it more beneficial or more redundant that there are multiple <nav role="navigation">...</nav>s and multiple <aside role="complementary">...</aside>s in a document?
According to the HTML5 spec, role="navigation" is implicit to the <nav> element, and role="complementary" is implicit to the <aside> element. As such, you do not need to add them according to the spec.
The question is how many ATs actually honor the spec, so if you want to play it safe, you can add those roles, it won't hurt.
Also rememebr that some <aside> elements should however be marked as role=note.
Another thing to consider is that the HTML5 spec allows multiple seperate <ul>s to be grouped under a <nav>. I am uncertain if this implies that role="navigation" is enough on just the <nav> or that each <ul> should be marked as such. I am unable to find any information on this.