Setting up keyboard navigation in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

Keyboard Navigation Setup in 1C-Bitrix

Keyboard navigation is not just for blind users. Corporate users, call center operators, people with temporary hand injuries actively use Tab for form and site navigation. If Tab order is broken or focus invisible — direct conversion losses in B2B segment. In Bitrix, this usually manifests as: user presses Tab on checkout page, focus jumps randomly or disappears off-screen entirely.

Visible Focus: Most Common Problem

CSS reset outline: none or outline: 0 kills visible focus indicator for all elements. Often added to global template styles "to avoid ugly blue rectangle." This violates WCAG 2.4.7 (Focus Visible).

Correct approach — don't remove outline globally, style it:

/* Remove outline only for mouse navigation */
:focus:not(:focus-visible) {
    outline: none;
}

/* Show nice focus on keyboard navigation */
:focus-visible {
    outline: 2px solid #0066cc;
    outline-offset: 2px;
    border-radius: 2px;
}

The :focus-visible pseudo-class is supported by all modern browsers — triggers only on keyboard navigation, not mouse click.

Tab Order and Tabindex in Bitrix Templates

Tab focus order is determined by element order in DOM plus tabindex attribute. In Bitrix, issues usually arise from:

  • CSS order in Flexbox/Grid changes visual order, not DOM order — Tab follows DOM, not visual
  • tabindex="0" added to non-focusable elements (div, span) without roles — they get focus but do nothing on Enter
  • tabindex="-1" on interactive elements — focus skipped

For Bitrix menu (bitrix:menu), add arrow key support for submenus. Via JavaScript: when dropdown open, ArrowDown/ArrowUp keys move focus through items, Escape closes menu and returns focus to parent.

Modal Windows and Focus Trap

Bitrix components actively use modals: quick product view, authorization, delivery address selection. Problem: when modal opens, focus should move into it, and Tab shouldn't exit modal bounds (focus trap). On close — focus returns to element that opened modal.

Standard Bitrix components don't do this. Minimal focus trap implementation:

function trapFocus(modal) {
    const focusable = modal.querySelectorAll(
        'a[href], button:not([disabled]), input, select, textarea, [tabindex="0"]'
    );
    const first = focusable[0];
    const last = focusable[focusable.length - 1];

    modal.addEventListener('keydown', function(e) {
        if (e.key !== 'Tab') return;
        if (e.shiftKey) {
            if (document.activeElement === first) {
                e.preventDefault();
                last.focus();
            }
        } else {
            if (document.activeElement === last) {
                e.preventDefault();
                first.focus();
            }
        }
    });
}

Catalog Filter Component

The bitrix:catalog.smart.filter component generates many checkboxes and range sliders. Custom sliders (jQuery UI Slider) are not keyboard-accessible by default. Need to add tabindex="0", role="slider" and key handlers ArrowLeft/ArrowRight for value change. Significant work — easier to replace slider with native <input type="range">, which browser makes keyboard-accessible automatically.

Testing

Full keyboard navigation testing is manual: disable mouse, walk through entire purchase scenario using only Tab/Enter/Space/arrows. Completion time is real usability indicator.