Расположение календарей side-by-side

Режим отображения нескольких месяцев в Pikaday реализуется через параметр numberOfMonths, который управляет количеством одновременно рендеримых календарных сеток внутри одного экземпляра компонента. При значении больше единицы календарь автоматически формирует горизонтальную компоновку, в которой месяцы выстраиваются рядом друг с другом, образуя единый интерфейс навигации по датам.

Базовая конфигурация многомесячного режима

Основной механизм бокового размещения календарей включается через инициализацию Pikaday с параметром количества месяцев:

const picker = new Pikaday({
    field: document.getElementById('datepicker'),
    numberOfMonths: 2,
    format: 'DD.MM.YYYY'
});

При numberOfMonths: 2 календарь отображает два месяца в одной строке. Каждый следующий месяц синхронизирован с предыдущим: навигация по стрелкам сдвигает оба месяца одновременно.

Внутренняя структура DOM при этом формируется следующим образом: создаётся контейнер календаря, внутри которого генерируется несколько элементов .pika-lendar, каждый из которых соответствует отдельному месяцу.

Поведение навигации в многомесячном режиме

Навигационные кнопки (previous month, next month) управляют не отдельными календарями, а общей датой смещения. Это означает, что при переключении вперёд или назад изменяется базовый месяц, а остальные месяцы пересчитываются относительно него.

При numberOfMonths: 3 поведение выглядит следующим образом:

  • первый календарь показывает текущий месяц
  • второй — следующий
  • третий — месяц +2 относительно текущего

Сдвиг на один шаг вперёд приводит к полному обновлению всех трёх отображаемых месяцев.

Горизонтальная компоновка и CSS-структура

Pikaday использует блочную структуру, где каждый месяц является независимым контейнером. Горизонтальное расположение обеспечивается стилями, применяемыми к родительскому элементу:

.pika-lendar {
    display: inline-block;
    vertical-align: top;
}

При этом общий контейнер календаря (.pika-single) не требует обязательного flex-контейнера, так как стандартная реализация использует inline-раскладку.

Для более современного управления расположением часто применяется переопределение стилей:

.pika-single {
    display: flex;
    gap: 12px;
}

Такой подход делает поведение более предсказуемым при адаптивной верстке и позволяет контролировать расстояние между месяцами.

Синхронизация высоты календарей

При отображении нескольких месяцев возникает задача выравнивания высоты блоков. Каждый месяц может иметь различное количество недель, что приводит к визуальному «скачку» интерфейса.

Для стабилизации высоты используется фиксирование минимальной высоты:

.pika-lendar {
    min-height: 260px;
}

Альтернативный подход — выравнивание по максимальному значению через flex-контейнер:

.pika-single {
    display: flex;
    align-items: stretch;
}

Это обеспечивает одинаковую высоту всех месяцев независимо от их содержимого.

Адаптивное поведение на разных разрешениях

Многомесячный режим требует отдельной обработки для мобильных устройств. При малых ширинах экрана горизонтальная компоновка приводит к сжатию элементов и ухудшению читаемости.

Типичная стратегия адаптации:

@media (max-width: 600px) {
    .pika-single {
        display: block;
    }

    .pika-lendar {
        display: block;
        width: 100%;
    }
}

При таком подходе календари автоматически переходят в вертикальную компоновку, сохраняя функциональность выбора дат без потери доступности.

Ограничения numberOfMonths и производительность

Увеличение количества отображаемых месяцев напрямую влияет на производительность, так как каждый месяц создаёт собственный DOM-дерево и набор событий.

Основные факторы нагрузки:

  • количество .pika-lendar элементов
  • количество обработчиков событий навигации
  • перерасчёт позиций при смене месяца

Практическое ограничение обычно составляет 2–3 месяца. Значения выше могут использоваться, но требуют оптимизации CSS и минимизации дополнительных вычислений в пользовательских обработчиках.

Согласование диапазона дат в многомесячном режиме

При использовании Pikaday в режиме выбора диапазона дат (range selection) несколько месяцев особенно полезны для визуализации начала и конца периода.

