Control how viewport size changes are detected using the autoResize and useResizeObserver options.
Try changing the container width with the slider and compare the resize response difference between the two carousels.
import Flicking from "@egjs/flicking" ;
import "@egjs/flicking/dist/flicking.css" ;
import "./styles.css" ;
const flickA = new Flicking( "#flick-observer" , {
autoResize : true ,
useResizeObserver : true
} ) ;
const flickB = new Flicking( "#flick-window" , {
autoResize : true ,
useResizeObserver : false
} ) ;
let countA = 0 ;
let countB = 0 ;
const countElA = document .getElementById ( "count-a" ) ;
const countElB = document .getElementById ( "count-b" ) ;
flickA .on ( "afterResize" , ( ) => {
countElA .textContent = ++countA ;
} ) ;
flickB .on ( "afterResize" , ( ) => {
countElB .textContent = ++countB ;
} ) ;
const slider = document .getElementById ( "width-slider" ) ;
const valueLabel = document .getElementById ( "width-value" ) ;
const wrapA = document .getElementById ( "wrap-a" ) ;
const wrapB = document .getElementById ( "wrap-b" ) ;
slider .addEventListener ( "input" , ( ) => {
const w = ` ${ slider .value } %` ;
wrapA .style .width = w ;
wrapB .style .width = w ;
valueLabel .textContent = ` ${ slider .value } %` ;
} ) ;
const toggleBtn = document .getElementById ( "btn-toggle" ) ;
let autoResizeOn = true ;
toggleBtn .addEventListener ( "click" , ( ) => {
autoResizeOn = !autoResizeOn ;
flickA .autoResize = autoResizeOn ;
flickB .autoResize = autoResizeOn ;
toggleBtn .textContent = `autoResize: ${ autoResizeOn } ` ;
toggleBtn .classList .toggle ( "active" , autoResizeOn ) ;
document .getElementById ( "manual-btn" ) .style .display = autoResizeOn ? "none" : "inline-block" ;
} ) ;
document .getElementById ( "manual-btn" ) .addEventListener ( "click" , ( ) => {
flickA .resize ( ) ;
flickB .resize ( ) ;
} ) ;
import Flicking from "@egjs/react-flicking" ;
import { useCallback , useRef , useState } from "react" ;
import "@egjs/react-flicking/dist/flicking.css" ;
import "./styles.css" ;
function FlickingDemo ( { label , hint , width , useResizeObserver , autoResize } ) {
const ref = useRef ( null ) ;
const [ count , setCount ] = useState ( 0 ) ;
const onAfterResize = useCallback ( ( ) => {
setCount ( c => c + 1 ) ;
} , [ ] ) ;
return (
< div className ="demo-section" >
< div className ="demo-label" > { label } </ div >
< div style ={ { width } } >
< Flicking
ref ={ ref }
key ={ ` ${ autoResize } - ${ useResizeObserver } ` }
autoResize ={ autoResize }
useResizeObserver ={ useResizeObserver }
onAfterResize ={ onAfterResize }
>
< div className ="flicking-panel panel-1" > 1</ div >
< div className ="flicking-panel panel-2" > 2</ div >
< div className ="flicking-panel panel-3" > 3</ div >
< div className ="flicking-panel panel-4" > 4</ div >
< div className ="flicking-panel panel-5" > 5</ div >
</ Flicking >
</ div >
< div className ="resize-count" > Resize count: { count } </ div >
< div className ="resize-count" style ={ { color : "#aaa" } } >
{ hint }
</ div >
{ !autoResize && (
< button className ="button" style ={ { marginTop : 6 } } onClick ={ ( ) => ref .current ?.resize ( ) } >
Manual resize()
</ button >
) }
</ div >
) ;
}
export default function App ( ) {
const [ width , setWidth ] = useState ( 100 ) ;
const [ autoResize , setAutoResize ] = useState ( true ) ;
return (
< div >
< div className ="slider-row" >
< span > Container width</ span >
< input type ="range" min ={ 30 } max ={ 100 } value ={ width } onChange ={ e => setWidth ( Number ( e .target .value ) ) } />
< span className ="value-label" > { width } %</ span >
</ div >
< FlickingDemo
label ="useResizeObserver: true"
hint ="Responds immediately when width is changed via slider"
width ={ ` ${ width } %` }
useResizeObserver ={ true }
autoResize ={ autoResize }
/>
< FlickingDemo
label ="useResizeObserver: false"
hint ="Does not detect element size changes (only detects window resize)"
width ={ ` ${ width } %` }
useResizeObserver ={ false }
autoResize ={ autoResize }
/>
< div className ="toggle-row" >
< button className ={ `button ${ autoResize ? "active" : "" } ` } onClick ={ ( ) => setAutoResize ( v => !v ) } >
autoResize: { autoResize ? "true" : "false" }
</ button >
< span style ={ { fontSize : 13 , color : "#888" } } >
{ autoResize ? "Auto resize enabled" : "Auto resize disabled — use the Manual resize() button" }
</ span >
</ div >
</ div >
) ;
}
< template >
< div >
< div class ="slider-row" >
< span > Container width</ span >
< input type ="range" :min ="30" :max ="100" v-model.number ="width" />
< span class ="value-label" > {{ width }}%</ span >
</ div >
< div class ="demo-section" >
< div class ="demo-label" > useResizeObserver: true</ div >
< div :style ="{ width: width + '%' }" >
< Flicking
:key ="'a-' + autoResize"
:options ="{ autoResize, useResizeObserver: true }"
@afterResize ="countA++"
>
< div class ="flicking-panel panel-1" > 1</ div >
< div class ="flicking-panel panel-2" > 2</ div >
< div class ="flicking-panel panel-3" > 3</ div >
< div class ="flicking-panel panel-4" > 4</ div >
< div class ="flicking-panel panel-5" > 5</ div >
</ Flicking >
</ div >
< div class ="resize-count" > Resize count: {{ countA }}</ div >
< div class ="resize-count" style =" color : #aaa " > Responds immediately when width is changed via slider</ div >
</ div >
< div class ="demo-section" >
< div class ="demo-label" > useResizeObserver: false</ div >
< div :style ="{ width: width + '%' }" >
< Flicking
ref ="flickB"
:key ="'b-' + autoResize"
:options ="{ autoResize, useResizeObserver: false }"
@afterResize ="countB++"
>
< div class ="flicking-panel panel-1" > 1</ div >
< div class ="flicking-panel panel-2" > 2</ div >
< div class ="flicking-panel panel-3" > 3</ div >
< div class ="flicking-panel panel-4" > 4</ div >
< div class ="flicking-panel panel-5" > 5</ div >
</ Flicking >
</ div >
< div class ="resize-count" > Resize count: {{ countB }}</ div >
< div class ="resize-count" style =" color : #aaa " > Does not detect element size changes (only detects window resize)</ div >
< button v-if ="!autoResize" class ="button" style =" margin-top : 6 px "
@click ="flickB?.resize()" >
Manual resize()
</ button >
</ div >
< div class ="toggle-row" >
< button :class ="['button', autoResize && 'active']"
@click ="autoResize = !autoResize; countA = 0; countB = 0" >
autoResize: {{ autoResize }}
</ button >
< span style =" font-size : 13 px ; color : #888 " >
{{ autoResize ? 'Auto resize enabled' : 'Auto resize disabled — use the Manual resize() button' }}
</ span >
</ div >
</ div >
</ template >
< script setup >
import Flicking from "@egjs/vue3-flicking" ;
import { ref } from "vue" ;
import "@egjs/vue3-flicking/dist/flicking.css" ;
const flickB = ref ( null ) ;
const width = ref ( 100 ) ;
const autoResize = ref ( true ) ;
const countA = ref ( 0 ) ;
const countB = ref ( 0 ) ;
</ script >
< style >
.flicking-viewport.vertical {
display : block ;
width : 100 % ;
}
.flicking-panel {
width : 200 px ;
height : 150 px ;
margin-right : 10 px ;
border-radius : 8 px ;
display : flex ;
align-items : center ;
justify-content : center ;
font-size : 24 px ;
font-weight : bold ;
color : white ;
}
.panel-1 { background : #3e8ed0 ; }
.panel-2 { background : #00d1b2 ; }
.panel-3 { background : #f14668 ; }
.panel-4 { background : #ffe08a ; color : #333 ; }
.panel-5 { background : #48c78e ; }
.demo-container {
margin-bottom : 24 px ;
}
.demo-label {
font-weight : bold ;
margin-bottom : 8 px ;
color : #666 ;
}
.button {
padding : 8 px 16 px ;
margin : 4 px ;
border : 2 px solid #3498db ;
background : transparent ;
color : #3498db ;
border-radius : 4 px ;
cursor : pointer ;
font-size : 14 px ;
}
.button: hover {
background : #3498db ;
color : white ;
}
.controls {
display : flex ;
justify-content : center ;
margin-top : 16 px ;
gap : 8 px ;
}
.slider-row {
display : flex ;
align-items : center ;
gap : 12 px ;
margin-bottom : 12 px ;
}
.slider-row input [ type ="range" ] {
flex : 1 ;
}
.slider-row .value-label {
font-size : 13 px ;
color : #666 ;
min-width : 50 px ;
text-align : right ;
}
.demo-section {
margin-bottom : 20 px ;
}
.demo-section .demo-label {
font-weight : bold ;
margin-bottom : 6 px ;
font-size : 14 px ;
}
.resize-count {
font-size : 13 px ;
color : #888 ;
margin-top : 4 px ;
}
.toggle-row {
display : flex ;
align-items : center ;
gap : 12 px ;
margin-top : 12 px ;
}
.toggle-row .button {
font-size : 13 px ;
padding : 6 px 12 px ;
}
.toggle-row .button.active {
background : #3498db ;
color : white ;
}
</ style >
Summary
Key Options
Option Type Default Description autoResizebooleantrueAutomatically call resize() when viewport size changes useResizeObserverbooleantrueWhether to use ResizeObserver (falls back to window resize if false)
Option Combination Comparison
Combination Behavior Best For autoResize: true + useResizeObserver: trueImmediately detects element size changes General use (default) autoResize: true + useResizeObserver: falseOnly detects window resize Element size is fixed, only window size changes autoResize: falseManual resize() call required When you want to control the resize timing yourself
Details
autoResize
When autoResize: true (default), Flicking automatically calls the resize() method when the viewport size changes. Setting it to false requires the developer to manually call flicking.resize().
useResizeObserver
When useResizeObserver: true (default), the ResizeObserver API is used to detect element-level size changes. When false, only the window's resize event is detected, which means changes to the parent element size may not be detected.
Use Cases
When should you use this?
Responsive layouts : Use the defaults as-is (autoResize + ResizeObserver)
Tab switching UI : Set autoResize: false and manually resize only when the tab is activated
Performance-sensitive environments : Set useResizeObserver: false to only detect window resize
Notes
When autoResize: false is set, you must call resize() after the viewport size changes
When useResizeObserver: false, size changes caused by CSS layout changes (flex, grid, etc.) are not detected