x documentation

Полная справка по CSS-утилитам, JS-компонентам и публичному API библиотеки.

Быстрый старт

x состоит из CSS-утилит и набора маленьких JS-компонентов. Для обычной HTML-страницы достаточно подключить CSS, JS и вызвать x.init(). В демо-проекте это делает assets/js/app.js.

<link rel="stylesheet" href="dist/x.css" /> <script src="dist/x.js"></script> <script>x.init()</script>

Если используешь исходники как ESM, импортируй публичный entrypoint:

import x from './index.js'; x.init();

x.init() инициализирует: Device, Modal, Animate, Appear, Lazyload, Loadmore, Sheets, Dropdown, Scroll, Sticky, Slider и Hover. Autocomplete и Typograf запускаются вручную, потому что им нужны пользовательские данные или явно выбранные селекторы.

Как устроен x

CSS

CSS собран из независимых файлов в src/components/x/*.css. Утилиты используют rem-шкалу: например .max70 означает max-width: 70rem, а не 700px.

JavaScript

Каждый компонент экспортирует singleton. src/js/x.js собирает их в объект x и кладёт его в window.x для браузерного использования.

Глобальные сокращения

СокращениеЧто делает
x.id(id)Возвращает document.getElementById(id).
x.qs(selector, context)Возвращает первый элемент. Принимает селектор, NodeList, массив или Node.
x.qsa(selector, context)Возвращает массив элементов. Принимает селектор, NodeList, массив или Node.
x.render(...)Сокращение для x.lib.render(...).

CSS

Breakpoints

Все responsive-утилиты mobile-first. Префикс добавляет правило внутри min-width.

ПрефиксУсловиеПример
s:min-width: 640pxs:flex
m:min-width: 768pxm:g2
l:min-width: 1024pxl:px8
xl:min-width: 1280pxxl:g4

Сетки и поток

.grid включает CSS Grid. .g1.g12 задают число колонок, .c1.c12 задают span элемента. .flow создаёт вертикальный поток, а .flow.s0.flow.s10 меняют расстояние между соседними элементами.

<div class="grid g1 m:g2 l:g4 gap4"> <div class="c1">Card</div> <div class="c1 l:c2">Wide card</div> </div>

Flex

.flex включает flex-контейнер. Направление: .fr, .fc. Перенос: .fw. Выравнивание: .aic, .ais, .aie, .jcc, .jcsb, .jcse, .jce.

Размеры

Все числовые width/max/min/height утилиты используют rem. Это основной принцип новой шкалы.

КлассДиапазонЧто задаёт
.w*2-38 step 2, 40-160 step 10width
.h*2-38 step 2, 40-80 step 10height
.max*2-38 step 2, 40-160 step 10max-width
.min*2-38 step 2, 40-160 step 10min-width

Примеры: .max70 = 70rem, .w16 = 16rem, .h40 = 40rem.

Lib utilities

В CSS-разделе Lib собраны классы общего назначения: .container, .unselectable, .unclickable, .pointer, .toe, .lc1.lc5, .oh, .fix, .rel, .abs, .inset, .fill, .hidden, .hidden-next, .visuallyHidden, .scroll-responsive.

Aspect ratio: .ratio1x1, .ratio2x1, .ratio3x1, .ratio4x1, .ratio3x2, .ratio4x3, .ratio16x9, .ratio1x2, .ratio1x3, .ratio1x4, .ratio2x3, .ratio3x4, .ratio9x16.

Spacing, radius, shadow, order

Spacing построен на переменных --space-0--space-10, но классы margin/padding/gap идут до 12. Для отрицательных margin используется суффикс n: .mt2n.

Радиусы: .br0.br12, .br100. Тени: .sh0.sh5. Порядок flex/grid элемента: .o0.o10.

Типографика и цвета

Размеры шрифта: .fs10.fs19 step 1 и .fs20.fs100 step 2. Вес: .fw100.fw900. Также есть .mono, .italic, .strike, .ls0.ls4, .lh0.lh9.

Цвета: .color-primary, .color-success, .color-warning, .color-danger, .color-error, .color-black, .color-white, .color-grey. Для фона используются соответствующие .bg-*.

JS-компоненты

Animate

x-animate привязывает элемент к прогрессу скролла. Компонент может вызывать глобальную функцию, добавлять класс, убирать класс после выхода из диапазона и работать с кастомным trigger.

Параметр JSONОписание
triggerСелектор элемента, относительно которого считается прогресс. Если не указан, используется сам элемент.
start, endГраницы диапазона. Поддерживаются px, vh, проценты и числовые значения.
functionNameИмя глобальной функции. Она получает объект с прогрессом и состоянием.
classКласс, который добавляется при попадании в диапазон.
classRemoveЕсли true, класс снимается после выхода из диапазона.
<div x-animate='{"start":"80vh","end":"20vh","functionName":"onProgress","class":"active"}'></div> <script>function onProgress(data) { console.log(data.progress); }</script>

Appear

x-appear добавляет .appeared при первом появлении и переключает .visible, пока элемент виден. Подходит для простых reveal-анимаций.

API: x.appear.init({ once, rootMargin, threshold }), x.appear.destroy().

Autocomplete

Autocomplete работает поверх Dropdown: нужен контейнер с id, поле x-dropdown-open и список x-dropdown. Данные можно грузить асинхронно, фильтровать через mapData, рендерить через renderItem.

<div id="searchDropdown"> <input x-dropdown-open type="text" placeholder="Search" /> <ul x-dropdown></ul> </div> x.autocomplete.init('searchDropdown', { loadData: async (ctx) => fetch('/api?q=' + encodeURIComponent(ctx.field.value)).then(r => r.json()), renderItem: item => `<li data-item='${JSON.stringify(item)}'>${item.name}</li>`, onSelect: item => x.form.setValue('#searchDropdown input', item.name) });

API: x.autocomplete.init(dropdownId, options), x.autocomplete.destroy(dropdownId), x.autocomplete.destroy(), x.autocomplete.get(dropdownId).

Device

x.device определяет breakpoint, touch, browser, OS и добавляет классы на html. На resize состояние пересчитывается. Это удобно для CSS-ветвлений и диагностики.

API: x.device.init(), x.device.destroy().

Dropdown

Dropdown связывает trigger x-dropdown-open и соседний список x-dropdown. Поддерживает клики вне меню, keyboard navigation, ARIA-роли и события жизненного цикла.

СобытиеКогда вызывается
dropdown:beforeshowПеред открытием.
dropdown:aftershowПосле открытия.
dropdown:beforehideПеред закрытием.
dropdown:afterhideПосле закрытия.

API: x.dropdown.init(), x.dropdown.closeAllDropdowns(), x.dropdown.destroy().

Hover

x-hover синхронизирует класс .hover у ссылок с одинаковым href. Наиболее полезно, когда карточка и текстовая ссылка ведут в одно место.

API: x.hover.init(), x.hover.destroy().

Lazyload

x-lazyload наблюдает изображения через IntersectionObserver, переносит data-src/data-srcset в реальные атрибуты и добавляет .loaded. Если данных для загрузки нет, элемент просто снимается с наблюдения.

<img x-lazyload src="placeholder.png" data-src="photo.jpg" data-srcset="photo@2x.jpg 2x" alt="" />

API: x.lazyload.init(), x.lazyload.destroy().

Loadmore

x-loadmore вызывает глобальную функцию при приближении маркера к viewport. Функция получает номер страницы и должна вернуть truthy, если можно продолжать загрузку, или falsy, если данных больше нет.

<div x-loadmore='{"functionName":"loadPosts"}'></div> window.loadPosts = async (page) => { const ok = await fetchPage(page); return ok; };

API: x.loadmore.init(), x.loadmore.reset(selector), x.loadmore.destroy().

Modal

Modal открывается через x-modal-open="id", а содержимое задаётся блоком x-modal="id". При инициализации содержимое переносится в modal-контейнер. Поддерживаются hash-модалки, уникальные модалки, вложенные окна, overlay click и Esc.

<a x-modal-open="profile">Open</a> <div x-modal="profile" class="modal_hash" data-window-class="max80">...</div>
APIОписание
x.modal.show(id)Открыть модалку.
x.modal.hide(id)Закрыть модалку.
x.modal.hideAll()Закрыть все активные модалки.
x.modal.isActive(id)Проверить активность.
x.modal.destroy()Снять глобальные обработчики.

События: modal:ready, modal:open, modal:close.

Scroll

x-scrollto скроллит к id, selector или JSON-конфигу. Для модалок можно указать внутренний scroll-parent.

<a x-scrollto="#top">Наверх</a> <a x-scrollto='{"parent":"#modal .modal-outer","target":"#api","offset":100}'>API</a>

API: x.scroll.init(), x.scroll.destroy().

Sheets

Sheets - это табы. Контейнер помечается x-sheets, кнопки - x-sheet-open, панели - x-sheet. Активная кнопка получает .active, активная панель показывается.

<div x-sheets> <a x-sheet-open="a" class="active">A</a> <a x-sheet-open="b">B</a> <div x-sheet="a">Panel A</div> <div x-sheet="b">Panel B</div> </div>

API: x.sheets.init(), x.sheets.show(xSheet, options), x.sheets.destroy(). События: sheets:beforeshow, sheets:aftershow.

Slider

x-slider подготавливает слайды, lazy-загружает изображения, поддерживает touch-drag на мобильных и hover-preview на desktop. Конфиг передаётся JSON-атрибутом.

Частые параметры: gap, touch, hover, rubber, indicators, resetOnMouseout.

API: x.slider.init(), x.slider.destroy(), x.slider.observeSliders().

Sticky

x.sticky наблюдает элементы .sticky. Когда элемент начинает “прилипать”, добавляется .sticky_on и отправляется событие sticky:on. При возврате отправляется sticky:off.

API: x.sticky.init(), x.sticky.reset(), x.sticky.destroy().

Typograf

x.typograf.process(html) обрабатывает кавычки, многоточия, дроби, степени, тире, минус в числах и неразрывные пробелы. Теги code, pre, script, style пропускаются.

x.typograf.live(staticSelector, interactiveSelector, root) обрабатывает статичный текст и вешает live-обработку на input, textarea и contenteditable.

x.form

x.form нужен, чтобы программно менять поля и при этом запускать правильные события. Он работает с input, textarea, select, checkbox/radio и contenteditable.

МетодОписание
x.form.setValue(selector, value)Записывает value и dispatch-ит подходящее событие.
x.form.setChecked(selector, checked)Меняет checked у checkbox/radio и dispatch-ит input.
x.form.onUpdate(selector, callback)Подписывает callback на input/change в зависимости от типа поля.
x.form.offUpdate(selector)Снимает подписку с выбранных элементов.
x.form.update(selector)Принудительно dispatch-ит update-событие.
x.form.destroy()Снимает все подписки, созданные через form.
x.form.getEventType(element)Возвращает событие, которое будет использоваться для элемента.

x.lib

DOM и классы

x.lib.id, x.lib.qs, x.lib.qsa, x.lib.hide, x.lib.show, x.lib.toggle, x.lib.switch, x.lib.addClass, x.lib.removeClass, x.lib.toggleClass, x.lib.switchClass.

Навигация

x.lib.reload(), x.lib.reloadWithHash(hash), x.lib.redirectTo(url), x.lib.updateURL(url, title).

Форматирование и валидация

x.lib.random(a, b), x.lib.price(price), x.lib.number(num), x.lib.numberDecline(number, one, few, many), x.lib.phoneCleaner(phone), x.lib.phone(phone), x.lib.isEmail(email), x.lib.isValidJSON(str), x.lib.isInteger(value), x.lib.isDouble(value), x.lib.makeId(), x.lib.makePassword(length, selector).

x.lib.phoneCleaner(phone) оставляет только цифры, приводит российский префикс 8 к 7 (кроме номеров 8 800), добавляет 7, если код страны отсутствует, и возвращает не более 11 цифр. x.lib.phone(phone) дополнительно форматирует полный номер.

x.lib.phoneCleaner('8 (912) 345-67-89'); // '79123456789' x.lib.phone('8 (912) 345-67-89'); // '+7 912 345-67-89' x.lib.phone('8 800 555-35-35'); // '8 800 555-35-35'

Runtime

x.lib.loadScript(path, callback, type) грузит внешний скрипт один раз. x.lib.deferred(callback, delay) запускает код после пользовательской активности или таймера. x.lib.deffered сохранён как алиас с исторической опечаткой.

x.lib.throttle(fn, wait, options) и x.lib.debounce(fn, wait, options) возвращают функцию с методом cancel(). Options: leading, trailing.

x.lib.onAppear(selector, appearCallback, disappearCallback, options) создаёт IntersectionObserver. Если disappearCallback не передан, элемент снимается с наблюдения после первого появления.

Render

x.lib.render(selector, data, placement = null, escapeHtml = false) рендерит строку, функцию или async-функцию. Если placement не указан, заменяет innerHTML. Если включён escapeHtml, вставляет безопасный текст.

x.lib.render('.out', '<b>HTML</b>'); x.lib.render('.out', userInput, null, true); x.lib.render('.list', () => '<li>Item</li>', 'beforeend');

Жизненный цикл

Большинство компонентов можно безопасно переинициализировать: init() либо сам снимает старые обработчики, либо пропускает уже обработанные элементы. Для SPA лучше вызывать destroy() при размонтировании страницы или перед полной заменой DOM.

КогдаЧто делать
Обычная статичная страницаОдин раз вызвать x.init().
После AJAX-вставки HTMLПовторно вызвать нужный компонент или x.init(), если менялась большая часть страницы.
SPA route leaveВызвать destroy() у компонентов с глобальными обработчиками.

Безопасность и ограничения

x-render использует JavaScript expression из HTML-атрибута. Используй его только в доверенной разметке. Для пользовательского текста предпочитай x.lib.render(selector, userInput, null, true).

x-loadmore и x-animate вызывают функции по имени из глобальной области. Не передавай туда непроверенные имена функций из пользовательских данных.

Lazyload и Autocomplete зависят от браузерных API и внешних ресурсов. Для локального открытия через file:// лучше использовать обычный script bundle и локальные placeholder-изображения, как в index.html.