Как в Swiper Slider показать содержимое табов — position absolute?
Задача реализовать блок категории в виде табов и завернуть в слайдер.
Проблема по части верстки.
Проблема состоит в том что у самого слайдера выставленно свойство overflow и оно " режет" все что выходит за рамки слайдера - не видим содержимое .category-content (postion:absolute), скрипт табов продолжает работать корректно.
Если убираем у слайдера свойство overflow появляются скролы и содержимое слайдера выходит за пределы экрана, но тогда визуально видно корректную работу табов
Необходимо решите обе проблемы что бы и слайдер не выходил за рамки контейнера и контент табов не урезался.
Код
<ul class="products__slider category-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <li class="category-slide category-slide__all" data-tab="all"> <img src="img/category/all.svg" alt="All" class="category-slide__icon"> <span class="category-slide__title">All</span> <!-- /.category-slide --> </li> </div> <div class="swiper-slide"> <li class="category-slide" data-tab="herbs"> <img src="img/category/herbs.svg" alt="Herbs" class="category-slide__icon"> <span class="category-slide__title">Herbs</span> <b> Блок таб контента - postiion absolute</b> <div class="category-content" data-tab-content id="herbs"> <div class="category-subcontent"> <ul class="category-subnav"> <li class="category-subnav__item"> <a href="#" class="category-subnav__link"> Herbs </a> </li> </ul> <a href="#" class="category-subcontent__link">View all Herbs</a> </div> </div> </li> <!-- /.category-slide --> </div> <div class="swiper-slide"> <li class="category-slide" data-tab="vegetables"> ... </li> <!-- /.category-slide --> </div> ... </div> </ |
<ul class="products__slider category-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <li class="category-slide category-slide__all" data-tab="all"> <img src="img/category/all.svg" alt="All" class="category-slide__icon"> <span class="category-slide__title">All</span> <!-- /.category-slide --> </li> </div> <div class="swiper-slide"> <li class="category-slide" data-tab="herbs"> <img src="img/category/herbs.svg" alt="Herbs" class="category-slide__icon"> <span class="category-slide__title">Herbs</span> <b> Блок таб контента - postiion absolute</b> <div class="category-content" data-tab-content id="herbs"> <div class="category-subcontent"> <ul class="category-subnav"> <li class="category-subnav__item"> <a href="#" class="category-subnav__link"> Herbs </a> </li> </ul> <a href="#" class="category-subcontent__link">View all Herbs</a> </div> </div> </li> <!-- /.category-slide --> </div> <div class="swiper-slide"> <li class="category-slide" data-tab="vegetables"> ... </li> <!-- /.category-slide --> </div> ... </div> </
Где . category-slide выступает в виде таба а блок .category-content содержимое с postiion: absolute
При нажатии на .category-slide показываем блок .category-content, без подключения swiper слайдера все отлично работает.
.category &-slider //display: flex //align-items: center //column-gap: 12px overflow: hidden &-slide position: relative flex-shrink: 0 padding: 15px 20px display: flex align-items: center font-size: 14px font-weight: 400 line-height: 1.78 text-transform: uppercase color: $text-color border: 2px solid $border-color border-radius: 8px transition: border, color, 0.3s ease-in cursor: pointer &:hover color: $text-color-accent border: 2px solid $bg-color-accent &__icon margin-right: 8px &-content position: absolute bottom: 0 left: 0 opacity: 1 visibility: visible display: block width: 100% &__hidden opacity: 0 visibility: hidden &::before position: absolute content: '' top: calc(100% + 25px) left: 50% transform: translate(0 -50%) display: inline-block width: 0 height: 0 border-style: solid border-width: 0 14.5px 13px 14.5px border-color: transparent transparent $bg-color-light transparent z-index: 12 &-subcontent position: absolute padding: 37px 30px 30px 30px width: 530px display: block top: calc(100% + 37px) border-radius: 8px border: 1px solid $border-color z-index: 10 background: $bg-color-light box-shadow: 0px 4px 58px rgba(199, 199, 199, 0.50) |
.category &-slider //display: flex //align-items: center //column-gap: 12px overflow: hidden &-slide position: relative flex-shrink: 0 padding: 15px 20px display: flex align-items: center font-size: 14px font-weight: 400 line-height: 1.78 text-transform: uppercase color: $text-color border: 2px solid $border-color border-radius: 8px transition: border, color, 0.3s ease-in cursor: pointer &:hover color: $text-color-accent border: 2px solid $bg-color-accent &__icon margin-right: 8px &-content position: absolute bottom: 0 left: 0 opacity: 1 visibility: visible display: block width: 100% &__hidden opacity: 0 visibility: hidden &::before position: absolute content: '' top: calc(100% + 25px) left: 50% transform: translate(0 -50%) display: inline-block width: 0 height: 0 border-style: solid border-width: 0 14.5px 13px 14.5px border-color: transparent transparent $bg-color-light transparent z-index: 12 &-subcontent position: absolute padding: 37px 30px 30px 30px width: 530px display: block top: calc(100% + 37px) border-radius: 8px border: 1px solid $border-color z-index: 10 background: $bg-color-light box-shadow: 0px 4px 58px rgba(199, 199, 199, 0.50)
JavaScript
const categorySlider = new Swiper('.category-slider', { loop: true, slidesPerView: 6, slidesPerGroup: 1, spaceBetween: 12, speed: 1000, grabCursor: true, disableOnInteraction: false, // autoplay: { // delay: 1000 // }, keyboard: { enabled: true }, }); //Tabs window.addEventListener('click', event => { if(!event.target.closest('[data-tab]')){ closeTabs(); } }) const tabs = document.querySelectorAll('[data-tab]'); const content = document.querySelectorAll('[data-tab-content]'); //Close all tabContent const closeTabs = () => { tabs.forEach(item => item.classList.remove('category-slide__active')); content.forEach(item => { item.classList.add('category-content__hidden'); }); } //Закрыть все табы при старте closeTabs(); tabs.forEach(item => { item.addEventListener('click', () => { const tabContent = document.querySelector(`#${item.dataset.tab}`); if(!tabContent) return false; //Закрыть все остальные табы кроме текущего closeTabs(); item.classList.add('category-slide__active'); tabContent.classList.remove('category-content__hidden'); tabContent.addEventListener('click', event => { event.stopPropagation(); if(event.target.closest('a').getAttribute('href')){ closeTabs(); } }); }); }); |
const categorySlider = new Swiper('.category-slider', { loop: true, slidesPerView: 6, slidesPerGroup: 1, spaceBetween: 12, speed: 1000, grabCursor: true, disableOnInteraction: false, // autoplay: { // delay: 1000 // }, keyboard: { enabled: true }, }); //Tabs window.addEventListener('click', event => { if(!event.target.closest('[data-tab]')){ closeTabs(); } }) const tabs = document.querySelectorAll('[data-tab]'); const content = document.querySelectorAll('[data-tab-content]'); //Close all tabContent const closeTabs = () => { tabs.forEach(item => item.classList.remove('category-slide__active')); content.forEach(item => { item.classList.add('category-content__hidden'); }); } //Закрыть все табы при старте closeTabs(); tabs.forEach(item => { item.addEventListener('click', () => { const tabContent = document.querySelector(`#${item.dataset.tab}`); if(!tabContent) return false; //Закрыть все остальные табы кроме текущего closeTabs(); item.classList.add('category-slide__active'); tabContent.classList.remove('category-content__hidden'); tabContent.addEventListener('click', event => { event.stopPropagation(); if(event.target.closest('a').getAttribute('href')){ closeTabs(); } }); }); });
Еще отдельно вопрос- по структуре кода можно ли оставить в таком виде слайдер в виде списка UL>LI, каждый li завернуть в .swiper-slide или переделать на .swiper-slide> div>button
Дополнительно:
Воспользуйтесь tippyjs и вызывайте её с параметром:
appendTo: () => document.body,
Контент будет помещен поверх всего сайта
Еще отдельно вопрос- по структуре кода можно ли оставить в таком виде слайдер в виде списка UL>LI, каждый li завернуть в .swiper-slide или переделать на .swiper-slide> div>button
li должны быть вложены в ul в таком виде:
<ul> <li></li> <li></li> <li></li> </ul> |
<ul> <li></li> <li></li> <li></li> </ul>
И никак иначе, поэтому вы можете сделать разве что так:
<ul class="swiper-wrapper"> <li class="swiper-slide"></li> <li class="swiper-slide"></li> <li class="swiper-slide"></li> </ul> |
<ul class="swiper-wrapper"> <li class="swiper-slide"></li> <li class="swiper-slide"></li> <li class="swiper-slide"></li> </ul>
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос


Для того чтобы показать содержимое табов в Swiper Slider с использованием position absolute, вам нужно сделать следующее:
1. Создайте контейнер для слайдов и табов:
```html
```
2. Примените стили к вашим табам и их содержимому:
```css
.swiper-slide {
position: relative;
}
.tab-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
}
.swiper-slide-active .tab-content {
display: block;
}
```
3. Инициализируйте Swiper Slider и добавьте обработчик события изменения слайда:
```php
var mySwiper = new Swiper('.swiper-container', { // Настройки Swiper Slider on: { slideChange: function () { var activeSlide = this.slides[this.activeIndex]; var tabContent = activeSlide.querySelector('.tab-content'); tabContent.style.display = 'block'; } } });
```
Теперь при изменении слайда Swiper Slider будет показывать содержимое таба с использованием position absolute. Не забудьте настроить стили и другие параметры под свои потребности.