Логика подсветки диапазона распространяется на все отображаемые месяцы одновременно. Это означает, что выбранный интервал может начинаться в одном календаре и заканчиваться в другом.

Пример конфигурации:

const picker = new Pikaday({
    field: document.getElementById('range'),
    numberOfMonths: 2,
    onSelect: function() {
        const start = this.getStartRange();
        const end = this.getEndRange();
    }
});

При этом визуальная логика подсветки полностью управляется внутренними методами библиотеки и не требует дополнительной синхронизации.

Кастомизация расстояний и визуального разделения

При размещении календарей бок о бок часто требуется усилить визуальное разделение месяцев. Это достигается через margin и gap:

.pika-lendar + .pika-lendar {
    margin-left: 16px;
}

Либо через flex gap:

.pika-single {
    display: flex;
    gap: 16px;
}

Дополнительно можно использовать разделительные линии:

.pika-lendar:not(:last-child) {
    border-right: 1px solid #e5e5e5;
    padding-right: 12px;
}

Такое оформление улучшает визуальную структуру при большом количестве месяцев.

Управление начальным месяцем отображения

В многомесячной конфигурации важную роль играет параметр defaultDate, который задаёт базовую точку отсчёта:

const picker = new Pikaday({
    field: document.getElementById('date'),
    numberOfMonths: 2,
    defaultDate: new Date(2026, 0, 1),
    setDefaultDate: true
});

Первый календарь будет отображать указанный месяц, а остальные будут вычисляться относительно него.

Для динамического управления стартовым месяцем используется метод setDate:

picker.setDate(new Date(2026, 5, 1));

Это приводит к перерасчёту всех отображаемых месяцев в боковой группе.

Особенности работы с локализацией

При боковом отображении месяцев локализация влияет не только на названия дней недели, но и на визуальную длину заголовков месяцев.

В некоторых языках заголовки могут быть существенно длиннее, что влияет на ширину каждого блока. Для стабилизации макета используется:

.pika-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

Это предотвращает раздвижение календарей и сохраняет равномерную структуру.

Согласование с внешними контейнерами

При встраивании Pikaday в сложные интерфейсы (модальные окна, формы, таблицы) важно учитывать, что многомесячный режим увеличивает общую ширину компонента.

Типичный подход — ограничение ширины контейнера:

.pika-single {
    max-width: 600px;
}

Или использование горизонтального скролла:

.calendar-wrapper {
    overflow-x: auto;
}

Такой метод применяется при необходимости сохранить фиксированное количество месяцев без адаптивного сокращения.

Поведение при динамическом изменении numberOfMonths

Pikaday не всегда корректно пересоздаёт DOM при изменении numberOfMonths после инициализации. В большинстве случаев требуется полное пересоздание экземпляра календаря.

Типичный паттерн:

picker.destroy();

const newPicker = new Pikaday({
    field: document.getElementById('date'),
    numberOfMonths: 3
});

Это обеспечивает корректное пересоздание структуры .pika-lendar и предотвращает визуальные артефакты.

Компоновка нескольких независимых календарей

Альтернативный способ бокового размещения — использование нескольких независимых экземпляров Pikaday, размещённых в контейнере с flex-раскладкой:

<div class="calendar-row">
    <input id="date1">
    <input id="date2">
</div>
.calendar-row {
    display: flex;
    gap: 20px;
}
new Pikaday({ field: document.getElementById('date1') });
new Pikaday({ field: document.getElementById('date2') });

Этот подход отличается от numberOfMonths тем, что каждый календарь имеет собственное состояние и навигацию. Он применяется в сценариях, где требуется независимый выбор дат без синхронизации.

Взаимодействие с кастомной версткой

При глубокой кастомизации интерфейса часто требуется переопределение структуры Pikaday. В таких случаях боковое расположение месяцев может быть интегрировано в общий layout приложения.

Пример интеграции в grid-систему:

.pika-single {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}

Такой подход позволяет легко расширять количество месяцев без изменения логики JavaScript, ограничиваясь только CSS-слоем.