I'm working on making a Carousel component in svelte and I have ran in to an issue. I am setting the width of the carousel based on the widest image in the carousel. This works great on Firefox but on Chromium browsers it is not working propperly at all. For example an image that is showing as 600px wide on ff is showing as 180px on chromium browsers. I have tested this on multiple devices in ff, edge, and chrome.
Here is the code for my component:
<script lang="ts"> import { onMount } from 'svelte'; type imageListType = { src: string; alt: string }; export let autoPlay: number = 0; export let height: string = 'fit-content'; export let imageList: Array<imageListType>; export let startIndex: number = 0; export let title: string = 'Carousel'; export let type: string = 'slide'; export let width: string = 'fit-content'; let currentIndex = startIndex; let slideInterval: ReturnType<typeof setTimeout> | null; let carousel: HTMLElement; let images: Array<HTMLImageElement> = new Array(); onMount(() => { if (images.length > 0) { let largestSize = 0; images.forEach((image) => { if (image.offsetWidth > largestSize) { largestSize = image.offsetWidth; } }); console.log('largestSize:', largestSize); carousel.style.width = largestSize +'px'; } if (autoPlay > 0) { startSlideInterval(); } }); function startSlideInterval() { if (slideInterval) { clearInterval(slideInterval); } slideInterval = setInterval(() => { currentIndex = (currentIndex + 1) % imageList.length; }, autoPlay); } function stopSlideInterval() { if (slideInterval) { clearInterval(slideInterval); slideInterval = null; } } $: { if (currentIndex < 0) { currentIndex = imageList.length - 1; } else if (currentIndex >= imageList.length) { currentIndex = 0; } }</script><section bind:this={carousel} aria-roledescription=" Carousel" aria-label={title} style={'height:'+ height +';width:'+ width +';display: flex;flex-direction: column-reverse;border: 1px solid red;'} on:mouseenter={() => stopSlideInterval()} on:focusin={() => stopSlideInterval()} on:mouseleave={() => startSlideInterval()} on:focusout={() => startSlideInterval()}><div class="slideControls" role="region" aria-label="Slide Controls"><button class="navigationArrow" on:click={() => currentIndex--} aria-label={'Previous '+ type}><span class="fa-duotone fa-cake-slice" style="--fa-primary-color: var(--logoBackgroundColor); --fa-secondary-color: var(--logoFontGold);--fa-secondary-opacity:1;"></span></button> {#each imageList as image, index}<button class="navigationDot" aria-disabled={index == currentIndex ? true : undefined} aria-current={index == currentIndex ? true : undefined} on:click={() => (currentIndex = index)} aria-label={'Go to '+ type +''+ (index + 1)}><span class="fa-solid fa-cupcake"></span></button> {/each}<button class="navigationArrow" on:click={() => currentIndex++} aria-label={'Next '+ type}><span class="fa-duotone fa-cake-slice fa-flip-horizontal" style="--fa-primary-color: var(--logoBackgroundColor); --fa-secondary-color: var(--logoFontGold); --fa-secondary-opacity:1;"></span></button></div><div class="slideContainer"> {#each imageList as image, index}<div class="slide" role="group" aria-roledescription="Slide" aria-label={type +''+ (index + 1) +' of '+ imageList.length} style={index != currentIndex ? 'visibility: hidden;' : 'visibility: visible;'}><img bind:this={images[index]} class="slideImage" src={image.src} alt={image.alt} /></div> {/each}</div></section><style> .slideContainer { position: relative; width: 100%; height: 90%; } .slide { position: absolute; display: flex; height: 100%; left: 0; right: 0; margin: 0 auto; } .slideImage { height: 100%; border: 1px solid black; margin: auto; } .slideControls { display: flex; flex-direction: row; margin: auto; } .slideControls span { color: var(--logoFontGold); } .navigationArrow { border: 0; background-color: transparent; } .navigationArrow span { font-size: 1.5rem; } .navigationDot { border: 0; background-color: transparent; font-size: 0.7rem; } .navigationDot[aria-disabled='true'] span { color: var(--logoFontPurple); }</style>
I have tried multiple different ways of getting the widths such as using naturalWidth, width, offsetWidth, clientWidth, etc. I also tried using an on:load function but that didn't seem to run in chromium browsers at all.