Skip to content

Commit

Permalink
Merge pull request #1848 from IBMa/dev-1610
Browse files Browse the repository at this point in the history
fixrule(`element_tabbable_visible`): Reduce "Needs review" on custom checkbox and radio buttons
  • Loading branch information
ErickRenteria authored Mar 11, 2024
2 parents 565f70c + 8cbb587 commit 23aa10d
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export let element_tabbable_visible: Rule = {
"en-US": {
"group": "A tabbable element should be visible on the screen when it has keyboard focus",
"pass": "The tabbable element is visible on the screen",
"potential_visible": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus"
"potential_visible": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus"
}
},
rulesets: [{
Expand All @@ -58,11 +58,32 @@ export let element_tabbable_visible: Rule = {
const defined_styles = getDefinedStyles(ruleContext);
const onfocus_styles = getDefinedStyles(ruleContext, ":focus");

if (bounds['height'] === 0 || bounds['width'] === 0
|| (defined_styles['position']==='absolute' && defined_styles['clip'] && defined_styles['clip'].replaceAll(' ', '')==='rect(0px,0px,0px,0px)'
&& !onfocus_styles['clip']))
if (bounds['height'] === 0 || bounds['width'] === 0)
return RulePotential("potential_visible", []);

if (defined_styles['position']==='absolute' && defined_styles['clip'] && defined_styles['clip'].replaceAll(' ', '')==='rect(0px,0px,0px,0px)'
&& !onfocus_styles['clip']) {
/**
* note that A user can select a checkbox and radio button by selecting the button or the label text.
* When a checkbox or radio button is clipped to 0 size, it is still available to a keyboard or a screen reader.
* The rule should be passed if the label text exists and the button on-focus style is defined by the user,
* which likely incurs the changes of the label style.
*/
if (nodeName === 'input' && (ruleContext.getAttribute('type')==='checkbox' || ruleContext.getAttribute('type')==='radio')) {
const label = RPTUtil.getLabelForElement(ruleContext);
if (label && !RPTUtil.isInnerTextEmpty(label)) {
const focus_styles = getDefinedStyles(ruleContext, ":focus");
const focus_visible_styles = getDefinedStyles(ruleContext, ":focus-visible");
const focus_within_styles = getDefinedStyles(ruleContext, ":focus-within");
const checked_styles = getDefinedStyles(ruleContext, ":checked");

if (focus_styles || focus_visible_styles || focus_within_styles || checked_styles)
return RulePass("pass");
}
}
return RulePotential("potential_visible", []);
}

if (bounds['top'] >= 0 && bounds['left'] >= 0)
return RulePass("pass");

Expand Down
5 changes: 4 additions & 1 deletion accessibility-checker-engine/src/v4/util/CSSUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,14 @@ export function getComputedStyle(elem: HTMLElement, pseudoElt?: PseudoClass) {
* for example, for 'transform: rotate(2.5deg);', the computed style returns 'matrix(-0.0436194, 0.999048, -0.999048, -0.0436194, 0, 0)'
* and the defined style returns 'rotate(2.5deg)'
*
* change the type of the parameter pseudoClass from PseudoClass to string to include both pseudo classes (e.g., :focus, :checked)
* and pseudo elements (e.g., ::before, ::after).
*
* @param {HTMLElement} elem
* @param {string} [pseudoClass] If specified, will return values that are different
* than when the pseudoClass does not match.
*/
export function getDefinedStyles(elem: HTMLElement, pseudoClass?: PseudoClass) {
export function getDefinedStyles(elem: HTMLElement, pseudoClass?: string ) {
// console.log("Function: getDefinedStyles");
let definedStyles = {};
let definedStylePseudo = {};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--
/******************************************************************************
Copyright:: 2020- IBM, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
-->

<html lang="en">

<head>
<title>Test Example</title>
<style>
.catalog--checkbox {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
white-space: nowrap;
border: 1px;
visibility: inherit;
clip: rect(0,0,0,0);
display: block;

}

.catalog--checkbox-label-text::before {
position: absolute;
top: 0.125rem;
left: 0;
width: 1rem;
height: 1rem;
border: 1px solid var(--cds-icon-01, #161616);
margin: 0.125rem 0.125rem 0.125rem 0.1875rem;
background-color: rgba(0,0,0,0);
border-radius: 1px;
display:block;
content: "";
}

</style>
</head>

<body>

<div>
<input type="checkbox" class="catalog--checkbox" id="catalog">
<label for="catalog" class="catalog--checkbox-label-text">iOS</label>
</div>
<script>
UnitTest = {
ruleIds: ["element_tabbable_visible"],
results: [
{
"ruleId": "element_tabbable_visible",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/div[1]/input[1]",
"aria": "/document[1]/checkbox[1]"
},
"reasonId": "pass",
"message": "The tabbable element is visible on the screen",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>

</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"aria": "/document[1]/button[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand All @@ -78,7 +78,7 @@
"aria": "/document[1]/link[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ <h3>Elements Tests</h3>
"aria": "/document[1]/button[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand All @@ -65,7 +65,7 @@ <h3>Elements Tests</h3>
"aria": "/document[1]/link[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"aria": "/document[1]/link[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
UnitTest = {
ruleIds: ["element_tabbable_visible"],
results: [
{
{
"ruleId": "element_tabbable_visible",
"value": [
"INFORMATION",
Expand All @@ -58,11 +58,11 @@
"aria": "/document[1]/link[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
}
]
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h3>Elements Tests</h3>
"aria": "/document[1]/button[1]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand All @@ -81,7 +81,7 @@ <h3>Elements Tests</h3>
"aria": "/document[1]/button[2]"
},
"reasonId": "potential_visible",
"message": "Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus",
"message": "Confirm the element should be tabbable and if so, it becomes visible when it has keyboard focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--
/******************************************************************************
Copyright:: 2020- IBM, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
-->

<html lang="en">

<head>
<title>Test Example</title>
<style>
.catalog--radio {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;

}

.catalog--radio-label-text {
flex: auto;
background-color: #FFF;
color: #1E69A6;
text-align: center;
padding: 4px 8px;
border: 1px solid #999CA0;
border-radius: 0;
transition: all 0.2s ease-in-out;
}

</style>
</head>

<body>

<div>
<input type="radio" class="catalog--radio" id="catalog">
<label for="catalog" class="catalog--radio-label-text">iOS</label>
</div>
<script>
UnitTest = {
ruleIds: ["element_tabbable_visible"],
results: [
{
"ruleId": "element_tabbable_visible",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/div[1]/input[1]",
"aria": "/document[1]/radio[1]"
},
"reasonId": "pass",
"message": "The tabbable element is visible on the screen",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>

</body>

</html>

0 comments on commit 23aa10d

Please sign in to comment.