Skip to content
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

Graceful loading of slides? #1741

Closed
ghost opened this issue Sep 17, 2015 · 28 comments
Closed

Graceful loading of slides? #1741

ghost opened this issue Sep 17, 2015 · 28 comments

Comments

@ghost
Copy link

ghost commented Sep 17, 2015

Is there a way to hide Slick until its page has finished loading?

http://nowrongdoorsws.com.au/

Slick shows the slides beside each other while loading (a hard refresh should show this) and I would like to hide the area completely until everything has loaded for a more graceful result.

Is this possible?

Thanks. And sorry – I'm a bit rusty when it comes to JS.

:)

@dodotdot
Copy link

yes i have the same issue, on mobile web page is always block render css

even in demo page the slide is load vertically,
blocking

its really annoying. is there any solution how to solve this
Thanks

@vramana
Copy link

vramana commented Sep 18, 2015

@kavonatsalv You can try considering the <template> tag. It doesn't render anything upon the initial load. May be you can consider that.

@vfonic
Copy link

vfonic commented Sep 21, 2015

+1

<template> is not supported in IE

@kenwheeler
Copy link
Owner

This is really easy to do. Put a class on your slider, in your css set it to display none, and then add .slick-initialized: display block, and it shows up when slick is loaded. You may want to wrap your .slick() call in a window.load too if you're still seeing problems.

@vfonic
Copy link

vfonic commented Sep 21, 2015

Thanks for quick reply @kenwheeler!

I fixed this by using visibility: hidden and then doing:

setTimeout(function() {
        slides.hide().css('visibility','visible').fadeIn('slow');
    }, 200);

display: none didn't work because slick couldn't calculate the slide height correctly.

@lapski
Copy link

lapski commented Sep 28, 2015

This is really easy to do. Put a class on your slider, in your css set it to display none, and then add .slick-initialized: display block, and it shows up when slick is loaded. You may want to wrap your .slick() call in a window.load too if you're still seeing problems.

Another option is to hide all the slides except the first one (:first-child). Similar to what @kenwheeler suggested, when the .slick-initialized class appears, set the other slides to display: block. I haven't tried this myself, but if at least the first slide is visible, it should be able to calculate the slight height, and you it should prevent the flash of stacked slides on load.

@masi
Copy link

masi commented Nov 5, 2015

You can avoid flash of unstyled content completely in CSS. Perhaps worth adding to the "get started" section of the site.

<html>
  <head>
  <title>My Webpage Without FOUC</title>
  <link rel="stylesheet" type="text/css" href="slick/slick.css"/>
  <link rel="stylesheet" type="text/css" href="slick/slick-theme.css"/>
  <style>
    .your-carousel .your-item {
      display: none;
    }
    .your-carousel .your-item:first-child {
      display: block;
    }
    .your-carousel.slick-initialized .your-item {
      display: block;
    }
  </style>
  </head>
  <body>

  <div class="your-carousel">
    <div class="your-item">your content</div>
    <div class="your-item">your content</div>
    <div class="your-item">your content</div>
  </div>

  <script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
  <script type="text/javascript" src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
  <script type="text/javascript" src="slick/slick.min.js"></script>

  <script type="text/javascript">
    $(document).ready(function(){
      $('.your-class').slick({
        setting-name: setting-value
      });
    });
  </script>

  </body>
</html>

@ahmadalfy
Copy link
Collaborator

@masi 's solution is perfect. Slick add a class slick-initialized once the slider is constructed. You can do:

.slider { display: none; }
.slider.slick-initialized { display: block; }

@chris-griffin
Copy link

@masi

It might be worth changing your css to use visibility instead of display to avoid issues with sizing child elements.

.your-carousel .your-item { visibility: hidden; } .your-carousel .your-item:first-child { visibility: visible; } .your-carousel.slick-initialized .your-item { visibility: visible; }

@neilgee
Copy link

neilgee commented Nov 25, 2016

I was having issues taming FOUC on the Slider Syncing usage with slider-nav and slider-for, in particular for the slider-nav

Initially displaying the slider container to none and using the .slick-initialised class to display block fixes it and also setting a height on the slider container can fix the layout.

.slider-for-container {
        min-height: xx px;
}

.slider-nav-container {
        min-height: xx px;
}

.slider-for-container .slider-for,
.slider-nav-container .slider-nav {
	display: none;
}

.slider-for-container .slick-initialized,
.slider-for-container .slick-initialized {
	display: block;
}

@RedlingshoeferUndHofmann

Using the ideas above, I found a pleasing (not perfect) solution for the problem, i guess:

.your-carousel{
	 visibility:hidden;
	 opacity:0;	 
	 transition: opacity 1s;
}

.your-carousel.slick-initialized{
	visibility:visible;
	opacity:1;
}

.your-carousel .your-item{
	display:none ;
}

.your-carousel .your-item:first-child{
	display:block; visibility:hidden;
} 

.your-carousel.slick-initialized .your-item{
	display:block;visibility:visible!important;
}

@Ogeh-Ezeonu
Copy link

@ahmadalfy I found your fix to be the perfect solution to the slick vertical loading issue.

@justcookin
Copy link

@RedlingshoeferUndHofmann 's answer is what I ended up using, worked great

@CrispySinger
Copy link

@RedlingshoeferUndHofmann 's answer is a nice solution for this, pretty handy. Cheers!

@BenSpace48
Copy link

Great workarounds, thanks!

To shorten the code a bit you can use the :not selector, it works with both display: none; and visiblity: hidden; methods.

.your-class:not(:first-child) {
    visibility: hidden;
}

.slick-initialized.your-class {
    visibility: visible;
}

