-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
If content is hidden during Slick bootstrap, Slick refuses to play ball #187
Comments
Sounds like because it is "display: none;" that it can't get the dimensions. I would try manually firing a window resize event on tab change, and see if that gives it a kick in the ass. |
Looking into the source, there are kinda a few places where widths are calculated and passed around, but it all seems to boil down to the slick-list element that is injected: on line 1143 its width is calculated and used in a further calculation of the width of a slide. From those values of |
@kenwheeler the resize thing seems to fix it. As I said in my original issue text this does rely on a developer's ability ot actually hook into these events, so it'd still be good to see if Slick could do its own workaround. The code I used in the end was: // set up Slick carousel
$('.gallery').has('img + img').slick({
autoplaySpeed: 5e3,
arrows: false,
infinite: true,
slide: 'img',
slidesToScroll: 1,
slidesToShow: 1,
speed: 300,
touchMove: false,
});
// hook into Bootstrap shown event and manually trigger 'resize' event so that Slick recalculates the widths
$('[href="#gallery"]').on('shown.bs.tab', function (e) {
$('.gallery').resize();
}); |
You can manually refresh slick itself using slickSetOption(anyoption, anyvalue, true); |
Still doesn't really fix the underlying problem, but fair enough if you think this isn't something that can really be done by slick itself. |
Any suggestions on how? |
The underlying problem is essentially a javascript/dom problem, that you can't get the dimensions of hidden elements. |
Well I know that, for example, various JS libraries (Prototype and jQuery) do try their best to make this happen by quickly making an element displayed (i.e. not I guess the dependency on jQuery to do all of this DOM stuff suggests it's more an upstream issue than a slick issue. The problem is that jQuery doesn't seem to be able to return the width of an element whose parent is set to Still, it may be worth mentioning this as a caveat somewhere in the docs - just mention that obviously if the element is hidden when you call |
It's not a jQuery issue, its a browser/DOM issue. You can't get the dimensions of a hidden element. As the implementor, if you are hiding slick, be sure to hide it after it has initialized, or mitigate the dimension calculation by triggering a resize event. |
I think it might be worth putting this somewhere in the docs. I've also just run into this problem while using Bootstrap 3 tabs (when the carousel is placed in a tab that is initially hidden), and it wasn't immediately clear how to fix the issue. As already mentioned, calling resize() fixes the problem. |
Yeah I think it's high time I write up a FAQ section to clear up certain things that implementors may encounter, |
The .resize() option didn't work for me. I experienced a similar problem attempting to render an embedded google map inside a bootstrap tab as well. To my surprise both problems were resolved by changing how bootstrap handles hidden tabs: /* bootstrap hack: fix content width inside hidden tabs */ .tab-content > .tab-pane, .pill-content > .pill-pane { display: block; /* undo display:none */ height: 0; /* height:0 is also invisible */ overflow: hidden; /* no-overflow */ } .tab-content > .active, .pill-content > .active { height: auto; /* let the content decide it */ } /* bootstrap hack end */ more here: https://groups.google.com/forum/#!topic/twitter-bootstrap-stackoverflow/0Aqzs5s_hEY |
This was also driving me crazy... This is what i did: .ui-widget-content[aria-hidden="true"] { display: block !important; height: 0px; overflow: hidden; } .ui-widget-content[aria-hidden="false"] { display: block !important; height: auto; } Not sure if this is the right solution, but it worked for me, and it might help others, seeing this is the place you land, when you google the problem :) |
@JensNielsen81 Yeah its tough because if you are using display: none, slick can't get the correct dimensions from a hidden element. I'm certainly not going to poll for display changes, and there really aren't reliable events in place to recalc. Been thinking a lot about how to solve this one... |
The CSS solution by Jens worked great for me. Slick inside of Foundation Tabs was giving me a hard time. Thanks! |
thanks, @alexrussell: your solution worked for me using slick inside a Foundation 5 accordion. |
@alexrussell , sorry to ask, but would you be able to shed some light on how your code would be used with responsiveTabs? I've looked at their docs and some 'Events', but it doesn't seem to match up with Bootstraps. So far I've got:
The only thing I haven't changed so far is the But I'm not sure if I simply have to replace Essentially, I believe I'm having hte same issues as everyone else, when the page loads with another tab being shown, the slick width is displaying as 0, even when the tab is selected. Can you or anyone else help? |
@leecollings sorry for the delay getting back to you, I kept forgetting to come and read this properly after seeing it in my emails. I haven't tested this but from the demo given by the repo itself something like this will work: $('#tabContainer').responsiveTabs({
// ...
activate: function(e, tab) {
if (tab.selector == '#carousel') {
$('.slick-carousel-responsive').resize();
}
},
// ...
}); The Also, instead of passing this function to the bootstrapping of responsiveTabs you could also use jQuery event binding as you suggest above: $('#tabContainer').responsiveTabs({
// ...
});
// ...
$('#tabContainer').on('tabs-activate', function(e, tab) {
if (tab.selector == '#carousel') {
$('#slick-carousel-responsive').resize();
}
}); |
I ran into this issue recently and saw an answer on StackOverflow that worked great for me. The code:
IE:
|
@patrickvaillancourt your solution is tricky and worked for me, Thanks :) |
@Lynda333 worked wonderfully for me. thanks mucho! |
This worked for me (directly from Slick site) |
I am using JQuery UI Tabs and was struggling with this issue all day. Thank you!! @JensNielsen81 The CSS works perfectly. |
@Marionovello that worked perfectly for me! |
i solved in this way (coffeescript) |
@patrickvaillancourt thank you, man |
I didn't use bootstrap and wrote my own equivalent to bootstrap tabs, but when I try to fire |
@JeremyLopez try @alexrussell suggestion:
|
this works great on click and a few other suggestions worked too on opening and closing tabs, but if i resize the page then open a tab my slick is broke until it goes to the next slide. This could be an issue when people are changing orientation on devices. Any suggestions? |
@TimmyDodd worked for me! thank you! also, changing event handler from 'show.bs.modal' to 'shown.bs.modal' works (comes with lag, though) |
patrickvaillancourt, thanks! Your solution worked for me! |
Thanks to @painreign.. The solution works
But this flickers alot |
unfortunately, I tried all the solutions above, but none of them worked correctly with me |
@AbdallahNasser So the reason it breaks is because by default the content in a non-active tab is hidden with So you can use visibility hidden, which hides things without taking them out of the document flow, and position absolute all except one of the .tab-content>.tab-pane {display: block;visibility: hidden;}
.tab-content>.tab-pane.active {visibility: visible;}
.tab-content{position: relative;}
.tab-pane:not(:first-child){position: absolute;width: 100%;height: 100%;top: 0;left: 0;} Note: This assumes all the tab panes have the same height, which might not be the case. If each tab pane needs to be able to set the height of the parent through the document flow, then you should probably use a horizontal offset to hide/show. |
None of the above worked in my case, I had to set a timeout to execute the refresh. $('.depos').on('click', function () { setTimeout(function() { $('.slider-nav').slick("getSlick").refresh(); $('.slider-for').slick("getSlick").refresh(); },300); }); |
@tibelchior Yeah, to work with slick with AJAX requests, u always have to set timeouts or refresh or deactivate and activate slick. Better to use other sliders rather than slick. |
@tijanmdr which one do you recommend that is as good as Slick? |
I think Owl Carousel is also a good one. Try that one out. |
this worked for me .nav-item its a class found on tabs menu
|
If anyone is still having this issue - seems like if you change the .slick-active slide in any way via JS after initialization of slick slider it will work as expected. So, after you initialize your slider just add for example yourSlider.find('.slick-active').css('z-index', 1); and it will will work :) |
@patrickvaillancourt @JensNielsen81 Thanks for the elegant solution! |
SIMPLE SOLUTION Thanks @LDigital84 I have a site where 'slick' is within a hidden div, and then shown during a transition. Slick's parent div is set to 'hidden' with initial CSS, and shown later with JQuery. Slick wouldn't appear, even though during initial formatting and testing (with the parent div NOT hidden) Slick had been performing as expected. I simply use a hacky function call: function slickFix(){ and then call that function after I show the parent div. Works a charm.....thanks, this was driving me crazy! |
I wasn't getting very far with the setPosition or triggering resize approaches, maybe because I had a slightly different context. Just in case this helps anyone... I needed to switch between a few different slick sliders, meaning I wanted a couple of hidden sliders on load that I swapped in on a button click. However, using display none leads to the cited problem of Slick not being able to get dimensions. I thought about flashing them in on load and then hiding them, as they are near the bottom of my page, that way Slick could init them. However, that's not tidy and still left the issue of what happened if someone resized the browser. All the hidden sliders wouldn't be resized correctly. In the end I decided to create Slick everytime I needed it. Using a combination of a jQuery fadeIn followed by initialising slick worked well. I thought it might flash content, but it hasn't in the browsers I've tested. When I swap to a new slick carousel, I hide the existing one and unslick it. Then for the incoming carousel I use the combination of fadeIn and initialising. Kind of a just in time approach. Something to consider depending where and how you're using Slick. It seems stable on what I've tested, but if anyone can see any pitfalls to this approach I haven't spotted please let me know. |
@painreign solution was the only thing that would work for me with multiple slide modals on a page. |
I implemented universal code for all type of containers: tabs, modals, collapsible's and etc that finds hidden parent container where slick is in and updates slick position each time parent container is displayed (display: block).
|
Okay so i was stuck in this sitution just like you guys and i found the reason it cause the issue, it simple because when you use slick in tabs, it gonna set your unused tab to
Set non-active tab to |
.tab-content>.tab-pane{ display: block; height: 0px; overflow: hidden; } |
I solved my problem with slick after showing bootstrap modal :
maybe it helps. |
In my side above solutions are not working. |
@Arashz22 your code worked for me! Thank you! 👍 |
Happy to hear that, you are always welcome😍 |
I was spending about 4 hours figuring this out and I cried for joy when I found this code. Thank you so MUCH! |
I'm not sure that this is easily fixable but I'm implementing Slick on a Bootstrap website and I have a Slick-based gallery in a set of Bootstrap tabs. If the gallery tab is the active one on page load, the Slick carousel works fine, but if the gallery tab is not the one that's active on page load the Slick carousel seems to break (the tab basically looks empty).
At a guess this is due to the items being hidden as Slick is set up against the items and so Slick can't calculate the dimensions of the slides, etc.
A possible non-Slick-based fix is to hook into BS tab event system and only call
$.fx.slick()
when the tab is first switched to. Of course this only works for JavaScript components that allow a developer to hook into this kind of event system, so maybe there's a way for Slick to get round this limitation without requiring developers to do these hackish bits of code (which they sometimes may not be able to do).The text was updated successfully, but these errors were encountered: