• Skip to main content
  • Skip to primary sidebar

Web Development Archive

  • Archive
You are here: Home / Other / Swiper as WebComponent with AutoPlay

Swiper as WebComponent with AutoPlay

<section class="news">
<div class="container">
<h2 class="news-title">Látásmódunk - néhány kiragadott példán keresztül</h2>

<div class="news-swiper">

<!-- Swiper Container -->
<swiper-container
#swiperRef
[slidesPerView]="1"
[spaceBetween]="10"
[loop]="true"
autoplay-delay="3000"
autoplay-disable-on-interaction="true"
autoplay-pause-on-mouse-enter="true"
>
<swiper-slide *ngFor="let news of newsItems">
<article class="news-card">
<div class="news-card-overlay"></div>
<picture>
<source media="(min-width: 1200px)" [srcset]="news.img_xl">
<source media="(min-width: 992px)" [srcset]="news.img_lg">
<source media="(min-width: 768px)" [srcset]="news.img_md">
<img class="news-image" [src]="news.img_sm" [alt]="news.alt" />
</picture>
<div class="news-caption">
<h3 class="news-caption-title">{{ news.title }}</h3>
<app-button [link]="news.link" [label]="'CTA.READMORE' | transloco"></app-button>
</div>
</article>
</swiper-slide>
</swiper-container>

<!-- Custom Pagination -->
<div class="news-pagination">
<div
class="pagination-item"
*ngFor="let news of newsItems; let i = index"
[class.active]="i === activeIndex"
(click)="setActiveSlide(i)"
>
<span class="pagination-progress" [class.running]="i === activeIndex"></span>
<span class="pagination-label">
{{ news.title }}
</span>
</div>
</div>
<span class="news-swiper-overlay"></span>
</div>
</div>
</section>
import { Component, CUSTOM_ELEMENTS_SCHEMA, PLATFORM_ID, Inject, ViewChild, ElementRef } from '@angular/core';
import { ButtonComponent } from '../../../../shared/components';
import { TranslocoPipe } from '@jsverse/transloco';
import { MockNews } from './news.mock';
import { News } from './news.model';
import { CommonModule, isPlatformBrowser } from '@angular/common';

import { register, SwiperContainer } from 'swiper/element/bundle';
register();



@Component({
selector: 'app-news',
imports: [CommonModule, ButtonComponent, TranslocoPipe],
templateUrl: './news.component.html',
styleUrl: './news.component.scss',
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class NewsComponent {
@ViewChild('swiperRef', { static: true })
protected _swiperRef!: ElementRef<HTMLElement>;

newsItems: readonly News[] = MockNews;
activeIndex: number = 0;

constructor(@Inject(PLATFORM_ID) private platformId: object) {}

ngAfterViewInit() {
if (!isPlatformBrowser(this.platformId)) return;
const el = this._swiperRef.nativeElement as any;

el.addEventListener('slidechange', (e: any) => {
this.activeIndex = e.detail[0].realIndex;
});

el.initialize();
}

setActiveSlide(idx: number) {
if (!isPlatformBrowser(this.platformId)) return;
const swiper = (this._swiperRef.nativeElement as any).swiper;
swiper.slideToLoop(idx);
this.activeIndex = idx;
}

}
@use "shared" as *;

.news{
background: var(--color-black);
color: var(--color-white);
&-swiper{
position: relative;
padding-bottom: 80px;

}
&-title{
font-size: 32px;
text-align: center;
line-height: 120%;
margin-bottom: 48px;
@include media-breakpoint-up(md){
font-size: 40px;
}
}
&-card {
position: relative;
display: inline-block;
width: 100%;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 8px 24px rgba(0,0,0,0.2);
&-overlay{
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.9) 70%);
position: absolute;
width: 100%;
height: 70%;
bottom: 0;
left: 0;
z-index: 9;
}
}
&-image {
display: block;
width: 100%;
height: auto;
object-fit: cover;
}
&-caption {
position: absolute;
bottom: 100px;
left: 0px;
right: 20px;
text-align: left;
padding: 60px 24px 32px;
width: 100%;
z-index: 9;
@include media-breakpoint-up(md){
padding: 60px 32px 40px;
}
&-title {
font-weight: bold;
line-height: 1.2;
margin-bottom: 24px;
font-size: 20px;
position: relative;
z-index: 999;
@include media-breakpoint-up(md){
font-size: 24px;
max-width: 423px;
}
}
}
&-pagination {
position: absolute;
bottom: 110px;
left: 32px;
display: flex;
justify-content: space-between;
padding: 0;
gap: 16px;
margin-top: 32px;
z-index: 9;
@include media-breakpoint-up(md){
margin-top: 45px;
}
@include media-breakpoint-up(lg){
margin-top: 48px;
gap: 32px;
}
.pagination-item {
flex: 1;
position: relative;
cursor: pointer;
border-top: 2px solid var(--color-grey-400);
transition: opacity 0.3s, border-color 0.3s;
width: 100%;

.pagination-progress {
position: absolute;
top: -2px;
left: 0;
height: 2px;
width: 0;
background-color: var(--color-primary);
transition: width 1s;
}

.pagination-label {
display: none;
@include media-breakpoint-up(lg){
display: block;
font-size: 14px;
line-height: 1.4;

color: var(--color-grey-400);
display: block;
margin-top: 8px;
}
}

&.active,
&:hover {
opacity: 1;
border-top-color: var(--color-primary);
.pagination{
&-progress {
width: 100%;
}
&-label{
color: var(--color-white);
}
}
}
}

.pagination-item.active .pagination-progress {
background-color: var(--color-primary);
}
}
}



swiper-container {
width: 100%;
}

swiper-slide {
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5rem;
}

Filed Under: Other

About Gabor Flamich

I'm a web developer and designer based in Budapest, Hungary. In recent years, I've documented hundreds of solutions I came across during development. This site is an archive for useful code snippets on WordPress, Genesis Framework and WooCommerce. If You have any questions related to WordPress development, get in touch!

Primary Sidebar

  • angular.io
© 2026 WP Flames - All Right Reserved