Setting up a website version for the visually impaired 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

Website Version Setup for Low Vision Users in 1C-Bitrix

Version for low-vision users is mandatory requirement for government and municipal websites per GOST R 52872-2019. For commercial organizations working with government procurement or serving wide audience, also becomes part of requirements. Standard quite specific: three font sizes, three color schemes, ability to disable images, letter-spacing options.

Architecture: Separate Template or CSS Switching

Two approaches. First — separate Bitrix template (/bitrix/templates/accessible/) with simplified layout. Second — CSS classes on <body>, toggled via JavaScript with localStorage or cookie save.

Separate template: more reliable, but requires double maintenance — content changes need both template updates. Bitrix switching logic:

// In init.php
AddEventHandler('main', 'OnBeforeProlog', function() {
    if (!empty($_COOKIE['accessible_mode'])) {
        define('SITE_TEMPLATE_ID', 'accessible');
    }
});

CSS switching: single template, all settings via CSS variables. More modern approach, easier to maintain:

body.accessible-large { --font-scale: 1.5; }
body.accessible-xlarge { --font-scale: 2; }
body.accessible-bw { --bg: #fff; --text: #000; --link: #000; }
body.accessible-black { --bg: #000; --text: #fff; --link: #ff0; }
body.accessible-blue { --bg: #9dd1ff; --text: #063462; --link: #063462; }
body.accessible-no-images img { visibility: hidden; }

Control Panel for Version

Panel placed in header.php template, above main menu. Mandatory elements per GOST:

  • Font size: "Normal", "Large", "Very Large"
  • Color scheme: "White", "Black", "Blue"
  • Images: "Enable", "Disable"
  • Letter-spacing: "Normal", "Increased", "Large"
<div id="accessibility-panel" role="toolbar" aria-label="Low vision version">
    <div class="ac-group" role="group" aria-labelledby="font-size-label">
        <span id="font-size-label">Font size:</span>
        <button class="ac-btn" data-font="1" aria-pressed="true">A</button>
        <button class="ac-btn" data-font="1.5" style="font-size:1.2em" aria-pressed="false">A</button>
        <button class="ac-btn" data-font="2" style="font-size:1.5em" aria-pressed="false">A</button>
    </div>
    <div class="ac-group" role="group" aria-labelledby="color-label">
        <span id="color-label">Color:</span>
        <button class="ac-btn" data-theme="white" aria-pressed="true">B</button>
        <button class="ac-btn" data-theme="black" style="background:#000;color:#fff" aria-pressed="false">B</button>
        <button class="ac-btn" data-theme="blue" style="background:#9dd1ff;color:#063462" aria-pressed="false">B</button>
    </div>
</div>

JavaScript and State Saving

var AC = {
    settings: JSON.parse(localStorage.getItem('ac_settings') || '{}'),

    apply: function() {
        var body = document.body;
        body.style.setProperty('--font-scale', this.settings.font || 1);
        body.className = body.className
            .replace(/\bac-theme-\S+/g, '')
            .replace(/\bac-kern-\S+/g, '');
        if (this.settings.theme) body.classList.add('ac-theme-' + this.settings.theme);
        if (this.settings.kern) body.classList.add('ac-kern-' + this.settings.kern);
        if (this.settings.images === false) body.classList.add('ac-no-images');
    },

    save: function() {
        localStorage.setItem('ac_settings', JSON.stringify(this.settings));
        // Cookie for server-side rendering (Bitrix can read on load)
        document.cookie = 'ac_settings=' + encodeURIComponent(JSON.stringify(this.settings))
            + '; path=/; max-age=31536000; SameSite=Lax';
    }
};

AC.apply(); // On page load

Images in "No Images" Mode

visibility: hidden hides image but preserves layout space. For complete removal:

body.ac-no-images img {
    display: none;
}
body.ac-no-images img[alt]:not([alt=""]):after {
    content: attr(alt);
    display: block;
    border: 1px dashed currentColor;
    padding: 4px;
}

Pseudo-element ::after for <img> works in most browsers with display: block on image itself.

Bitrix Cache and Cookie State

If Bitrix caches pages at PHP component level, accessibility panel should be outside cached blocks — in template header.php (which isn't cached). Page content itself caches normally: all changes applied via CSS/JS on client without server re-request.