I'm trying to set a min-width in pixel to swiper slides on big screens (width greater than 1200px) only, has anyone already tried/done this? When I set a min-width to .swiper-slide then the (default) active slide is not properly centered. I tried to set slidesPerView to 'auto' with the min-width then I have only 1 full width slide as active, the other ones seem to be out of the viewport.
.swiper-slide {
display: flex;
height: auto;
align-items: stretch;
justify-content: center;
opacity: 0.7;
transition: all 0.3s;
min-width: 400px;
}
const customerSlider = new Swiper('.swiper-container', {
slidesPerView: 1,
centeredSlides: true,
spaceBetween: 32,
slidesOffsetBefore: 0,
slideToClickedSlide: true,
loop: true,
breakpoints: {
768: {
slidesPerView: 3,
},
1200: {
slidesPerView: 'auto',
},
},
})
Related
I'm using Swiper API to create a mobile-friendly slider but I need to find a way to make the swiper.update() method reposition the slides smoothly and not instantly placing them upon removing a slide.
Right now when removing a slide and calling swiper.update to reposition the remaining slides, it just reposition the remaining slides instantly. How can I make it run the same way but with a smoother reposition of the slides?
Link for Swiper API: https://swiperjs.com/swiper-api
Initialization of Swiper
swiper = new Swiper(".mySwiper", {
slidesPerView: 3,
allowTouchMove: true,
allowSlideNext: true,
allowSlidePrev: true,
spaceBetween: 5,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: ".swiper-pagination",
clickable: true,
},
});
swiper.setTransition(this, 0.3);
EDIT: As requested I created an example code to run and reproduce the issue. As you can see with the code provided below when you remove a slide the transition that repositions the remaining slides is instant. I need to find a way to make it smoother. To position the remaining slides slower and not instantly. Is there a way to do that?
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css"/>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<style>
html, body {
padding: 0;
margin: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.swiper {
width: 100%;
height: 500px;
margin-left: 10px !important;
margin-right: 10px !important;
box-sizing: border-box;
}
.swiper-slide {
background-size: cover !important;
border: 2px solid darkgray;
box-sizing: border-box;
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
transition: 0.3s all ease;
}
.swiper-slide img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.removeSlideBtn {
margin-top: 50px;
line-height: 30px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
</div>
<button class="removeSlideBtn" onclick="RemoveSlide();">Remove Slide</button>
</body>
<script>
var swiper = new Swiper(".swiper", {
slidesPerView: 3,
allowTouchMove: true,
allowSlideNext: true,
allowSlidePrev: true,
spaceBetween: 5,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: ".swiper-pagination",
clickable: true,
},
});
swiper.setTransition(this, 300);
function RemoveSlide() {
var slide = Math.floor(Math.random() * swiper.slides.length);
swiper.removeSlide(slide);
}
</script>
</html>
Turns out, it could be achieved without using any of the API's methods and properties. The way the swiper is displaying the slides is by using flex display.
So I managed to achieve a smooth transition upon removing slides by using the following jsfiddle code.
Link for JsFiddle: https://jsfiddle.net/MadLittleMods/EM4xL/
<style>
.remove-item {
flex: 1;
-webkit-animation: flexShrink 500ms ease forwards;
-o-animation: flexShrink 500ms ease forwards;
animation: flexShrink 500ms ease forwards;
}
#keyframes flexShrink {
to {
flex: .01;
flex: .00001;
}
}
#keyframes flexGrow {
to {
flex: 1;
}
}
</style>
<script>
swiper.slides[i].classList.add('remove-item');
swiper.slides[i].addEventListener('animationend', function () {
swiper.removeSlide(i);
});
</script>
Everything works fine if the slider is the only element in the page, but add an extra one after the swiper element and the active slide is always the first one. Adding height: 100% to .swiper-container makes it work fine, but then when you go to the end of the page and back to top, footer is fixed. Anyone has a workaround?
Example:
https://stackblitz.com/edit/swiper-demo-15-free-mode-no-fixed-positions-losg12?file=style.css
Your issue only looks like a bug (But it's not).
The footer is not fixed but when you hover A area you scroll the swiper mousewheel: true (not the page).
One Solution/Idea:
[1]Disable/Enable scroll [2] if footer is visible.
Part 1: Use mousewheel API methods:
mySwiper.mousewheel.disable();
mySwiper.mousewheel.enable();
Part 2: Use Intersection Observer API (If the footer is visible disable mousewheel).Read more: How to Know when an Element Gets Visible in the Screen During Scrolling
var observer = new IntersectionObserver(function(entries) {
// isIntersecting is true when element and viewport are overlapping
// isIntersecting is false when element and viewport don't overlap
if(entries[0].isIntersecting === true){
console.log('Element has just become visible in screen');
swiper.mousewheel.disable();
}
else{
swiper.mousewheel.enable();
}
}, { threshold: [0] });
observer.observe(document.querySelector("#footer"));
Snippet
var swiper = new Swiper('.swiper-container', {
freeMode: true,
mousewheel: {
invert: false,
},
// If we need pagination
pagination: {
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
scrollbar: {
el: '.swiper-scrollbar',
draggable: true,
}
});
var observer = new IntersectionObserver(function(entries) {
// isIntersecting is true when element and viewport are overlapping
// isIntersecting is false when element and viewport don't overlap
if(entries[0].isIntersecting === true){
console.log('Element has just become visible in screen');
swiper.mousewheel.disable();
document.getElementById("status").innerHTML = "mousewheel.disable!";
}
else{
swiper.mousewheel.enable();
document.getElementById("status").innerHTML = "mousewheel.enable!";
}
}, { threshold: [0.1] });
/* threshold is a number between 0 and 1, that represents the viewable area of the target element in the screen. For example, 0 represents no area of element is visible. A value of 0.10 represents about 10% area is viewable in screen. Value of 1 means element is fully viewable in screen.*/
observer.observe(document.querySelector("#footer"));
html,
body {
position: relative;
height: 100%;
}
body {
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color: #000;
margin: 0;
padding: 0;
}
.swiper-container {
width: 100%;
height: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: flex;
justify-content: center;
align-items: center;
}
nav{
min-height: 50px;
display: flex;
justify-content: center;
align-items: center;
background: lightgray;
}
footer{
min-height: 500px;
display: flex;
justify-content: center;
align-items: center;
background: brown;
color: white;
}
#message{
position: fixed;
z-index: 100;
padding: 10px;
background: brown;
color: white;
border: 2px solid gray;
}
#status{
background: yellow;
color: red;
padding: 5px;
}
<span id="message">Status: <b id="status">True</b></span>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<nav>Navbar</nav>
<!-- Slider main container -->
<main class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</main>
<footer id="footer">Footer</footer>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
Codepen: https://codepen.io/ezra_siton/pen/JjRbrJM
Fullpage.js
One more idea is to use a full-page scroll plugin (More control):
https://alvarotrigo.com/fullPage/
https://alvarotrigo.com/pagePiling/
Related: fullpage.js: normal scroll for particular sections?
I'm using the Swiper by iDangero.us and I'm having difficulty creating an infinite loop of multi-row slides. I have 30 images which I need to group into 3 rows of 5 over 2 slides. Setting loop renders the slides in the grid that I want to achieve and clicking the arrows slides between each one correctly. But I need the slides to be infinite, going back to the original 15 images on the first slide once I reach the end. Setting loop to true breaks this.
What am I doing wrong? Is it possible to do this with this plugin?
Snippet and JSFiddle below.
Any help would be appreciated.
Thanks :)
var swiper = new Swiper('.swiper-container', {
// loop: true,
prevButton: '.swiper-button-prev',
nextButton: '.swiper-button-next',
slidesPerView: 5,
spaceBetween: 15,
slidesPerColumn: 3,
slidesPerColumnFill: 'row',
slidesPerGroup: 15
});
* {
box-sizing: border-box;
}
html,
body {
margin: 20px 0;
padding: 0;
font-family: Arial, sans-serif;
}
.container {
width: 100%;
max-width: 1170px;
padding: 0 15px;
margin: 0 auto;
}
.img-responsive {
display: block;
max-width: 100%;
height: auto;
}
.swiper-slide span {
position: absolute;
top: 15px;
left: 15px;
background-color: black;
color: white;
padding: 6px;
display: block;
font-size: 20px;
width: 35px;
height: 35px;
text-align: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.1/css/swiper.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.1/js/swiper.min.js"></script>
<div class="container">
<div class="swiper-container">
<div class="swiper-wrapper">
<script>
for (i = 1; i <= 30; i++) {
document.write('<div class="swiper-slide"><img src="http://placehold.it/240x240" class="img-responsive"><span>' + i + '</span></div>');
}
</script>
</div>
<div class="swiper-button-prev swiper-button-white"></div>
<div class="swiper-button-next swiper-button-white"></div>
</div>
</div>
JS Fiddle: http://codepen.io/aethyrion/pen/mRVwzE
What you want is called Recursion. Create a function that re-instantiates your slides and then loops through your slides, and then at the end of the function call your function again. This will recursively call your loop of the same slides.
However you'll want to have some stopping point I would think. If you don't you'll run out of memory eventually.
Create a function, that does this loop and then add it to the script tag in your html.
I got the static images to resize but the video doesn't when the browser size is adjusted. This is probably because I've added a width into the script. However, if I just leave videoWidth: true, then the video becomes tiny.
On the website (http://imdarrien.com/work/Kami/kami.html)
https://jsfiddle.net/9NJ2k/6/
Here is the offical demo from the website (http://www.owlcarousel.owlgraphic.com/demos/video.html)
video:true,
videoHeight: 500,
videoWidth: 856,
.owl-carousel .owl-video-wrapper {
position: relative;
height: 100%;
background: #000;
}
.owl-carousel .owl-video-play-icon {
position: absolute;
height: 80px;
width: 80px;
left: 50%;
top: 50%;
margin-left: -40px;
margin-top: -40px;
background: url(play_button.png) no-repeat;
cursor: pointer;
z-index: 1;
-webkit-backface-visibility: hidden;
opacity:1;
transition: all 1s;
}
When videoWidth: false
By adding "responsive:true" option and changing video tag width 100%;height:auto you can get video as responsive.
Demo: http://jsfiddle.net/nLz17fcv/5/
script:
$(document).ready(function() {
$("#carousel").owlCarousel({
items:1,
autoPlay : 5500,
stopOnHover : true,
center:true,
navigation:false,
pagination:false,
goToFirstSpeed : 1300,
singleItem : true,
autoHeight : true,
responsive: true,
responsiveRefreshRate : 200,
responsiveBaseWidth: window,
video:true,
transitionStyle:"fade",
onTranslate: function() {
$('.owl-item').find('video').each(function() {
this.pause();
});
}
});
})
CSS
.owl-carousel {width:90%; margin: 0 auto;}
.owl-carousel img{width:100%;height:auto;}
I completely agree that the addition of "responsive:true" option and changing the video tag
width:100%;height:auto
you are able to get video as responsive.
I'm using the slick carousel. I want the background-url to have a 100% height
here is my carousel
http://jsfiddle.net/84c8gvkt/3/
HTML:
<section>
<div class="carousel-container">
<div class="fill" style="background-image:url('http://media-cdn.tripadvisor.com/media/photo-s/01/a4/e9/fa/los-perdidos-hot-springs.jpg');"> </div>
<div class="slide" style="background-image:url('http://media-cdn.tripadvisor.com/media/photo-s/01/a4/e9/fa/los-perdidos-hot-springs.jpg');"> </div>
</div>
JS:
$('.carousel-container').slick({
dots: true,
infinite: true,
speed: 3000,
fade: true,
cssEase: 'linear',
autoplay: false,
pauseOnHover: true,
});
CSS
html, body {
width: 100%;
height: 100%;
}
.fill {
padding: 0px;
width:100%;
height:100%;
background-position:center;
background-size:cover;
}
.fill:after {
content: '';
position: absolute;
width: inherit;
height: inherit;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.3);
}
I can't figure out where it's going wrong.
Can you help me? Thnx!
The problem appears to be coming from the fact that neither your section or your .carousel-container have 100% height, nor do any of the elements generated by your slick carousel.
The easy fixed would simply be to use viewport units instead of a percentage on the .fill element.
Try making the following change:
.fill {
height: 100vh;
}
The vh unit is pretty well supported across all browsers. Can I use
This may not necessarily be the best way to do it for what you're trying to achieve, but just a suggestion.