Отключение flip для конкретных направлений

Модификатор flip в библиотеке Popper.js отвечает за автоматическое изменение положения всплывающего элемента (popper), если в выбранном направлении недостаточно места. Это позволяет избегать выхода за пределы области видимости (viewport) или родительских контейнеров.

По умолчанию flip работает по следующему принципу:

  • проверяет доступное пространство вокруг референсного элемента;
  • при нехватке места меняет направление размещения (placement);
  • использует список fallback-направлений.

Однако в реальных интерфейсах требуется более тонкая настройка поведения, особенно когда определённые направления должны быть запрещены.


Задача ограничения направлений

В ряде сценариев автоматическое поведение flip нежелательно:

  • всплывающее меню должно всегда оставаться сверху, даже если частично обрезается;
  • дизайн предполагает строго определённые направления (например, только вертикальные);
  • горизонтальные смещения могут ломать композицию интерфейса;
  • необходимо исключить «скачки» интерфейса при нехватке места.

В таких случаях требуется отключить flip частично, а не полностью.


Управление через fallbackPlacements

Ключевой инструмент — настройка свойства fallbackPlacements в модификаторе flip.

По умолчанию Popper сам генерирует список fallback-направлений, например:

top → bottom → right → left

Для ограничения направлений задаётся собственный список:

import { createPopper } from '@popperjs/core';

createPopper(referenceElement, popperElement, {
  placement: 'top',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['bottom']
      }
    }
  ]
});

В этом примере:

  • разрешён только переход top → bottom;
  • направления left и right полностью исключены.

Полное исключение определённых направлений

Если требуется запретить, например, горизонтальные направления:

fallbackPlacements: ['top', 'bottom']

Popper:

  • будет пытаться разместить элемент сверху;
  • при нехватке места переключится вниз;
  • никогда не выберет left или right.

Фиксация одного направления (частичное отключение flip)

Чтобы фактически отключить flip, но оставить модификатор активным:

fallbackPlacements: []

Поведение:

  • Popper использует только исходный placement;
  • при нехватке места не происходит смены направления;
  • элемент может выйти за границы.

Это отличается от полного отключения модификатора тем, что:

  • логика расчёта остаётся активной;
  • другие модификаторы продолжают работать согласованно.

Использование allowedAutoPlacements

При использовании placement: 'auto' Popper сам выбирает оптимальное направление. Ограничить возможные варианты можно через allowedAutoPlacements:

createPopper(referenceElement, popperElement, {
  placement: 'auto',
  modifiers: [
    {
      name: 'flip',
      options: {
        allowedAutoPlacements: ['top', 'bottom']
      }
    }
  ]
});

Теперь:

  • Popper выбирает только между top и bottom;
  • игнорирует left и right даже при наличии пространства.

Комбинирование с вариациями (start, end)

Popper поддерживает вариации размещения:

  • top-start
  • top-end
  • bottom-start
  • bottom-end

Ограничения применяются и к ним:

fallbackPlacements: ['bottom-start', 'bottom-end']

Это позволяет:

  • сохранить направление (вертикальное);
  • гибко управлять выравниванием.

Практический сценарий: всплывающее меню

Требование:

  • меню должно открываться только вниз;
  • при нехватке места — вверх;
  • без горизонтальных смещений.

Решение:

createPopper(button, menu, {
  placement: 'bottom-start',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['top-start']
      }
    }
  ]
});

Результат:

  • основной вариант: bottom-start;
  • fallback: top-start;
  • никаких переходов влево или вправо.

Практический сценарий: tooltip без «прыжков»

Если важно избежать изменения направления:

createPopper(target, tooltip, {
  placement: 'top',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: []
      }
    }
  ]
});

Tooltip:

  • всегда остаётся сверху;
  • не меняет положение;
  • может частично обрезаться.

Влияние на UX

Ограничение направлений влияет на пользовательский опыт:

Плюсы:

  • предсказуемое поведение интерфейса;
  • отсутствие неожиданных перемещений;
  • соответствие дизайн-системе.

Минусы:

  • возможное обрезание контента;
  • ухудшение доступности на маленьких экранах;
  • необходимость учитывать адаптивность вручную.

Взаимодействие с другими модификаторами

Ограничения flip тесно связаны с:

  • preventOverflow — предотвращает выход за границы;
  • offset — задаёт смещение;
  • shift (в новых версиях через preventOverflow) — корректирует позицию внутри границ.

Пример комбинирования:

createPopper(reference, popper, {
  placement: 'top',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['bottom']
      }
    },
    {
      name: 'preventOverflow',
      options: {
        padding: 8
      }
    }
  ]
});

Тонкости и подводные камни

1. Пустой fallbackPlacements ≠ отключение flip

  • модификатор остаётся в цепочке;
  • может влиять на вычисления.

2. auto игнорирует fallbackPlacements

  • используется allowedAutoPlacements.

3. Порядок направлений важен

  • Popper проверяет их последовательно;
  • первый подходящий вариант будет выбран.

4. Контейнеры с overflow

  • ограничение направлений может привести к скрытию popper внутри контейнера;
  • требуется дополнительная настройка boundary.

Рекомендации по использованию

  • Ограничивать направления, если интерфейс строго регламентирован
  • Использовать allowedAutoPlacements при auto
  • Минимизировать список fallback-направлений для предсказуемости
  • Проверять поведение на разных размерах экрана
  • Комбинировать с preventOverflow для контроля границ

Такая настройка позволяет добиться баланса между автоматикой Popper и требованиями интерфейса, оставляя полный контроль над поведением всплывающих элементов.