Show Swiper slider out of container - swiper.js

The slider slides out of the container.
I do not want to use overflow: hidden for the container.
Here my code:
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide a</div>
<div class="swiper-slide">Slide b</div>
<div class="swiper-slide">Slide c</div>
<div class="swiper-slide">Slide d</div>
<div class="swiper-slide">Slide e</div>
<div class="swiper-slide">Slide f</div>
<div class="swiper-slide">Slide g</div>
<div class="swiper-slide">Slide h</div>
<div class="swiper-slide">Slide i</div>
<div class="swiper-slide">Slide j</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
var swiper = new Swiper('.swiper-container', {
slidesPerView: 5,
spaceBetween: 9,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
Look this:
image

You can try this solution:
const swiper = new Swiper(".swiper-container", {
// Optional parameters
loop: false,
slidesPerView: "auto",
spaceBetween: 30,
breakpoints: {
// when window width is >= 320px
300: {
slidesPerView: 1.5
},
// when window width is >= 480px
600: {
slidesPerView: 2.5
},
// when window width is >= 640px
900: {
slidesPerView: 3.5
},
1200: {
slidesPerView: 4.5
}
}
});
.swiper-overflow-container {
overflow-x: hidden;
}
.container {
overflow: visible;
outline: 2px solid red;
}
.swiper-container {
overflow: visible;
}
.item {
outline: 1px solid cyan;
}
.image {
width: 100%;
padding-bottom: 100%;
background: #808080;
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper-overflow-container">
<div class="container py-5">
<div class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>First</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Second</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Thrid</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Four</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Five</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Six</p>
</div>
</div>
</div>
</div>
</div>
</div>
HTML:
<div class="swiper-overflow-container">
<div class="container">
<!-- swiper html here -->
</div>
</div>
CSS:
.swiper-overflow-container {
overflow-x: hidden; /* prevent horizontal scroll */
}
.swiper-overflow-container .container {
overflow: visible; /* if your container has overflow by default */
}
.swiper-overflow-container .swiper-container {
overflow: visible; /* remove swiper container overflow */
}
Limitations: not working properly with loop: true

Related

Lightbox with Swiper JS

I'm building a page where I'm using ACF Flexible Content to add a Swiper Slider.
Slider is built so far, but now I want to have a lightbox function in the slider.
For this I have the approach to duplicate the slider once (with one slide per view, instead of three slides per view). So far so good:
Now I want to click on e.g. a zoom icon on the second slider to get to the slide that was clicked on.
For this I have an ActiveIndex function, but I don't know exactly how to give the second slider the index of the first slider...
I have sketched this roughly in a pen:
https://codepen.io/webkonditorei/pen/JjLjRQW?fbclid=IwAR2NZWpzx30gqVWVDPdOkRVrTdMC637dLNPYvakUruFYOjr6auYaJw6L9tY
Or here the code:
<link
rel="stylesheet"
href="https://unpkg.com/swiper#8/swiper-bundle.min.css"
/>
<script src="https://unpkg.com/swiper#8/swiper-bundle.min.js"></script>
<div class="swiper-container swiper1">
<div class="swiper-wrapper">
<div class="swiper-slide"><p onclick="umswipen()">Slide 1</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 2</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 3</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 4</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 5</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 6</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 7</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 8</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 9</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 10</p></div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination1"></div>
<div class="swiper-button-prev swiper-button-prev1"></div>
<div class="swiper-button-next swiper-button-next1"></div>
</div>
<!-- Swiper -->
<div class="swiper-container swiper2">
<div class="swiper-wrapper">
<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 class="swiper-slide">Slide 6</div>
<div class="swiper-slide">Slide 7</div>
<div class="swiper-slide">Slide 8</div>
<div class="swiper-slide">Slide 9</div>
<div class="swiper-slide">Slide 10</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination2"></div>
</div>
<style>
body {
max-width: 1000px;
overflow: hidden;
margin: 0px auto;
}
.swiper-container {
width: 100%;
}
.swiper-slide {
text-align: center;
padding: 50px;
background: #f4f4f4;
margin-top: 25px;
}
.sliderContainer {
max-width: 500px;
}
.swiper-button-prev, .swiper-button-next {
position: absolute;
}
p {
cursor: pointer;
}
</style>
<script>
<!-- Initialize Swiper -->
var swiper1 = new Swiper('.swiper1', {
slidesPerView: 3,
spaceBetween: 10,
pagination: '.swiper-pagination1',
paginationClickable: true,
navigation: {
nextEl: '.swiper-button-next1',
prevEl: '.swiper-button-prev1',
},
});
var swiper2 = new Swiper('.swiper2', {
slidesPerView: 1,
spaceBetween: 10,
pagination: '.swiper-pagination2',
paginationClickable: true,
navigation: {
nextEl: '.swiper-button-next2',
prevEl: '.swiper-button-prev2',
},
});
<!-- Get SlideIndex -->
function geSlideDataIndex(mainSlider){
var mainSlider = document.querySelector('swiper1');
var activeIndex = mainSlider.activeIndex;
var slidesLen = mainSlider.slides.length;
if(mainSlider.params.loop){
switch(mainSlider.activeIndex){
case 0:
activeIndex = slidesLen-3;
break;
case slidesLen-1:
activeIndex = 0;
break;
default:
--activeIndex;
}
}
return activeIndex;
}
<!-- Scroll Second Slider to current Slide of first Slider on Click -->
function umswipen(activeIndex) {
swiper2.slideTo(activeIndex);
}
</script>
Here the second slider (which should be the lightbox) is of course visible, which it really should not be, but is just about the basic function
Ideas for an approach? 🙂
I think you are looking for some think lake: LightGallery.
This package can help you.

I'm trying to convert from pure html code to Vuejs but it's not working

This is the logic algorithm I'm converting and it's not working.
Popup.vue
<script>
import '../../assets/style.css'
export default {
data(){
return{
ceos: [{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."},
]
}
},
methods:{
modalCeo(i){
var modal = this.$refs.modal;
modal[0].style.display="flex";
ceos.forEach(element => {
name_ceo1.innerHTML=ceos[i].name_ceo;
position.innerHTML=ceos[i].position_ceo;
content.innerHTML=ceos[i].content;
});
},
closemodal(){
var modal = this.$refs.modal;
modal[0].style.display="none";
}
}
}
</script>
<style>
</style>
My theme:
<template>
<div class="ceo">
<div ref="modal" class="ceo-popup">
<div class="modal-content-ceo">
<div class="btn-close-popup">
<img src="../../assets/close.svg" id="btn-close-modal" type="button" #click="closemodal()">
</div>
<div class="content-main" v-for="(detail, index) in ceos" :key="index">
<h3 id="name"></h3>
<h5 id="position"></h5>
<h6 id="intro-ceo"></h6>
</div>
<img class="buiding-popup" src="../../assets/Group 226.png" alt="">
</div>
</div>
<div class="title">
<h5>Đội ngũ GoStream</h5>
<h2>Co-Founders</h2>
</div>
<div class="avatar-buiding">
<img class="buiding" src="../../assets/building-0122.png" alt="">
<div class="avatar ">
<img src="../../assets/Profile1.png" #click="modalCeo(0)">
<img src="../../assets//Profile2.png" alt="" #click="modalCeo(1)">
<img src="../../assets/Profile3.png" alt="" #click="modalCeo(2)">
</div>
</div>
</div>
</template>
I want when I click it, a pop up will appear showing the values ​​I have given.
Can you guys give me a solution to this problem?
<div class="avatar" v-for="(item, index) in images" :key="index" >
<img :src="item.url" #click="modalCeo(index)">
</div>
Script:
images:[
{url: '../../assets/Profile1.png'},
{url: '../../assets/Profile2.png'},
{url: '../../assets/Profile3.png'},
]
Update on the code I worked on but it still can't render the image.
You can simply achieve it by using Vue Modal component.
Demo :
new Vue({
el: '#app',
data: {
showModal: false,
selectedCeo: [],
ceos: [
{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."}
]
},
methods: {
modalCeo(index) {
this.showModal = true;
this.selectedCeo = this.ceos[index];
}
}
});
.modal-vue .overlay {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
}
.modal-vue .modal {
position: relative;
width: 300px;
z-index: 9999;
margin: 0 auto;
padding: 20px 30px;
background-color: #fff;
}
.modal-vue .close{
position: absolute;
top: 10px;
right: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- app -->
<div id="app" class="modal-vue">
<!-- button show -->
<button v-for="(item, index) in ceos" :key="index" #click="modalCeo(index)">{{ item.name_ceo }}</button>
<!-- overlay -->
<div class="overlay" v-if="showModal" #click="showModal = false"></div>
<!-- modal -->
<div class="modal" v-if="showModal">
<button class="close" #click="showModal = false">x</button>
<p>Name : {{ selectedCeo.name_ceo }}</p>
<p>Position : {{ selectedCeo.position_ceo }}</p>
<p>Content : {{ selectedCeo.content }}</p>
</div>
</div>
Note : I updated code snippet as per your comment. Instead of the profile pictures I used buttons just for the demo.

Easy way to apply masonry to vue grid items?

Is there an easy way to apply masonry to grid items in Vue? I've been searching through tutorials and questions here, but I haven't been able to successfully apply Masonry to my app. I'm looking for a way to use Masonry to automatically place and size the images:
<template>
<div class="row" v-if="othersImages">
<div class="col" v-if="errors">
<div class="alert alert-danger"><p>{{ errors }}</p></div>
</div>
<div id="others-images" class="grid">
<div class="grid-item" v-for="image in othersImages" :key="image.id">
<h5>{{ image.name }}</h5>
<picture v-bind="'image' + image.id">
<img v-bind:src="image.image.path" v-bind:alt="image.description"/>
</picture>
</div>
<div class="clearfix"></div>
</div>
</div>
</template>
<script>
export default {
name: 'othersImages',
created() {
this.fetchImages();
},
data() {
return {
apiRequest: new this.$request(),
othersImages: [],
errors: '',
};
},
methods: {
fetchImages() {
const endpoint = 'images';
this.apiRequest.get(endpoint)
.then((response) => {
this.othersImages = response;
this.errors = '';
})
.catch((errors) => {
this.errors = errors;
});
},
},
};
</script>
I believe, the easiest way to handle that is applying one plugin based on npm package: https://www.npmjs.com/package/vue-masonry. That's the simple library with good supporting and small size.
<template>
<div data-masonry='{"percentPosition": true }' class="row">
<div class="full col-lg-4 half"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
</div>
</template>
<script>
export default {}
</script>
<style>
.row {
width: 80vw;
height: 600px;
background-color: green;
margin: auto;
}
.full {
height: 150px;
background-color: grey;
border: 1px solid black;
}
.half {
height: 75px;
background-color: grey;
border: 1px solid black;
}
</style>
You should add bootstrap and masonry cdn's to your projects, then simply adding
data-masonry='{"percentPosition": true }'
line to your row, masonry works automatically.
Check out this link for more info.

SwiperJS Thumbs bug

Created a swipe with thumbs. When I click on thumbs, it scrolls to the right with incomprehensible logic. I cannot understand what this may be connected with, I am trying to solve this problem for the second day, nothing comes out. Is it possible to somehow disable this option so that you can remove this scroll when clicked?
const productThumbs = new Swiper(".swiper-thumbs", {
spaceBetween: 30,
loop: true,
slidesPerView: 6,
loopedSlides: 7,
});
const productCarousel = new Swiper(".swiper-content", {
effect: 'fade',
fadeEffect: {
crossFade: true
},
touchRatio: 0,
thumbs: {
swiper: productThumbs,
}
});
.swiper-slide{
background: gray;
}
.swiper-thumbs .swiper-slide{
height: 300px;
}
.swiper-content{
margin-top: 30px;
}
.swiper-thumbs .swiper-slide{
display: flex;
flex-direction: column;
}
.swiper-content .swiper-slide{
height: 250px;
background: black;
color: white;
font-size: 72px;
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper-container swiper-thumbs">
<div class="swiper-wrapper">
<div class="swiper-slide">
<span class="slider-title">01</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">02</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">03</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">04</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">05</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">06</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="swiper-container swiper-content">
<!-- 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 class="swiper-slide">Slide 6</div>
</div>
</div>
I tried to do this, but I just simply do not understand why this is happening
In the "thumbs" slider, you need to change the value "loop" to "false" or remove the key "loop" from "thumbs" slider.

Stacked progress bars with labels and min-width

I've got my stacked progress bars looking nice, with percentage labels on each, but I'm not sure how to solve when a percentage causes the bar to be too small for the label.
Setting a min-width works for non-stacked progress bars, but breaks stacked ones.
How can I fix this without hacking up bootstrap too much?
Example fiddle: http://jsfiddle.net/nimh/kx7hvxyz/
<div class="container-fluid">
<div class="row-fluid">
<div class="panel panel-default max-width">
<div class="panel-body">
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 89.74%">
<div class="text-left">+89.74%</div>
</div>
<div class="progress-bar progress-bar-danger" style="width: 10.26%">
<div class="text-right">-10.26%</div>
</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 10.26%">
<div class="text-left">+10.26%</div>
</div>
<div class="progress-bar progress-bar-danger" style="width: 89.74%">
<div class="text-right">-89.74%</div>
</div>
</div>
</div>
</div>
</div>
Had a night to think about it and realized i can add a max-width percentage, as well as a min-width percentage, to keep stacked progress bars at least wide enough to show a label on both.
.progress-bar {
min-width: 15%;
max-width: 85%;
}
http://jsfiddle.net/nimh/kx7hvxyz/8/
It's not perfect (may look funny with a 99% and 1%), but will work for showing a label at all times for our needs.
How about playing with the line-height and font-size?
[1]: http://www.bootply.com/Tq7YbaeOX5
/* CSS used here will be applied after bootstrap.css */
.max-width {
max-width: 25em;
}
/* .progress-bar {
min-width: 4em;
} */
.progress-bar {
padding: 4px;
line-height: 12px;
}
.text-Left {
font-size: 12px;
float: left;
}
.text-left, .text-right {
font-size: 7px;
padding-right:5px;
}
.text_Right {
float: right;
}
<div class="container-fluid">
<div class="row-fluid">
<div class="panel panel-default max-width">
<div class="panel-body">
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 89.74%">
<div class="text-Left">+89.74%</div>
</div>
<div class="progress-bar progress-bar-danger" style="width: 10.26%">
<div class="text-right">-10.26%</div>
</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 10.26%">
<div class="text-left">+10.26%</div>
</div>
<div class="progress-bar progress-bar-danger" style="width: 89.74%">
<div class="text_Right">-89.74%</div>
</div>
</div>
</div>
</div>
</div>
</div>