The issue is replicated in R3 2021 only.
<telerik:RadTabStrip runat="server" ID="RadTabStrip1" >
<Tabs>
<telerik:RadTab Text="Tab 1">
<Tabs>
<telerik:RadTab Text="fail"></telerik:RadTab>
</Tabs>
</telerik:RadTab>
<telerik:RadTab Text="Tab 2"></telerik:RadTab>
<telerik:RadTab Text="Tab 3"></telerik:RadTab>
</Tabs>
</telerik:RadTabStrip>
Solution from Admin:
Place the load/script below somewhere under the ScriptManager. It can be added in the MasterPage if needed:
<script>
Sys.Application.add_init(function fixTabStrip() {
if (Telerik && Telerik.Web && Telerik.Web.UI && Telerik.Web.UI.RadTabStrip) {
Telerik.Web.UI.RadTabStrip.prototype._childInserted = function (index, tab, owner) {
this._allTabs = null;
if (this._cachedSelectedTab) {
owner._setSelectedIndex(this._cachedSelectedTab.get_index());
this._cachedSelectedTab = null;
}
if (tab._cachedSelected) {
owner._setSelectedIndex(index);
tab._cachedSelected = false;
}
Telerik.Web.UI.RadTabStrip.callBaseMethod(this, "_childInserted", [index, tab, owner]);
if (tab.get_isBreak()) {
var breakElement = document.createElement("li");
breakElement.className = "rtsBreak";
owner.get_childListElement().insertBefore(breakElement, tab._element.nextSibling);
}
//if (tab.get_parent() && tab.get_parent() instanceof Telerik.Web.UI.RadTab && tab.get_parent().get_selected()) {
// $telerik.$(tab.get_parent().get_levelElement()).removeClass("rtsHidden");
//}
}
}
});
</script>
JAWS reads Tab selected when the focus is moved between tabs without selection:
<telerik:RadTabStrip ID="RadTabStrip1" runat="server" MultiPageID="RadMultiPage1" EnableAriaSupport="true" RenderMode="Lightweight" SelectedIndex="0" TabIndex="0">
<KeyboardNavigationSettings CommandKey="Alt" />
<Tabs>
<telerik:RadTab runat="server" Text="Root RadTab1">
</telerik:RadTab>
<telerik:RadTab runat="server" Text="Root RadTab2">
</telerik:RadTab>
<telerik:RadTab runat="server" Text="Root RadTab3">
</telerik:RadTab>
<telerik:RadTab runat="server" Text="Root RadTab4">
</telerik:RadTab>
<telerik:RadTab runat="server" Text="Root RadTab5">
</telerik:RadTab>
</Tabs>
</telerik:RadTabStrip>
Accessibility Insights is reporting invalid markup on all tabs in the TabList.
When consulting the online aria specifications I see that elements with role="tablist" support aria-level="#" where number is > 0. (https://www.w3.org/TR/wai-aria-1.2/#tablist) However, elements with role="tab" do not. (https://www.w3.org/TR/wai-aria-1.2/#tab)
If possible, we would like to see the aria-level tag moved to the correct page elements in the next release. (Thanks for correcting the aria-level="0" problem previously.)
I believe this may be the compliance issue Sunil was reporting previously here: https://feedback.telerik.com/aspnet-ajax/1413112-this-ul-should-only-contain-li-elements-without-an-aria-assigned-role.
Few of our clients reported the following issue with respect to WCAG 2.0 SC 4.1.2 standard. (508 Standard and compliance) -
Practice | Function (example) |
Ensure sub-lists are marked up properly | This UL should only contain li elements (without an ARIA-assigned role), script elements (without an ARIA-assigned role) or template elements (without an ARIA-assigned role); or
|
Example: When Telerik Tabstrip has EnableAriaSupport=true, internally tabstrip is combination of ul-li with css to display the Tabs properly -
The html looks like as follows -
<
ul
class
=
"rtsUL"
>
<
li
class
=
"rtsLI rtsFirst"
role
=
"tab"
aria-disabled
=
"false"
aria-level
=
"0"
aria-controls
=
"LayoutPageView"
>
<
a
accesskey
=
"L"
title
=
"Layout"
class
=
"rtsLink rtsBefore"
id
=
"LayoutTab"
href
=
"#"
><
span
class
=
"rtsOut"
>
<
span
class
=
"rtsIn"
>
<
span
class
=
"rtsTxt"
>
<
h2
class
=
"RadTabStrip RadTabStrip_Default"
><
u
>L</
u
>ayout</
h2
>
</
span
>
</
span
>
</
span
>
</
a
>
</
li
>
<
li
class
=
"rtsLI"
role
=
"tab"
aria-disabled
=
"false"
aria-level
=
"0"
aria-controls
=
"SearchPageView"
aria-selected
=
"true"
id
=
"SearchTabStrip_active_tab"
>
<
a
accesskey
=
"S"
title
=
"Search"
class
=
"rtsLink rtsSelected"
id
=
"SearchTab"
href
=
"#"
>
<
span
class
=
"rtsOut"
>
<
span
class
=
"rtsIn"
>
<
span
class
=
"rtsTxt"
>
<
h2
class
=
"RadTabStrip RadTabStrip_Default"
><
u
>S</
u
>earch</
h2
>
</
span
>
</
span
>
</
span
>
</
a
>
</
li
>
<
li
class
=
"rtsLI rtsLast"
role
=
"tab"
aria-disabled
=
"false"
aria-level
=
"0"
aria-controls
=
"ResultsPageView"
>
<
a
accesskey
=
"R"
title
=
"Statewide Search Results 0 records"
class
=
"rtsLink rtsAfter"
id
=
"ResultsTab"
href
=
"#"
>
<
span
class
=
"rtsOut"
>
<
span
class
=
"rtsIn"
>
<
span
class
=
"rtsTxt"
>
<
h2
class
=
"RadTabStrip RadTabStrip_Default"
>Statewide Search<
u
>R</
u
>esults (0)</
h2
>
</
span
>
</
span
>
</
span
>
</
a
>
</
li
>
</
ul
>
Observe the aria attributes which are on li elements. Is that really necessary considering the compliance? (as mentioned in practice and example).
Please let me know when are you going to fix this for compliance.
--
Sunil
Hi Telerik team,
Few of our clients reported the following issue with respect to WCAG 2.0 SC 4.1.2 standard. (508 Standard and compliance) -
Practice | Function (example) |
Ensure ARIA roles, states, and properties are valid | LI has an aria-level attribute of 0, which is not an integer value greater than, or equal to, 1 |
Example: visit https://demos.telerik.com/aspnet-ajax/tabstrip/examples/wai-aria-support/defaultcs.aspx
Observe the ul-li elements created for tabstrip. On each li element, there is aria-level attribute whose value is set to 0.
As per WCAG this value should start from 1. The value 0 is invalid. Refer: https://www.w3.org/TR/WCAG20-TECHS/ARIA12.html
Please let me know when are you going to fix this for compliance.
--
Sunil
Workaround: .rtsDropClueLeft { margin: -0.5em 0 0 -0.75em; } .rtsDropClueLeft:before { content: "\e005"; } .rtsDropClueRight { margin: -0.5em 0 0 -0.25em; } .rtsDropClueRight:before { content: "\e007"; }
When adding a child tab programmatically to a second TabStrip tab that has no child item, the newly created child tab will not show up. Workaround is to remove the class that was hiding the child element: if (selectedTab.get_tabs().get_count() > 0) { $(selectedTab.get_levelElement()).removeClass("rtsHidden"); }
Workaround is attached. It focuses the first focusable element on the page and you can easily change that logic. We have already taken upon ourselves the task of managing the keyboard navigation in a container (the pageview). Please leave your comments how this should be fixed, because there are many options. For example: - we can focus the first focusable element, in a fashion similar to the workaround. Caveat: the list is incomplete, there are more focusable elements. Also, non-sequential tabIndex values set by the developer will not be honored. We may implement logic that counts the tabIndexes and focuses the smallest one, but this is complex, error prone and browsers tend to return bad values for this attribute, especially when it is set to -1. Also, this may not be the desired behavior by the developers. - we can focus the pageview element. Caveat: you may be unable to enter its child inputs at all, depending on the page setup and the tabIndex values. - we can consider setting tabIndex to -1 for all focusable elements in other pageViews akin to the modal backgrounds for controls like window and tooltip. The goal being to let the natural flow of the page take over and the browser to do this job, not our JS code. Caveat: we can still break the navigation logic on the page and this also has low performance when changing many tabIndex attributes at once.
The disabled tabs don't look like disabled in Classic render mode. This issue is not observable with the 2016 release as shown in the attached screenshot. Workarounds: 1) You can change the color of the disabled items by applying the following class to the page: .rtsLink.rtsDisabled { color: #a5a5a5 !important; } 2) Another option is to switch the rendering to Lightweight -> RenderMode="Lightweight".
Observe the below video, demonstrating the issue : http://screencast.com/t/pC1V29UwYQ83 Adding another, not visible textarea to absorb the focus can be used as a workaround: <telerik:RadTabStrip ID="rtsRFT" runat="server" Skin="Office2007" MultiPageID="rmpRTF" SelectedIndex="0" ShowBaseLine="True" OnClientTabSelected="OnClientTabSelected"> <Tabs> <telerik:RadTab Text="Description" TabIndex="61" ToolTip="Click to view description" SelectedCssClass="SelectedTab" PageViewID="pDesription"> </telerik:RadTab> <telerik:RadTab Text="Notes" TabIndex="63" ToolTip="Click to view notes" PageViewID="pNotes"> </telerik:RadTab> </Tabs> </telerik:RadTabStrip> <div class="welcomeTab" style="height: 100%"> <telerik:RadMultiPage ID="rmpRTF" runat="server" SelectedIndex="0"> <telerik:RadPageView ID="pDesription" runat="server"> <div> <telerik:RadEditor ID="txtDescription" runat="server" Width="100%" Height="250px"> </telerik:RadEditor> </div> </telerik:RadPageView> <telerik:RadPageView ID="pNotes" runat="server" Height="100%"> <div> <telerik:RadEditor ID="txtNote" runat="server" Width="100%" Height="250px"> </telerik:RadEditor> </div> </telerik:RadPageView> </telerik:RadMultiPage> </div> <script type="text/javascript"> function OnClientTabSelected(sender, args) { $telerik.$("#inboxId").focus(); } </script>
While it is currently possible to target the first or last item in a RadTabStrip via their CSS classes .rtsFirst and .rtsLast, it is not possible to target individual items, e.g. to add a custom icon or display different background images in tabs. Assigning icons via the ImageURL property is often not feasible, e.g. when using the RadTabStrip-based navigation controls in Sitefinity. Numbering the list items, e.g. .rtsLI1, .rtsLI2, .rtsLI3, etc., would be trivial to implement and provide a lot of flexibility through individual CSS targeting. This also applies to the RadPanelBar and RadMenu controls.