How can I initially set a slide container to be 10% away from left margin and when reached the end, 10% away from right margin? (vue-awesome-swiper)
Asked Answered
A

6

5

This is probably an easy question but I can't seem to find a solution to this..

I am using vue-awesome-swiper(https://github.surmon.me/vue-awesome-swiper/). I would like to have something like this:

Initial margin on the left by 10%: Transition Begin

When the inner slides are visible, they are touching left and right(full width stretch): enter image description here

When the last slide is reached, a margin-right of 10%: Transition End

Examples can be found here: https://github.surmon.me/vue-awesome-swiper/.

I added margin-left:10%; to the swiper-wrapper class which works for me as the initial margin, but this covers my last slide as the content is shift by 10%. I would like margin-left to be removed when the last slide is reached and vice versa.

I tried looking at events(https://swiperjs.com/api/#events): reachEnd and reachBeginning. Both of these, I tried to apply like this:

<template>
<div>
      <swiper
        class="swiper"
        :options="swiperOption"
        :reach-beginning="handleTransitionStart"
        :reach-end="handleTransitionEnd"
        :style="transitionStarted ? { margin: '0 0 0 10%' } : { margin: '0 10% 0 0' }"

      >
.....
</swiper>
</div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class InformationSection extends Vue {
  @Prop() 'reachEnd'!: any;
  @Prop() 'reachBeginning'!: any;

  swiperOption = {
    slidesPerView: 4,
    spaceBetween: 30,
    pagination: {
      el: '.swiper-pagination',
      clickable: true,
    },
  };

  transitionStarted: boolean = true;

  handleTransitionStart(): any {
    // eslint-disable-next-line no-console
    console.log('Started');
    this.transitionStarted = true;
  }

  handleTransitionEnd(): any {
    // eslint-disable-next-line no-console
    console.log('Ended');
    this.transitionStarted = false;
  }
}
</script>

<style scoped>

  .swiper-slide {
    width: 60%;
  }
  .swiper-slide:nth-child(2n) {
      width: 40%;
  }
  .swiper-slide:nth-child(3n) {
      width: 20%;
  }

</style>

The above does not add margin to the right at the end. How can I achieve this goal?

Ave answered 7/5, 2020 at 13:43 Comment(1)
#67380362Pithead
P
8

slidesOffsetAfter

slidesOffsetBefore

Ref: https://swiperjs.com/swiper-api#param-slidesOffsetAfter

if($('.swiper').length !== 0){
const swiper = new Swiper('.swiper', {
    loop: false,
    slidesOffsetBefore: 5, // This is 5px slide offset 
    slidesPerView: 1.3,  // second slide partial show (In this question it was probably 3.5)
    centeredSlides: true // centering slides
    spaceBetween: 10,
  }
});}
Pithead answered 18/10, 2022 at 13:48 Comment(0)
B
6

I recall needing something similar and ended up building my own scroller component. But that's not for everyone.

There's a hacky way to do it, and I hope you find something cleaner.

The first slide has a margin <swiper-slide style="margin-left:10%;">I'm Slide 1</swiper-slide>

and the last slide is invisible <swiper-slide style="opacity:0;"></swiper-slide>

Vue.use(VueAwesomeSwiper)
new Vue({
  el: '#vueapp',
  components: {
    LocalSwiper: VueAwesomeSwiper.swiper,
    LocalSlide: VueAwesomeSwiper.swiperSlide,
  },
  data: {
    swiperOptionA: {

      slidesPerView: 4,
      spaceBetween: 30,
      pagination: {
        el: '.swiper-pagination',
        clickable: true,
      },
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev'
      }
    },
  },
  computed: {
    swiperA() {
      return this.$refs.awesomeSwiperA.swiper
    },
  },
})
.swiper-container {
  height: 300px;
  width: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 38px;
  font-weight: 700;
  background-color: #eee;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/css/swiper.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/js/swiper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-awesome-swiper.js"></script>

<div id="vueapp">
    <swiper ref="awesomeSwiperA" :options="swiperOptionA">
      <!-- slides -->
      <swiper-slide style="margin-left:10%;">I'm Slide 1</swiper-slide>
      <swiper-slide>I'm Slide 2</swiper-slide>
      <swiper-slide>I'm Slide 3</swiper-slide>
      <swiper-slide>I'm Slide 4</swiper-slide>
      <swiper-slide>I'm Slide 5</swiper-slide>
      <swiper-slide>I'm Slide 6</swiper-slide>
      <swiper-slide>I'm Slide 7</swiper-slide>
      <swiper-slide style="opacity:0;"></swiper-slide>
      <!-- Optional controls -->
      <div class="swiper-pagination"  slot="pagination"></div>
      <div class="swiper-button-prev" slot="button-prev"></div>
      <div class="swiper-button-next" slot="button-next"></div>
    </swiper>
    <br>
</div>
Blacklist answered 7/5, 2020 at 17:7 Comment(0)
S
0

The way I achieved this is to set the overflow property of .swiper-container to visible, place it inside a div that has the required margin, and give another outer div the property of overflow: hidden like so:

<div style="overflow: hidden">
    <div style="margin: 0 1rem">
        <div class="swiper-container" style="overflow: visible">
            <!-- ... -->
        </div>
    </div>
</div>

There may also be another way which is to set the width of .swiper-container less than 100% and ensure it is centred inside the parent element, but I haven't tried it out.

Saccharase answered 19/9, 2021 at 8:25 Comment(0)
I
0

The problem I faced is a bit different, because it's not percentage but a mere 32px of margin left. I solved it by doing just css of these:

.swiper-wrapper {
  margin-left: 32px;
}

.swiper-wrapper .swiper-slide:last-child{
  padding-right: 32px;
}

If I only add the margin-left to the .swiper-wrapper, the last slide will be cut 32px, hence I add the last slide to be 32px more wider by adding a padding-right. Similar approach is you can use margin-right or :after selector to make the last slide wider.

Interrupt answered 15/10, 2022 at 5:17 Comment(0)
M
0

Worked for me.
_SW - screen width of website
1440 - random choosen width of screen
200 - optimal slidesOffsetBefore

const raw_offset = (_SW * 100) / 1440
const offset = (200 * raw_offset) / 100
Masera answered 21/2 at 16:30 Comment(0)
C
0

Just add slidesOffsetBefore and slidesOffsetAfter in your swiper config

const swiper = new Swiper('.swiper', {
    slidesPerView: 3.5,  // half of last slide element in viewport show
    slidesOffsetBefore: 16, // This number is in px
    slidesOffsetAfter: 16, // This number is in px
    spaceBetween: 16, // This number is in px
    centeredSlides: true, // centering slides

  }
});}

Or slides-offset-before and slides-offset-after attributes if you use the swiper element

<swiper-container slides-per-view="3.5" slides-offset-before="16" slides-offset-after="16" space-between="16" centered-slides="true">
  <swiper-slide> </swiper-slide>
</swiper-container>
Cox answered 1/3 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.