davidjerleke/embla-carousel

[Bug]: Flickering when adding icon or image in slides (8.0)

Nincha opened this issue · 3 comments

Nincha commented

Which variants of Embla Carousel are you using?

  • embla-carousel (Core)
  • embla-carousel-react
  • embla-carousel-vue
  • embla-carousel-svelte
  • embla-carousel-autoplay
  • embla-carousel-auto-scroll
  • embla-carousel-solid
  • embla-carousel-auto-height
  • embla-carousel-class-names
  • embla-carousel-docs (Documentation)
  • embla-carousel-docs (Generator)

Steps to reproduce

Hi!

First off, huge congrats for the work, your carousel is simply amazing. :)

I think I found out a bug: I have been following the demo and mixing a bit the examples, but it's still pretty raw:

import EmblaCarousel from 'embla-carousel'
// import { setupTweenScale } from './embla-carousel/embla-tween-scale'
import AutoScroll from 'embla-carousel-auto-scroll'
import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures'
import ClassNames from 'embla-carousel-class-names'


/**
 * Initialize Jobs lists
 */
export function initializeJobsLists() {

  const jobsLists = document.querySelectorAll('.embla-jobs-list')

  if (jobsLists.length > 0) {
    const initCarousels = () => {

      jobsLists.forEach(jobsList => {

        const viewportNode = jobsList.querySelector('.embla__viewport')
        const options = {
          loop: true,
          dragFree: true,
        }
        const emblaApi = EmblaCarousel(viewportNode, options, [
          AutoScroll({
            playOnInit: true,
            speed: 0.8,
            stopOnInteraction: false,
            stopOnMouseEnter: true
          }),
          WheelGesturesPlugin(),
          ClassNames()
        ])
        // const removeTweenScale = setupTweenScale(emblaApi)

        // console.log(emblaApi.slideNodes()) // Access API
      })
    }

    initCarousels()
  }
}

Nothing fancing for the CSS:

.jobs-list-parent {
  @include noise-bg;
  @include noise-bg-blue;
  color: $varWhite;
  padding-top: 3rem;
  padding-bottom: 2.5rem;

  @media (min-width: 768px) {
    padding-top: 5.5rem;
    padding-bottom: 4rem;
  }

  @media (max-width: 767px) {
  }
}

.jobs-list {

  @media (max-width: 767px) {
  }

  .embla {
    padding-top: 3rem;
    padding-bottom: 3rem;
  }

  .embla__slide {
    flex: 0 0 60%;
    margin-right: 30px;

    @media (min-width: 460px) {
      flex: 0 0 50%;
    }

    @media (min-width: 600px) {
      flex: 0 0 40%;
    }

    @media (min-width: 992px) {
      flex: 0 0 30%;
      margin-right: 40px;
    }

    @media (min-width: 1200px) {
      flex: 0 0 25%;
      margin-right: 50px;
    }
  }
}

And also basic HTML :

            <div class="embla embla-jobs-list">
              <div class="embla__viewport">
                <div class="embla__container">

                  <?php
                    $slideNumber = 0;
                    foreach ($settings['jobs_list'] as $item) {
                      ++$slideNumber;
                  ?>
                      <div class="embla__slide">
                          <?php
                            if ( ! empty( $item['job_link']['url'] ) ) {
                                $this->add_link_attributes( 'job_link_'.$slideNumber, $item['job_link'] );
                            }
                          ?>
                        <a class="carousel-tile tween-animated" <?= $this->get_render_attribute_string( 'job_link_'.$slideNumber )?>>
                          <h3><?= $item['job_title'] ?></h3>
                          <p><?= __('Role based:') ?> <?= $item['job_location']?></p>
                          <p><?= __('Start date:') ?> <?= $item['job_start_date']?></p>
                          <div class="carousel-tile-icon">
<!--                            <img alt="" src="--><?php //= get_stylesheet_directory_uri() . '/assets/img/plus-white.svg' ?><!--">-->
                            <svg width="19" height="20" viewBox="0 0 19 20" xmlns="http://www.w3.org/2000/svg">
                              <g transform="translate(.955 1.339)" stroke="#FFF" fill="none" fill-rule="evenodd">
                                <ellipse stroke-width=".827" cx="8.675" cy="8.664" rx="8.675" ry="8.664"/>
                                <path d="M4.627 8.664h8.096M8.675 4.62v8.086" stroke-width=".829"/>
                              </g>
                            </svg>
                          </div>
                        </a>
                      </div>
                  <?php } ?>
                </div>
              </div>
            </div>

Things are going well on desktop, but I had a strange flickering/overlap after a few seconds on mobile, or after scrolling a few elements:

I have been reducing the scope to isolate the problem and discovered it was tied to the presence of a SVG inline icon.

Expected Behavior

The presence of an icon shoudn't cause flickering on the slides imo, but unfortunely I can't think of what could cause that.

Additional Context

I've tried :
1 - Removing the inline <svg> icon tag by a hardcoded icon : problem gone
2 - Replacing the icon by an <img> tag : problem still here
3 - I've also tried (for 1 and 2) to position the element in various ways (block, flex, relative, absolute) but nothing seems to help.

I'm currently using the first solution but I was lucky I could compose the icon in CSS, and the icon is still a bit shaky with hovers/transforms ; using a proper icon would be better.

Also it should be noted that on the screenshot the size of the white slide is different, but it's only because I used CSS transforms. I also tried disabling them and it did not have any impact on the problem so I kept them.

Also, sorry I'm not familiar enough to build a sandbox, but feel free to ask any more information if needed.

What browsers are you seeing the problem on?

Chrome (mobile)

Version

v8.0.0

CodeSandbox

No response (sorry :) )

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues
  • I agree to follow this project's Contributing Guidelines for bug reports

Hi @Nincha,

I can’t debug anything with fragments of code. A CodeSandbox is mandatory if you want me to look into it.

However, my guess would be that this is a rendering problem in the browser and sometimes, they can be solved by promoting the flickering element to a separate layer. So you can try adding the following CSS to your icons, slides or slide container (try all separately, not all at the same time):

.icon {
  backface-visibility: hidden;
}

/* If that doesn’t work, try this instead: */

.icon {
  transform: translateZ(0);
}

Best,
David

Nincha commented

Hello @davidjerleke,

Thanks a lot for the quick feedback and sorry again for being lazy with the sandbox. n_n.

You were right as your first guess did the trick:

.icon {
  backface-visibility: hidden;
}

I'm closing the topic ; thanks again for your help. :)

Have a great day!
Cheers,
Charlie

@Nincha I’m glad to hear that.

Cheers,
David