Skip to main content

Percentage Position

Apply the camera element's transform position as a percentage value (%) instead of px using the usePercentagePos option.

The demo below disables autoResize to simulate the moment before resize() is applied. Toggle the container width and compare the two carousels — the px-positioned one gets misaligned until resize() is called, while the %-positioned one keeps its relative position.

import Flicking from "@egjs/flicking";
import "@egjs/flicking/dist/flicking.css";
import "./styles.css";

// autoResize is disabled to simulate the moment before resize() is applied
const flickingPx = new Flicking("#flick-px", {
  usePercentagePos: false,
  autoResize: false,
  defaultIndex: 2
});

const flickingPercent = new Flicking("#flick-percent", {
  usePercentagePos: true,
  autoResize: false,
  defaultIndex: 2
});

const transformElPx = document.getElementById("transform-px");
const transformElPercent = document.getElementById("transform-percent");

function updateTransform(flicking, el) {
  el.textContent = flicking.camera.element.style.transform;
}

flickingPx.on("move", () => updateTransform(flickingPx, transformElPx));
flickingPx.on("afterResize", () => updateTransform(flickingPx, transformElPx));
flickingPercent.on("move", () => updateTransform(flickingPercent, transformElPercent));
flickingPercent.on("afterResize", () => updateTransform(flickingPercent, transformElPercent));

updateTransform(flickingPx, transformElPx);
updateTransform(flickingPercent, transformElPercent);

// Toggle the container width (100% ↔ 60%)
const wraps = [document.getElementById("wrap-px"), document.getElementById("wrap-percent")];
const widthLabel = document.getElementById("width-value");
let narrow = false;

document.getElementById("toggle-width").addEventListener("click", () => {
  narrow = !narrow;
  const width = narrow ? "60%" : "100%";
  wraps.forEach(wrap => {
    wrap.style.width = width;
  });
  widthLabel.textContent = width;
});

// Recalculate the internal sizes manually
document.getElementById("call-resize").addEventListener("click", () => {
  flickingPx.resize();
  flickingPercent.resize();
});

Summary

Key Options

OptionTypeDefaultDescription
usePercentagePosbooleanfalseApply the camera position as a percentage value (%) instead of px

Behavior Comparison

SettingCamera transformOn viewport size change (before resize)
usePercentagePos: falsetranslate(-832px)Camera stays at the same px position, so panels get misaligned
usePercentagePos: truetranslate(-104%)Camera keeps its relative position, so panels stay in place

Details

How It Works

When enabled, Flicking calculates the camera position as a percentage relative to the viewport size and applies it as transform: translate(-104%) instead of translate(-832px).

Since a percentage position scales together with the viewport, the camera keeps its relative position even before the internal sizes are recalculated by resize(). When the panels are also sized with relative units (%-based widths and margins like this demo), the whole layout stays visually aligned during viewport size changes.

  • Relationship with autoResize: In real-world usage you'd keep autoResize enabled. usePercentagePos prevents the temporary misalignment between the moment the layout changes and the moment the (possibly debounced) resize call is applied. This demo disables it only to make that in-between moment observable.
  • Relationship with resizeDebounce: With a large resizeDebounce value, the gap until resize is applied gets longer. usePercentagePos keeps panels in place during that gap.

Use Cases

When should you use this?
  • Responsive (%-based) layouts: Panels keep their position while the container size changes, such as during window resizes or CSS transitions
  • Debounced resize: Prevents visible misalignment during the debounce delay when using resizeDebounce

Notes

Caution
  • The percentage position keeps panels visually aligned only when the panel sizes are also relative to the viewport (e.g., %-based widths). Panels with fixed px sizes will still be misaligned until resize() is called.
  • This option only changes how the camera position is applied. The internal sizes are not updated automatically — resize() still has to be called (or autoResize kept enabled) to update the input areas and movement boundaries.
  • resize: Recalculate the internal sizes