angulartypescriptowl-carouselng-template

How can I style the active and centered slide in ngx owl carousel in Angular?


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.

Active Center tag in Owl Item

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
}

Solution

  • 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.