diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js
index 91b0dcfe274ecb..9d77ada45eba33 100644
--- a/packages/block-editor/src/components/writing-flow/index.js
+++ b/packages/block-editor/src/components/writing-flow/index.js
@@ -93,10 +93,18 @@ export function isNavigationCandidate( element, keyCode, hasModifier ) {
* @param {Element} target Currently focused text field.
* @param {boolean} isReverse True if considering as the first field.
* @param {Element} containerElement Element containing all blocks.
+ * @param {boolean} onlyVertical Wether to only consider tabbable elements
+ * that are visually above or under the
+ * target.
*
* @return {?Element} Optimal tab target, if one exists.
*/
-export function getClosestTabbable( target, isReverse, containerElement ) {
+export function getClosestTabbable(
+ target,
+ isReverse,
+ containerElement,
+ onlyVertical
+) {
// Since the current focus target is not guaranteed to be a text field,
// find all focusables. Tabbability is considered later.
let focusableNodes = focus.focusable.find( containerElement );
@@ -112,12 +120,29 @@ export function getClosestTabbable( target, isReverse, containerElement ) {
focusableNodes.indexOf( target ) + 1
);
+ let targetRect;
+
+ if ( onlyVertical ) {
+ targetRect = target.getBoundingClientRect();
+ }
+
function isTabCandidate( node, i, array ) {
// Not a candidate if the node is not tabbable.
if ( ! focus.tabbable.isTabbableIndex( node ) ) {
return false;
}
+ if ( onlyVertical ) {
+ const nodeRect = node.getBoundingClientRect();
+
+ if (
+ nodeRect.left >= targetRect.right ||
+ nodeRect.right <= targetRect.left
+ ) {
+ return false;
+ }
+ }
+
// Prefer text fields...
if ( isTextField( node ) ) {
return true;
@@ -517,7 +542,8 @@ export default function WritingFlow( { children } ) {
const closestTabbable = getClosestTabbable(
target,
isReverse,
- container.current
+ container.current,
+ true
);
if ( closestTabbable ) {
diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap
index c3545a01d8254d..fc9d85e415e5cc 100644
--- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap
+++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap
@@ -53,3 +53,9 @@ exports[`Table displays a form for choosing the row and column count of the tabl
"
`;
+
+exports[`Table up and down arrow navigation 1`] = `
+"
+