Skip to content

Commit

Permalink
Add support for allowing elements with display:contents to be focused.
Browse files Browse the repository at this point in the history
Chromestatus: https://chromestatus.com/feature/6237396851228672

This lands support for allowing elements with display:contents to be
focused, behind a feature flag that is created with status:experimental.

This is as concluded (though without a group resolution) in
w3c/csswg-drafts#2632 and as discussed a bit
in whatwg/html#1837 and proposed in
whatwg/html#9425 .  Note that this diverges from
Gecko (see https://bugzil.la/1553549, https://bugzil.la/1791648, and
mozilla/standards-positions#772) and WebKit
(see https://bugs.webkit.org/show_bug.cgi?id=255149 and
WebKit/standards-positions#164).

This makes the <slot> element focusable when it has a tabindex.  Note
that this does not match Gecko and WebKit, which also require that its
'display' value is changed (away from 'contents') to make it focusable.

Note that the <slot> element is still not tabbable in Chrome; this is
https://crbug.com/1428419.  This also does not match Gecko and WebKit,
where it is tabbable whenever it is focusable.  The added test
slot-element-tabbable.tentative.html fails both tests as a result, but
is added anyway.  (Gecko and WebKit pass the display: block test but
fail the default style (display: contents) test.)

The added tests display-contents-focusable-001.html and
slot-element-focusable.tentative.html are partly fixed by this change,
but the style part is still broken due to https://crbug.com/1428420.

Fixed: 1366037
Bug: 1428419, 1428420
Change-Id: I46a8ad3b6442ce07f440c8f6a07210bac305600e
  • Loading branch information
dbaron authored and chromium-wpt-export-bot committed Jan 24, 2024
1 parent 710c09a commit b047b57
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 6 deletions.
41 changes: 41 additions & 0 deletions css/css-display/display-contents-focusable-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<title>CSS Test (Display): Elements with display:contents should be focusable</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-display-3/#box-generation">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2632">
<link rel="help" href="https://github.com/whatwg/html/issues/1837">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366037">
<!--
This requirement may not be crystal-clear from specs, but discussion
in https://github.com/w3c/csswg-drafts/issues/2632 concluded it was
correct and that no spec changes were needed.
-->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>

#test { --test-var: 4; }
#test:focus { --test-var: 6; }

</style>

<div id="test" style="display: contents" tabindex="1">Hello</div>

<script>

test(
function() {
var e = document.getElementById("test");
var cs = getComputedStyle(e);
assert_not_equals(document.activeElement, e, "precondition");
assert_equals(cs.getPropertyValue("--test-var"), "4", "precondition (style)");
e.focus();
assert_equals(document.activeElement, e, "e is now focused");
assert_equals(cs.getPropertyValue("--test-var"), "6", "e is now focused (style)");
}, "element with display:contents is focusable");

</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<title>CSS Test (Display): <slot> elements should be focusable</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2632">
<link rel="help" href="https://github.com/whatwg/html/issues/1837">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366037">
<!--
This requirement is not particularly clear from current specs,
so this test is tentative. See issues above.
-->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<body>

<script>

function do_test(slot_style, description) {
test(
function() {
let host = document.createElement("div");
document.body.appendChild(host);
var root = host.attachShadow({mode:"open"});
root.innerHTML = `
<style>
slot { --test-value: 3; }
slot:focus { --test-value: 7; }
</style>
<slot tabindex="1" style="${slot_style}"></slot>
`;
let slot = root.querySelector("slot");
let cs = getComputedStyle(slot);
assert_not_equals(root.activeElement, slot, "precondition");
assert_equals(cs.getPropertyValue("--test-value"), "3", "precondition (style)");
slot.focus();
assert_equals(root.activeElement, slot, "slot is now focused");
assert_equals(cs.getPropertyValue("--test-value"), "7", "slot is now focused (style)");
document.body.removeChild(host);
}, `slot element with ${description} should be focusable`);
}

do_test("display: block", "display: block");
do_test("", "default style");

</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<title>CSS Test (Display): <slot> elements should be tabbable</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2632">
<link rel="help" href="https://github.com/whatwg/html/issues/1837">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366037">
<!--
This requirement is not particularly clear from current specs,
so this test is tentative. See issues above.
-->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>

<body>

<div id="before" tabindex="1" style="height: 10px"></div>

<script>

function do_test(slot_style, description) {
promise_test(
async () => {
let before = document.getElementById("before");
before.focus();
let host = document.createElement("div");
document.body.appendChild(host);
var root = host.attachShadow({mode:"open"});
root.innerHTML = `
<style>
slot { --test-value: 3; }
slot:focus { --test-value: 7; }
</style>
<slot tabindex="1" style="${slot_style}"></slot>
`;
let slot = root.querySelector("slot");
let cs = getComputedStyle(slot);
assert_equals(document.activeElement, before, "precondition");
assert_not_equals(root.activeElement, slot, "precondition");
assert_equals(cs.getPropertyValue("--test-value"), "3", "precondition (style)");
await test_driver.send_keys(before, "\uE004");
assert_equals(root.activeElement, slot, "slot is now focused");
assert_equals(cs.getPropertyValue("--test-value"), "7", "slot is now focused (style)");
document.body.removeChild(host);
}, `slot element with ${description} should be focusable`);
}

do_test("display: block", "display: block");
do_test("", "default style");

</script>

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
<link rel="help" href="https://github.com/whatwg/html/issues/7534">
<meta name="assert" content="Checks that elements being used as relevant canvas
fallback content can't be focusable if they are not rendered because of an
explicit 'display: none' or 'display: contents' style.">
explicit 'display: none' style, but can if they are not rendered because of
a 'display: contents' style.">
<div id="log"></div>
<canvas>
<button hidden data-focusable="false"></button>
Expand All @@ -16,11 +17,11 @@
<span tabindex="-1" data-focusable="false"></span>
<a href="#" data-focusable="false"></a>
</section>
<button style="display: contents" data-focusable="false"></button>
<section style="display: contents" tabindex="-1" data-focusable="false">
<div style="display: contents" tabindex="-1" data-focusable="false"></div>
<span style="display: contents" tabindex="-1" data-focusable="false"></span>
<a style="display: contents" href="#" data-focusable="false"></a>
<button style="display: contents" data-focusable="true"></button>
<section style="display: contents" tabindex="-1" data-focusable="true">
<div style="display: contents" tabindex="-1" data-focusable="true"></div>
<span style="display: contents" tabindex="-1" data-focusable="true"></span>
<a style="display: contents" href="#" data-focusable="true"></a>
</section>
</canvas>
<script src="/resources/testharness.js"></script>
Expand Down

0 comments on commit b047b57

Please sign in to comment.