# Custom keys > Arrows are the default, not the rule — rebinding the next and previous keys to any key combo. Nothing about keyrove is tied to the arrow keys. The keys that move focus are attributes on the root, and `ArrowDown` / `ArrowUp` are simply what they fall back to. `data-keyrove-next-key` and `data-keyrove-prev-key` rebind them to any [`KeyboardEvent.code`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code), with or without [modifiers](#modifiers). A toolbar, for one, navigates left-to-right rather than up-and-down. move between the buttons here; the up and down arrows are left to scroll the page. ```html
``` ```html
``` Rebinding is a markup change and nothing else — the `keyRove(e)` call is identical whatever the group answers to. For exactly this pair there is a more idiomatic spelling: `data-keyrove-orientation="horizontal"` maps the defaults to `ArrowRight`/`ArrowLeft` and flips them under RTL, so the "forward" arrow follows the text direction instead of being hardcoded. Reach for the explicit key attributes when the keys are anything other than the reading-direction arrows — they win over orientation wherever both are set. ## Any key, not a shortlist The attribute value is a combo — an optional set of modifiers and a `KeyboardEvent.code` — matched against the event on every press, so there is no set of supported keys to choose from: ```html ``` Each root is read on its own, so two groups on the same page can answer to completely different keys with one delegated listener serving both. ## Modifiers Prefix the code with any of `mod+`, `ctrl+`, `alt+`, `shift+`, `meta+` — in any order and any case. `mod` resolves to `meta` on Apple platforms and `ctrl` elsewhere: ```html ``` Matching is exact in both directions: a declared modifier is required, an undeclared one is forbidden. A bare `KeyJ` binding means "J with nothing else held", so Ctrl+J keeps its browser default — and a `ctrl+KeyJ` binding never fires on a plain J. ## Codes, not keys These are `KeyboardEvent.code` values — physical keys — not `KeyboardEvent.key` values. `KeyW` rather than `w`, and the code does not change with the keyboard layout, so a binding chosen for QWERTY lands on the same physical key on AZERTY. That cuts both ways, and it is the thing to weigh when picking a letter: a binding is to a _position_ on the keyboard. `KeyJ` and `KeyK` sit under the right hand on QWERTY, which is the whole point of the vim bindings; on Dvorak those same positions are `c` and `t`. ## Everything else keeps its default Only bound keys are acted on, and `preventDefault()` is called only for those. With `KeyJ` and `KeyK` above, the arrow keys stop moving focus entirely and go back to scrolling the page. Tab and Shift+Tab are never bound by default, which is what lets custom keys sit alongside [native tab navigation](/docs/introduction#tab-still-works) rather than in place of it. ### Two things that are not rebindable Home, End, PageUp and PageDown are fixed — there is no attribute for them. So is the grid's cell movement, below. ## Interaction with grids In a grid, and already move one cell. Binding one of them as the next or previous key hands it to that binding instead — the cell move gives way, so the two never both fire on one keypress. Binding a _non_-arrow pair leaves cell movement alone: with `KeyJ` and `KeyK` on a grid root, J and K move a whole row while still move a cell. ## Editable elements are exempt A key pressed inside an `input`, `textarea`, `select`, or `[contenteditable]` element is never handled, whatever it is bound to. Arrows and Home/End keep moving the caret, and a letter binding like `KeyJ` does not swallow typing "j" into a field that sits inside an item — navigation resumes once focus leaves the field. ## A binding worth avoiding **`Tab` itself.** Binding `data-keyrove-next-key="Tab"` does work, and it costs you the browser's own forward tab navigation for the whole group. Shift+Tab is a different combo, so it stays native and remains the way out — but a group where the two Tab directions behave that differently is confusing. If what you want is Tab moving past a group rather than through it, [roving tabindex](/docs/examples/roving-tabindex) is the mechanism for that, and it leaves the key alone.