I've been a few days now trying to understand how can I style my .active.center slide that was generated by the Ngx Owl Carousel structural directive.
As you can see in the image below, I have a .owl-item.active.center that was generated by the template part <ng-template carouselSlide>
. I just want to know how can I style it, because I am not being able to access it directly using .owl-item.active.center
.
Below is my attempt.
My Template:
<!-- Testimonials Carousel. Data is sent from TypeScript.
"Change" event generates SlidesOutputData object - https://www.npmjs.com/package/ngx-owl-carousel-2#change
Logic: Pass SlidesOutputData object to getData function. -->
<owl-carousel-o [options]="testimonialsCarousel" (change)="getData($event)" class="w-100">
<!-- We can't apply styles to NgContainer directly. -->
<ng-container *ngFor="let testimonial of testimonials">
<!-- DOMs were rendered using carouselSlide structural directive. You can't apply directives/element attributes here.
What I need: Get access and style slide object with attributes "Active" and "Center" -->
<ng-template carouselSlide>
<!-- Testimonial with Local Variable defined -->
<article #testimonialarticle class="d-flex flex-column align-items-center
shadow p-4 m-3 text-center testing-class">
<!-- Insert image using Property Binding -->
<figure><img class="img-circle" [src]="testimonial.avatar" [alt]="testimonial.avatarAlt"></figure>
<!-- Syntax below is: Interpolation / Data Binding -->
<p>{{testimonial.text}}</p>
<p>{{testimonial.author}}</p>
</article>
<!-- End of Testimonial -->
</ng-template>
</ng-container>
</owl-carousel-o>
My TypeScript:
// Carousel Class that uses OnInit
export class RowClientsComponent implements OnInit {
// Etc
testimonialsCarousel: OwlOptions = {
center: true,
dots: true,
// Slide continuously
autoplay: false,
loop: true,
// autoplayTimeout higher than autoplaySpeed | smartSpeed
autoplayTimeout: 5000,
autoplaySpeed: 1000,
smartSpeed: 1000,
autoplayHoverPause: true,
autoWidth: true,
items: 3
}
// Testimonials - 1. Define Interface, 2. Array of Type Interface
testimonials: Testimonial[] = [
// Data for Slides...
// Etc...
]
// New object of type "SlidesOutputData" that is generated after "Change" event.
activeSlides?: SlidesOutputData = new SlidesOutputData; // ? - Can be null
// Update activeSlides object with data sent from event defined in template
// Ref. https://www.npmjs.com/package/ngx-owl-carousel-2#events
getData(data: SlidesOutputData) {
// Import data from SlidesOutputData to activeSlides - The `This` is the component class.
this.activeSlides = data;
// Loop through slides and check if any slide has center attribute true
if (this.activeSlides && this.activeSlides.slides) {
for (const slide of this["activeSlides"].slides) {
if (slide.center === true) {
console.log('Slide centralizado:', slide);
// If it's centered - I want to add a class to it so I can style using the component CSS
}
}
}
}
// Inject reference to DOM element with @ViewChild and wrap it's native DOM element to nativeElement in @ElementRef
@ViewChild('testimonialarticle')
classArticle: ElementRef = new ElementRef('testimonialarticle');
ngOnInit() {
// Print "Testimonial Article" element using ElementRef wrapper, through his nativeElement property.
console.log(this.classArticle);
// Change background color of our article without accessing DOM element directly - Did'nt work.
this.renderer.selectRootElement('#testimonialarticle').setStyle(this, "background-color", "black");
}
// Inject Renderer2 to avoid XSS attacks and direct access to DOM
constructor(private renderer: Renderer2) {
}
// Etc
}
Well, the only two methods I was able to achieve this was by using ::ng-deep
, which is deprecated and the other way was to use the encapsulation: ViewEncapsulation.None,
parameter inside my @Component
decorator.
For now, this is how I did. But I am still looking for alternatives since I saw that neither solution is a good option.
@Component({
selector: 'app-row-clients',
templateUrl: './row-clients.component.html',
styleUrls: ['./row-clients.component.css'],
encapsulation: ViewEncapsulation.None,
})
Now without the encapsulation, I can style my component:
.testimonialcarousel .owl-item.active.center {
opacity: 1;
transform: scale3d(1.0, 1.0, 1);
}
I'm just not glad that I did'nt managed to use another more secure and recommended approach.