-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
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
Navigation and pagination positioning around slider (not over) #3736
Comments
me too: I'd like to build a carousel (Multiple Slides Per View) with arrows at left and right outside the slideshow area. How to? |
I was able to get this working today. Here's the HTML layout: <div class="relative -mx-6 px-6">
<div class="swiper-container home-large-carousel w-full mt-2">
<div class="swiper-wrapper">
<div class="swiper-slide md:flex">
...
</div>
<div class="swiper-slide md:flex">
...
</div>
<div class="swiper-slide md:flex">
...
</div>
</div>
<div class="carousel-pagination flex items-center justify-center mt-5"></div>
</div>
<div class="carousel-navigation-prev flex items-center absolute z-10 top-0 bottom-0 left-0 right-auto cursor-pointer" role="button" aria-label="Previous Video">
{{-- SVG ICON --}}
</div>
<div class="carousel-navigation-next flex items-center absolute z-10 top-0 bottom-0 left-auto right-0 cursor-pointer" role="button" aria-label="Next Video">
{{-- SVG ICON --}}
</div>
</div> And here's the JS (the snippet below also includes custom pagination): // core version + navigation, pagination modules:
import Swiper, { Navigation, Pagination } from "swiper";
// configure Swiper to use modules
Swiper.use([Navigation, Pagination]);
// import Swiper styles
import "swiper/swiper-bundle.css";
/**
* Create Swiper instances.
*/
const swiperCarousels = document.querySelectorAll(".swiper-container");
if (swiperCarousels.length) {
swiperCarousels.forEach(carouselContainer => {
const carouselPagination = carouselContainer.querySelector(
".carousel-pagination"
);
const carouselPrevButton =
carouselContainer.querySelector(".carousel-navigation-prev") ||
carouselContainer.parentElement.querySelector(
".carousel-navigation-prev" // <-- this is how you can have the Prev Button outside the swiper container
);
const carouselNextButton =
carouselContainer.querySelector(".carousel-navigation-next") ||
carouselContainer.parentElement.querySelector(
".carousel-navigation-next" // <-- this is how you can have the Next Button outside the swiper container
);
const swiperInstance = new Swiper(carouselContainer, {
loop: true,
pagination: {
el: carouselPagination,
type: "custom",
renderCustom: renderCarouselPaginationBullets
},
navigation: {
nextEl: carouselNextButton,
prevEl: carouselPrevButton
}
});
/**
* Swiper's "clickable" option does not work with custom pagination,
* so we have to manually make the pagination's bullets clickable.
*/
carouselPagination.addEventListener("click", function(e) {
const { slide } = e.target.dataset;
if (slide) {
swiperInstance.slideTo(slide);
}
});
});
}
/**
* Generate custom pagination bullets.
*
* @param {Swiper} swiper
* @param {number} current
* @param {number} total
*
* @return {string}
*/
function renderCarouselPaginationBullets(swiper, current, total) {
const bullets = [];
for (let index = 1; index <= total; index++) {
const bullet = document.createElement("div");
let className =
"w-2 h-2 bg-gray-400 rounded-full mr-1 cursor-pointer";
if (current === index) {
// handle active bullet
}
bullet.className = className;
bullet.setAttribute("data-slide", index);
bullets.push(bullet);
}
return bullets.map(bullet => bullet.outerHTML).join(" ");
} |
Same for me, I'd like to position the slider nav outside the slides, too. The workarounds look promising. Maybe there could be integrated a native solution? |
In fact, just put them wherever you want and then reference them when initializing the Swiper. If you have many swipers, put them into containers with unique ids and then use the ids to reference the navigation buttons. For example, here the swiper code in on the 'slideshow' external template, and it's on a content-section container with unique ID: <div class="content-section slideshow-block carousel-block <?php echo $object_id ?> ">
<?php get_template_part('template-parts/slideshow'); ?>
<div class="carousel-swiper-navigation">
<div class="carousel-slider-button-prev slider-arrow"><?php echo file_get_contents(get_img_url('freccia-slideshow.svg')); ?></div>
<div class="carousel-slider-button-next slider-arrow"><?php echo file_get_contents(get_img_url('freccia-slideshow.svg')); ?></div>
</div>
</div> Then in my js code: [...]
let object_id = slider_element.data('objectid');
let options = {
slidesPerView: 4,
spaceBetween: 30,
navigation: {
nextEl: '.' + object_id + ' .carousel-slider-button-next', // look here
prevEl: '.' + object_id + ' .carousel-slider-button-prev', // and here
}
,watchOverflow: true // disable con una sola slide
}
[... and so on, then pass the options to swiper] |
If you put them outside IMHO, best workaround is option 2 in first message, if u are able to edit the code. |
Obviously, when you put things outside the swiper container, you put them into your responsibility. But It's a well made and though script, it's not too difficult to add some good css to make it as you need. For me it took just minutes. I think it depends on what one needs and what his skills are. Anyway, if the developer will add some new updates/utilities to Swiper to accomplish our needs, it's better, for sure. But don't be scared of my method: most of the times will do, fast and easy. |
I know, don't get me wrong, I could easily do my own CSS, but I'd prefer not, not just only to "not reinvent the wheel", but to prevent me to fix that CSS in case future releases changes. My workaround was to edit the plugin code (cause I use it in a legacy project: no NPM, no ES6+), so that the plugin searches for the wrapper div in all children hierarchically, and inject my own This is a pretty good and easy "fix" for the developers to do, which requires no new major version imho. |
Hi, how can I use outside navigation's element with the React component too? navigation={{
prevEl: ".my__slider .swiper-button-prev.icon-prev",
nextEl: ".my__slider .swiper-button-next.icon-next",
}} but if I have more then one of the same component, the pagination click will trigger all the swipers. I tried using |
I don't use react. Anyway the same issue applies on non react environments. I think the easiest thing is to wrap the sliders in elements with unique ids and use the ids for selectors. Please see my example above. |
@nolimits4web could you explain, how can I make custom navigation outside the container happen, using react? |
I achieved navigation around with margin and position <div className="relative md:w-1/6">
<Swiper
spaceBetween={0}
slidesPerView={1}
navigation={{
prevEl: navigationPrevRef.current,
nextEl: navigationNextRef.current,
}}
modules={[Navigation]}
style={{ marginLeft: '80px', marginRight: '80px', position: 'unset' }}
>
<SwiperSlide className="flex items-center justify-center">
<div>
<p>Slide 1</p>
<p>Slide 1</p>
<p>Slide 1</p>
<p>Slide 1</p>
<p>Slide 1</p>
<p>Slide 1</p>
</div>
</SwiperSlide>
<SwiperSlide className="flex items-center justify-center">
<div>
<p>Slide 2</p>
<p>Slide 2</p>
<p>Slide 2</p>
<p>Slide 2</p>
<p>Slide 2</p>
<p>Slide 2</p>
</div>
</SwiperSlide>
<div
ref={navigationPrevRef}
className="flex items-center absolute top-0 bottom-0 left-0 right-auto cursor-pointer"
>
{/* --- SVG ICON */}
</div>
<div
ref={navigationNextRef}
className="flex items-center absolute top-0 bottom-0 left-auto right-0 cursor-pointer"
>
{/* --- SVG ICON */}
</div>
</Swiper>
</div>
``` |
My solution for pagination is to allow overflow in y-direction add a padding at the bottom: |
hi are there any solutions for this problem with CDN option |
Found a solution that simulates navigation outside the container, made the slides width 93%: .flex{ |
This is a (multiple allowed):
bug
enhancement
feature-discussion (RFC)
Swiper Version: 6.0.4
Platform/Target and Browser Versions: Ubuntu 18 // Google Chrome 84.0.4147.105
Issue
I wish I could move arrows and pagination/scrollbar outside the slider (not over). Now it's impossible to do it correctly and honour the vertical/horizontal direction.
swiper-container
hasoverflow:hidden
, so I can't position arrows/pagination/scrollbar elements outside it or they get hidden.I can't remove the
overflow:hidden
property from container or slides get visible outside the container...xxx-horizontal
andxxx-vertical
classes are added toswiper-container
, so even if I take the arrows/pagination/scrollbar outside the container, I'd be unable to know which direction is the slider configured with (yes, I could use the "all siblings css selector"~
, but I'd feel kinda dirty)Possible solutions
div
around theswiper-wrapper
, something likeswiper-clip
that has theoverflow:hidden
style.wrapperClass
hierarchically within the element, instead of searching only direct children. Usefind
method here (like it is used forprevEl
,nextEl
,pagination.el
, ...):swiper/src/components/core/core-class.js
Line 144 in 77d72e4
This way I could create the
swiper-clip
element myselfOption 1 would be my prefered, though it would not be simple, and may cause a new major version.
Option 2 is very simple, just a patch.
The text was updated successfully, but these errors were encountered: