-
Notifications
You must be signed in to change notification settings - Fork 605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change settings at breakpoint #233
Comments
Thanks for this feature request. +1 this issue if you'd like to see this feature added. I've tried to make Flickity as flexible as possible so that layouts are handled entirely with your CSS. There's also the watchCSS option that allows you to enable or disable Flickity with breakpoints. I'm not keen on adding this feature as its added complexity with small benefit. It requires mixing CSS logic with JS logic, which can be problematic. Many options, like freeScroll, assume you're only setting them at initialization. Changing options on the fly would require a large overhaul. That said, I'm always interested to see what developers are really wishing for. |
http://flickity.metafizzy.co/options.html#watchcss is just what I was after... being able to destroy/init the slider with your CSS/media queries is a game changer. Nice work, @desandro. |
+1 |
2 similar comments
+1 |
+1 |
+1 The Owl Carousel has these options: |
+1 indeed, I hoped to see the same like what Owl Carousel has. Before I've been using Owl Carousel in pretty much every project. Our team changed to Flickity because it was very promising. This feature however is key. An alternative solution is to make two options. 1 would be mouseDraggable and the other would be touchDraggable. So we still have the touchdrag on mobile & tablets. |
+1 |
1 similar comment
+1 |
+1 |
You can set options according to media queries with matchMedia. This will set the option on initialization, but not on resize. Some options are hard to re-set after initialization, like freeScroll, draggable, and cellAlign. But I think this solution will suit most of your requests. See demo http://codepen.io/desandro/pen/xVBpqG // Flickity options, defaults
var options = {
prevNextButtons: false
};
// enable prev/next buttons at 768px
if ( matchMedia('screen and (min-width: 768px)').matches ) {
options.prevNextButtons = true;
}
// disable draggable at 1200px
if ( matchMedia('screen and (min-width: 1200px)').matches ) {
options.draggable = false;
}
$('.gallery').flickity( options ); |
This demo is now linked in Extra demos |
Using vanilla js, I found this worked. // force options to transition instantly
featureFlkty.options.selectedAttraction = 1;
featureFlkty.options.friction = 1;
// select item
featureFlkty.select(i);
// reset defaults
featureFlkty.options.selectedAttraction = 0.025;
featureFlkty.options.friction = 0.28; |
@portedison You can select instantly with the third parameter in select flkty.select( index, isWrapped, isInstant )
//
flkty.select( i, true, true ) |
Can these options be somehow used on resize, I'm trying to implement few options without re-creating the slider on resize, i'm able to pass correct value to the plugin but it doesn't work while resizing. Thanks |
Heres a quick snippet of how I change the flickity options on resize. It's specific for my project but should be easy to adapt, sorry I don't have time to make a more generic example at the moment...
|
The new |
Hey all. I didn't see this example out there, so I wanted to leave it here. I want to instantiate flickity for small screens, then destroy it when we get up to large screens. I'm using enquirejs for the media query testing, but matchMedia would work too. This might not be the right/best way to do this, but I think it does work.
|
@desandro Why is this issue closed? As far as I can tell, it's still not possible to change options after initialization. |
The linked demo in this comment only shows how to set options based on breakpoint on page load but not on page resize. |
Why this issue is closed? Demos provided by desandro doesn't resolve problems with different settings for breakpoints for example "groupCells". |
Not directly solved with the plugin, but my solution works perfectly using enquire or just plain match media: |
Another attempt at this - handles multiple carousels in case you have multiple in one page that share the same break point. Should probably add logic to handle being given a non-array (i.e. just one carousel) as well ... function toggleDraggableAtFlickityBreakpoint(mediaQuery, $carousels) {
if(!mediaQuery || !$carousels) { return; }
var dragToggles = function (match) {
$carousels.forEach(function($carousel) {
var flkty = $carousel.data('flickity');
if(!flkty) { return; }
if (match) {
flkty.options.draggable = true;
} else {
flkty.options.draggable = false;
}
flkty.updateDraggable();
});
};
var mql = window.matchMedia(mediaQuery);
dragToggles(mql.matches);
// listener
mql.addListener(function(e){
dragToggles(e.matches);
});
}
// examples
toggleDraggableAtFlickityBreakpoint("(max-width: 768px)", [$carouselMain, $thatSecondSlider]);
toggleDraggableAtFlickityBreakpoint("(max-width: 1024px)", [$thatMoreDraggableSlider]); |
I've recently migrated from Slick and have been sorely missing this feature, I've come up with an idea to leverage the existing watchCSS so it can do more than just enable/disable Flickity, by adding the ability to trigger setting changes. Here's an example of how it could work: JS var flkty = new Flickity( elem, {
watchCSS: true
groupCells: 2,
responsive: {
small: {
groupCells: 1
}
}
}); CSS /* enable Flickity default settings */
.carousel:after {
content: 'flickity';
display: none; /* hide :after */
}
@media screen and ( max-width: 480px ) {
/* enable Flickity small settings */
.carousel:after {
content: 'flickity.small';
}
} You have a new setting, an object for storing your breakpoints, (in the example I've named it "responsive"), the property names become the identifiers for your breakpoint and you trigger them by appending the breakpoint identifier to the This keeps the settings and styles separate, yet allows for triggering settings changes with any CSS media query. Edit: I've put together a proof of concept that seems to be working, I found that Flickity only checks that watchCSS is truthy, so no need to add a new option, we can put the responsive object as the value of watchCSS and watchCSS will still evaluate as true. var flkty = new Flickity( elem, {
watchCSS: {
small: {
groupCells: 1
}
},
groupCells: 2
}); CSS as above if (typeof Flickity === 'function') {
var proto = Flickity.prototype;
proto.watchCSS = function () {
var watchOption = this.options.watchCSS;
if (!watchOption) {
return;
}
var afterContent = getComputedStyle(this.element, ':after').content;
// activate if :after { content: 'flickity' }
if (afterContent.indexOf('flickity') != -1) {
// ---modification start---
// check for watchCSS options changes
if (typeof watchOption === 'object') {
this.watchCSSOptionsChange(afterContent);
}
// ---modification end---
this.activate();
} else {
this.deactivate();
}
};
proto.watchCSSOptionsChange = function (afterContent) {
// store the current breakpoint identifier
if (!this._currentOptionsIdentifier) {
this._currentOptionsIdentifier = '';
}
// trim flickity. and surrounding quotes from the new breakpoint identifier
var identifier = afterContent.substring(0, afterContent.length - 1).substring(10);
// check for breakpoint change
if (this._currentOptionsIdentifier !== identifier) {
console.log(identifier);
// if the original options have been cloned apply them to reset
if (typeof this.options._flickityInitialOptions === 'object') {
this.options = this.options._flickityInitialOptions;
this._currentOptionsIdentifier = '';
console.log('reset');
}
// check if the new breakpoint options exist
if (typeof this.options.watchCSS[identifier] === 'object') {
// clone the original options so we can reset on breakpoint change
this.options._flickityInitialOptions = JSON.parse(JSON.stringify(this.options));
// apply the new options
var newOptions = this.options.watchCSS[identifier];
for (var key in newOptions) {
if (newOptions.hasOwnProperty(key)) {
this.options[key] = newOptions[key];
}
}
// update the identifer so we can skip if there's no change in breakpoint
this._currentOptionsIdentifier = identifier;
console.log('responsive');
}
console.log(this.options);
}
}
} I'm modifying the watchCSS method to check if The new watchCSSOptionsChange function could potentially be stand alone and triggered using the |
Any update on this? |
For my purposes, I wanted to change the groupCells based on breakpoint. I'm sure this method can be used with changing other Flickity options as well. My plan was to initi Flickity based on the current breakpoint (xs, sm, md, lg, xl, xxl). 1 groupCells for xs, sm & md; 2 groupCells for anything bigger. On resize, check the breakpoint & reset the number of groupCells. If the number of groupCells changed, destroy Flickity & re-init with the new groupCells count. I found this lovely article about setting breakpoints in CSS & using them within Javascript, so I gave it a try and I'm quite happy with the results. Here's my code: // Flickity set-up
var flkty;
var elem = document.querySelector('.testimonial-carousel');
var groupCells;
// Set-up the breakpoint variable
var breakpoint;
// Get the current breakpoint
var getBreakpoint = function () {
return window.getComputedStyle(document.body, ':before').content.replace(/"/g, '');
};
// Set the number of groupCells based on breakpoint
var setCells = function () {
if (breakpoint === 'xs' || breakpoint === 'sm' || breakpoint === 'md') {
return 1;
} else {
return 2;
}
};
// Calculate breakpoint on page load
breakpoint = getBreakpoint();
groupCells = setCells();
// console.log(groupCells);
do_flickity();
// Setup a timer
var timeout;
// Recalculate breakpoint on resize
window.addEventListener('resize', function () {
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame(function () {
// Get the groupCells value from before resize
var prevGroupCells = groupCells;
// Get the new current breakpoint
breakpoint = getBreakpoint();
// Get the new groupCells value
groupCells = setCells();
// If new groupCells count is different from previous. DESTROY Flickity & init new Flickity
// console.log(groupCells + ' | ' + prevGroupCells);
if( groupCells !== prevGroupCells ){
flkty.destroy();
do_flickity();
}
});
}, false);
// init Flickity
function do_flickity() {
flkty = new Flickity( elem, {
groupCells: groupCells,
prevNextButtons: false,
});
} |
@desandro |
Any news on this? |
+1 |
1 similar comment
+1 |
+8908765 !!! |
What about this? https://flickity.metafizzy.co/options.html |
Any update on bringing this functionality to Flickity? |
Hi guys, I've been using Flickity for a while and have had an urge for this responsive option, so I created a jQuery plugin to handle this and am quite happy with the result, here is how I control responsive with the extra plugin
The plugin will decide when to destroy and re-initialize the carousel to apply new options using |
Thankyou @phucbm this is just what I was looking for. It seems to be a very common requirement that |
+1 |
1 similar comment
+1 |
Works amazing @phucbm thank you! |
+1 |
1 similar comment
+1 |
Such a shocking and disappointing decision to make this an extra - rather than integrated into the slider... glad i went to SwiperJS |
Still no breakpoint feature ? |
It would be nice to do something similar to slick where you can define settings that only kick in at certain breakpoints.
For example, on a wide screen I would like to show multiple items and allow free scrolling, but on a smaller mobile device I would like to only show one item at a time and snap to each item. I see that the showing one at a time option is doable now by setting the width to 100%, but changing freeScroll is not possible currently (as far as I can tell).
Is there a simple way to handle this?
Thank you.
The text was updated successfully, but these errors were encountered: