Learus / react-material-ui-carousel

A Generic carousel UI component for React using Material UI.
MIT License
552 stars 220 forks source link

[Bug] Carousel does not Grow to full height of children #189

Open Reaw opened 2 years ago

Reaw commented 2 years ago

When rendering the first slide, the Carousel does sometimes stop its growing animation before reaching full height, see:

Animation

From my experience it seems that the more complex the slides are the more often it happens. Disabling this animation would be a solution for me

Any idea how to fix that?

sukh-noah commented 2 years ago

I have a similar issue where the first slide is not rendered at full height, but when the next slide appears it fixes itself. So the issue is only on first load

Jun-15-2022 17-10-24

There needs to be a delayed height check or one when the slide duration starts.

I have different heights for each slide.

Would really appreciate a fix for this.

nh2d commented 2 years ago

Experiencing the same thing here +1

my carousel definition: <Carousel autoPlay={false} indicators={false} navButtonsAlwaysInvisible={true} index={index}>

crunchytoast commented 2 years ago

Anyone have a temporary fix for this? It's really off-putting and buggy-looking...

alexanderbh commented 2 years ago

As mentioned in here: https://github.com/Learus/react-material-ui-carousel/issues/187#issuecomment-1222069555

It works for me if I set swipe={false}. That stops the buggy expanding animation.

sebaser99 commented 2 years ago

swipe={false}

I tried that solution but I didn´t get solve this bug... the behavior was the same

dmitry-js commented 1 year ago

How to reproduce the issue: disable cache and reload the page

The reason why it's happening: Carousel initializes before an image is fully loaded See plain JS example. Switch between line 4 and 7 to see the difference

Solutions

  1. render Carousel when a first image is loaded. Sample code how this can be achieved:
    
    import firstImg from "./img1.png";

export default function App() { const [firstImgLoaded, setFirstImgLoaded] = useState(false);

return (
    <>
      <img
        src={firstImg}
        onLoad={() => setFirstImgLoaded(true)}
        style={{ display: "none" }}
      />
      {firstImgLoaded && (
        <Carousel autoPlay={false}>
          {items.map((item) => (
            <Item key={item.name} {...item} />
          ))}
        </Carousel>
      )}
    </>
);

See full [example](https://codesandbox.io/s/react-material-ui-carousel-fixed-height-u7hjmn?file=/src/App.js)
This hack is more reliable since we load an image and then get it from the browser's cache where its width and height are already defined

2. just add fixed css `height` or `min-height` for your images
This hack is ok if you don't care about responsive images

But anyway, we need a proper fix. I'll try to create a PR later
brunomichalski commented 1 year ago

How to reproduce the issue: disable cache and reload the page

The reason why it's happening: Carousel initializes before an image is fully loaded See plain JS example. Switch between line 4 and 7 to see the difference

Solutions

  1. render Carousel when a first image is loaded. Sample code how this can be achieved:
import firstImg from "./img1.png";

export default function App() {
  const [firstImgLoaded, setFirstImgLoaded] = useState(false);

  return (
      <>
        <img
          src={firstImg}
          onLoad={() => setFirstImgLoaded(true)}
          style={{ display: "none" }}
        />
        {firstImgLoaded && (
          <Carousel autoPlay={false}>
            {items.map((item) => (
              <Item key={item.name} {...item} />
            ))}
          </Carousel>
        )}
      </>
  );

See full example This hack is more reliable since we load an image and then get it from the browser's cache where its width and height are already defined

  1. just add fixed css height or min-height for your images This hack is ok if you don't care about responsive images

But anyway, we need a proper fix. I'll try to create a PR later

This solution worked, Thank u so much !!!

44Kuniy commented 1 year ago

<Carousel /> component seems to have overflow:hidden property.

<Carousel
  sx={{ overflowY: 'visible', overflowX: 'clip' }} 
  ...
>
  {...}
</Carousel>

This worked for me.

lp185140 commented 1 year ago

it's been a year since this problem first surfaced...are there any real fix to implement responsive height? None of these solutions are actually fixing the root problem!

For me, the biggest issue is that the widget will load in properly, but if I drag the window and change the page's dimensions the carousel's content shrinks and enlarges but the actual carousel's height does not change causing the content to be cut off when page is enlarged or have white space when page is shrunk.

hanaakhojhove commented 1 year ago

experiencing the same issue !! any updates here?

arp55 commented 12 months ago

sx={{ overflowY: 'visible',

This creates another scrollbar with the carousel rather than showing the carousel component as it is with it's children.

ewewraw commented 11 months ago

Found a(n ugly) workaround:

    const [carouselHeight, setCarouselHeight] = useState(100);

    const updateCarouselHeight = () => {
        const content = document.getElementsByClassName('carousel-content')
        if (content.length > 0) {
            // Set the height of the carousel to match the height of its 'slide' with the maximum height
            setCarouselHeight(Math.max(...Array.from(content).map(element => element.clientHeight)));
        }
    };

    useEffect(() => {
        const handleResize = () => {
            updateCarouselHeight();
        };

        window.addEventListener("resize", handleResize);
        handleResize();

        return () => window.removeEventListener("resize", handleResize)
    }, [])

    // ...

    <Carousel sx={{height: carouselHeight}}>
        <SomeContent className={'carousel-content'}/>
    </Carousel>
DaltheCow commented 11 months ago

I tried every work around I could think of. I can get the content to dynamically resize properly but the indicators are my main hold out, when clicked I can't get them to work correctly, but they move properly on resize.

I was working on a solution where the carousel height would be set to the current content rather than the max content height since that is a worse user experience in my case.

Will come back to this and hopefully get something working.