@sasanikolic90
Copy link

@RedlingshoeferUndHofmann thanks, that is exactly what I needed. This also works with my custom settings to display the dots below the slider, where I do const elements_count = $('.header_slider', context).children().length; and dots: elements_count > 1 ? true : false, The dots were not displayed with other solutions mentioned above.

@roeeyossef
Copy link

using @RedlingshoeferUndHofmann - great answer!

@Dari4sho
Copy link

Thanks all and @RedlingshoeferUndHofmann, works like a charm. Only thing I did was replacing .your-item with .slick-slide.

@lesliekirk
Copy link

Nothing I try seems to help with this. All these solutions leave me with a temporary empty white expanding space while the slider waits for the javascript to finish loading. Is there any way to display the first slide while waiting for the javascript to load? You can see the issue here.

@BenSpace48
Copy link

@lesliekirk - Have you tried to use display: none; on all slides except the first one, and then once initialised overwrite that with display: block; or whatever value works best for you.

You can also throw height in there if required.

@adampatterson
Copy link

@BenSpace48 that worked for me, Display none on all of them was causing some of the slides not to load properly with lazyloading.

@ChristianoBourguignon
Copy link

ChristianoBourguignon commented Nov 10, 2020

I managed to solve this problem with the help of some here in this comment, I hope it helps!

I used the following JS and CSS requirements

//CSS
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.7.1/slick-theme.css" />

<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>

//JS
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

<script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>

And I made the following JS settings (in my case it was a banner, so 1 slide for everyone)

<script>
$(document).ready(function() {
    $('.carousel').slick({
        infinite: true,
        dots: true,
        arrows:false,
        autoplay: true,
        autoplaySpeed: 6000,
        arrows:false,
  });
}); 
</script>

Now, in order not to "flash the sliders" and show more grandiose I put the following CSS.

Note: I put a slick-slider class for all sliders, except the
first!

.carousel.slick-initialized{
    visibility:visible;
    opacity:1;
}

.carousel .slick-slider{
    display:none ;
}

.carousel .slick-slider:first-child{
    display:block; visibility:hidden;
} 

.carousel.slick-initialized .slick-slider{
    display:block;visibility:visible!important;
}

So, during loading the first slide will be visible, and the others will be hidden, just when they become active they will be in display: block;, so I solved my problem and I hope it helps more people too!

Attention, Christiano.

@adampatterson
Copy link

Thanks @ChristianoBourguignon I will give this a try later on!

@ateufel
Copy link

ateufel commented Nov 27, 2020

my version, if anyone needs it:

.slick-slider:not(.slick-initialized) .slick-slide:not(:first-of-type) {
	display: none;
}

.slick-slider:not(.slick-initialized) .slick-slide:first-of-type {
	visibility: hidden;
}

@Nanod10
Copy link

Nanod10 commented Oct 23, 2021

@masi

It might be worth changing your css to use visibility instead of display to avoid issues with sizing child elements.

.your-carousel .your-item { visibility: hidden; } .your-carousel .your-item:first-child { visibility: visible; } .your-carousel.slick-initialized .your-item { visibility: visible; }

Based on @chris-griffin anwer
answer, I can display as many images as I want like this.

.your-carrousel > .your-item {
visibility: hidden;
display: inline-block;
}
.your-carrousel .your-item:first-child {
visibility: visible;
}
.your-carrousel .your-item:nth-child(-n+4) {
visibility: visible;
}
.your-carrousel.slick-initialized .your-item {
visibility: visible;
}

Note that I am using a direct child operator (">"), if any of you had put a limitation on the connection speed from the developer tools, you could see that before loading Slick the structure has a basic form ( that you printed yourself), but then Slick cuts the contents of its initial container, and encapsulates it in its own container classes.

This makes it possible that with 2 custom classes, we handle the state before and after loading.

@graphicz
Copy link

graphicz commented Oct 3, 2022

Solution of @RedlingshoeferUndHofmann works a charm but I still have a little jump of the page content as the dots appear. I have tried display:block on ul.slick-dots and giving them a height to no avail.
I am afraid I do not understand where to place @sasanikolic90 's addition.
Please can anyone advise?
Thank you

@Jamoliddin610
Copy link

YOU NEED USE ANOTHER SLIDER AS SWIPER

@mrccariolato
Copy link

Hi Guys, let me cheer you up a bit, I think I found a solution to make this pretty.

Perhaps you noticed slide setting in slick settings documentation. Well that option let you decide which elements go inside slick-track element.

Let's consider my initial html:

<div class="wrapper">
                        <div class="type-list">
                            <div class="placeholders loading row">
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                            </div>
                            <div class="slide"></div>
                            <div class="slide"></div>
                            <div class="slide"></div>
                            <div class="slide"></div>
                        </div>
                    </div>

Set slide option to .slide will catch all div.slide elements and put them into .slick-track leaving outside unwanted elements.

Resultant html:

<div class="wrapper">
                        <div class="type-list slick-slider slick-initialized">
                            <div class="placeholders loading row">
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                                <div class="col-md-6 col-lg-3"><div class="placeholder placeholder-wishlist"></div></div>
                            </div>
                            <div class="slick-list">
                                <div class="slick-track">
                                    <div class="slide"></div>
                                    <div class="slide"></div>
                                    <div class="slide"></div>
                                    <div class="slide"></div>
                                  </div>
                            </div>
                        </div>
                    </div>

This was you can play with CSS to show/hide placeholders (or loading gif) and slider.

.wrapper .slick-initialized .placeholders{
    display: none!important;
}
.wrapper .type-list .slide{
    display: none;
}
.wrapper .type-list.slick-initialized .slide{
    display: block;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests